#include <stdio.h>

#undef __write

long __conscr;
long __conclr;
char __conx,__cony;
char __conxdim=80,__conydim=25;
unsigned int __consize=80*24;

static long __regsused("a/x") readlong(__reg("btmp0") long) =
 "\tldq\t[btmp0],z\n"
 "\tstq\tbtmp0\n"
 "\tldz\t#0";

static __regsused("btmp0") unsigned int readint(__reg("btmp0") long) =
 "\tinz\n"
 "\tlda\t[btmp0],z\n"
 "\ttax\n"
 "\tdez\n"
 "\tlda\t[btmp0],z";


static __regsused("a/btmp0") char readchar(__reg("btmp0") long) =
 "\tlda\t[btmp0],z";

static __regsused("a/btmp0") char writefar(__reg("a") char,__reg("btmp0") long) =
 "\tsta\t[btmp0],z";

static __regsused("a/btmp0") void writechar(__reg("a") char,__reg("btmp0") long)= 
 "\tldz\t___conx\n"
 "\tsta\t[btmp0],z\n"
 "\tldz\t#0";

#if USEDMA
struct {
  unsigned char command;
  unsigned int count;
  unsigned int source_addr;
  unsigned char source_bank;
  unsigned int dest_addr;
  unsigned char dest_bank;
  unsigned char sub_cmd; // F018B subcmd
  unsigned int modulo;
} __condmalist[2];
#else
__regsused ("a/x/btmp0/btmp1") void __scroll(void)
{
    __asm("\tldq\t___conscr\n"
          "\tstq\tbtmp0\n"
          "\tclc\n"
          "\tadc\t___conxdim\n"
          "\tbcc\t.skip2\n"
          "\tinx\n"
          ".skip2:\n"
          "\tstq\tbtmp1\n"
          "\tldq\t___conclr\n"
          "\tstq\tbtmp2\n"
          "\tclc\n"
          "\tadc\t___conxdim\n"
          "\tbcc\t.skip3\n"
          "\tinx\n"
          ".skip3:\n"
          "\tstq\tbtmp3\n"
          "\tldx\t___consize+1\n"
          "\tldz\t#0\n"
          ".loop1:\n"
          "\tlda\t[btmp1],z\n"
          "\tsta\t[btmp0],z\n"
          "\tlda\t[btmp3],z\n"
          "\tsta\t[btmp2],z\n"
          "\tinz\n"
          "\tbne\t.loop1\n"
          "\tinc\tbtmp0+1\n"
          "\tinc\tbtmp1+1\n"
          "\tinc\tbtmp2+1\n"
          "\tinc\tbtmp3+1\n"
          "\tdex\n"
          "\tbne\t.loop1\n"
          "\tldx\t___consize\n"
          ".loop2:\n"
          "\tlda\t[btmp1],z\n"
          "\tsta\t[btmp0],z\n"
          "\tlda\t[btmp3],z\n"
          "\tsta\t[btmp2],z\n"
          "\tinz\n"
          "\tdex\n"
          "\tbne\t.loop2\n"
          "\tldx\t___conxdim\n"
          ".loop3:\n"
          "\tlda\t#32\n"
          "\tsta\t[btmp0],z\n"
          "\tlda\t#1\n"
          "\tsta\t[btmp2],z\n"
          "\tinz\n"
          "\tdex\n"
          "\tbne\t.loop3\n"
          "\tldz\t#0");
}
#endif
char __petsciitoscreencode(char c)
{
    if (c == '_')
    {
        return 100;
    }

    if (c >= 64 && c < 95)
    {
        return c - 64;
    }

    if (c >= 192)
    {
        return c - 128;
    }

    if (c >= 96 && c < 192)
    {
        return c - 32;
    }

    return c;
}



void __cput(char c)
{
  if(!__conscr){
    char st;
    __conscr=readlong(0xffd3060);
    __conclr=0xff80000+readint(0xffd3064);
    st=readchar(0xffd3031)&136;
    if(st==136){ __conxdim=80;__conydim=50;__consize=80*49;}
    else if(st==8){ __conxdim=40;__conydim=50;__consize=40*49;}
    else if(st==0){ __conxdim=40;__conydim=25;__consize=40*24;}
    //printf("scr=%lx xdim=%d ydim=%d size=%d\n",__conscr,__conxdim,__conydim,__consize);
    //fflush(stdout);
#if USEDMA
    static long tmp;
    __condmalist[0].command=4;
    __condmalist[0].count=__consize;
    __condmalist[0].dest_addr = __conscr;
    __condmalist[0].dest_bank = ((char *)&__conscr)[2]&0xf;
    tmp=__conscr+__conxdim;
    __condmalist[0].source_addr = tmp;
    __condmalist[0].source_bank = ((char *)&tmp)[2]&0xf;
    __condmalist[1].command=3;
    __condmalist[1].count=__conxdim;
    tmp=__conscr+__consize;
    __condmalist[1].dest_addr = tmp;
    __condmalist[1].dest_bank = ((char *)&tmp)[2]&0xf;
    __condmalist[1].source_addr=0x2020;
#endif
    __cony=*(char*)235;
  }
  if(c=='\r') {__conx=0;return;}
  if(c=='\t') {__conx=(__conx+8)&248;return;}
  if(c=='\n'){
    __cony++;
    __conx=0;
  }else{
    writechar(__petsciitoscreencode(c),__conscr+__cony*__conxdim);
    __conx++;
    if(__conx>=__conxdim){__conx=0;__cony++;}
  }
  if(__cony>=__conydim){
    __cony--;
#if USEDMA
    __asm("\tldz\t#$0f\n"
          "\tldy\t#$fd\n"
          "\tldx\t#$37\n"
          "\tlda\t#$00\n"
          "\tstq\tbtmp0\n"
          "\tldz\t#2\n"
          "\tsta\t[btmp0],z\n"
          "\tlda\t#>___condmalist\n"
          "\tdez\n"
          "\tsta\t[btmp0],z\n"
          "\tlda\t#<___condmalist\n"
          "\tdez\n"
          "\tsta\t[btmp0],z\n");
#else
     __scroll();
#endif
  }
  (*(char*)235)=__cony;
}


int __write(int c,char *p,int len)
{
 int x=len;
 while(x){ __cput(*p++); --x;}
 return len;
}
