#include  "complex.h"
#include  "screen.h"

//    prn_as(func,symb,lpt_port);
//extern byte prn_as(byte,byte,word_s);
//#pragma aux prn_as  = "int  17h "\
//                      parm [ah] [al] [dx] \
//                      value [ah]          ;

void copy_scr(void);           /* ª®¯¨à®¢ ­¨¥ áâà ­¨æë 0 ­  áâà ­¨æã 1 */
#pragma aux copy_scr = "mov  ax,0105h           "\
                       "mov  dx,3ceh            "\
                       "out  dx,ax              "\
                       "mov  edi,0a8000h        "\
                       "mov  esi,0a0000h        "\
                       "mov  ecx,28000          "\
               "cont:   mov  al,[esi]           "\
                       "mov  byte ptr [edi],0ffh"\
                       "inc  edi                "\
                       "inc  esi                "\
                       "loop short cont         "\
                       "mov  ax,0005h           "\
                       "out  dx,ax              "\
                        modify [ax dx edi esi ecx]  ;

#if (PRINTER == 1)             /* ¥á«¨ 梥⭮© */
word_s getpix(word_s x,word_s y);
#pragma aux getpix = "mov  bh,1     "\
                     "mov  ah,0dh   "\
                     "int  10h      "\
                     "xor  ah,ah    "\
                      modify [ax bx] \
                      parm [cx] [dx] \
                      value [ax]          ;
#endif

byte ror_as(byte);
#pragma aux ror_as = "ror al,1"    \
                      parm [al]    \
                      value [al]   ;

word ror_as1(word);
#pragma aux ror_as1 = "ror ax,1"   \
                      parm [ax]    \
                      value [ax]   ;

word_s prt_byte(byte c);
word_s inst_printer();
word_s take_printer(long tpr);
void   printer(word_s *p_lpt);
void PRINT_SCREEN(void);
void prnt_scr(void);

extern word_s PRI_OFF;
extern word_s c_fonT;

word_s LPT = 1;                 /* 1 = LPT1, 2 = LPT2 */
word_s port_status_LPT;         /* ¯®àâ áâ âãá  ¯à¨­â¥à  */
resourceptr prt_res;         /* 㪠§ â. ­  p¥áãpá ¯¥ç â¨ */
pipeptr prt_chn;             /* 㪠§ â¥«ì ­  ª ­ « ¯¥ç â¨ */
tcbptr prt_task;             /* 㪠§ â. ­  § ¤ çã ¯¥ç â¨ */
word_s fl_prt = 0;              /* ¯p¨§­ ª ¢®§¬®¦­®á⨠¢ë¤ ç¨ ­  ¯¥ç âì */
word_s flag_print_screen = 0;   /* ¯à¨§­ ª § ­ïâ®á⨠¢â®à®© áâà ­¨æë íªà ­  */
word_s fon_screen = 0;          /* §­ ç¥­¨¥ æ¢¥â  ä®­  íªà ­  */
tcbptr task_print_screen;    /* 㪠§ â¥«ì ­  § ¤ çã ¯¥ç â¨ íªà ­  */
word_s screen_copy;             /* ­®¬¥à íªà ­ ,ª®â®àë© ª®¯¨àã¥âáï */
/*-------------------------------------------------------------------*/

word_s prt_byte(byte c)
{
  while(fl_prt && c_write_pipe(prt_chn,c))
  {
   while(check_pipe(prt_chn)!=-1) t_delay(3L);
  }
  if(fl_prt)  return 0;  else return 1;
}
/*-------------------------------------------------------------------*/

word_s inst_printer()
{
  if(LPT==1) port_status_LPT=0x379; else port_status_LPT=0x279;
  fl_prt = 0;
  prt_res = create_resource(NULL,"PRT_RES");
  prt_chn = create_pipe(NULL, NULL, 1536, "PRT");  /* ª ­ « ¯¥ç â¨ */
  prt_task = create_task(NULL,(funcptr)printer,NULL,1500,PRI_STD-PRI_OFF,&LPT,"PR");

  if(prt_chn==NULL || prt_task==NULL || prt_res==NULL) {
        eprintf(RED_,"PRINTER.C - ­¥â ¯ ¬ïâ¨");
        return 1;
  }

//  *(word_s *)0x00000478=(word_s)0x0101;          /* â ©¬ ã⠯ਭâ¥à  */
  start_task(prt_task);                    /* § ¯ã᪠§ ¤ ç¨ ¯¥ç â¨ */
  return 0;
}
/*-------------------------------------------------------------------*/

word_s take_printer(long tpr)
{
  word_s kz;

  kz=tsk_inp(port_status_LPT);                         /* áâ âãá ¯à¨­â¥à  */
  if((kz&0x78)==0x78 || !(kz&0x10)) kz = 1;  /* ¥á«¨ ®âª«. ¨«¨ ¢ëª«. */
  else kz = request_resource(prt_res, tpr);  /* ¨­ ç¥ § å¢ â ¯à¨­â¥à  */
  if(!kz) fl_prt=1;
  return kz;
}
/*-------------------------------------------------------------------*/

void free_printer()
{
  release_resource(prt_res);
}
/*-------------------------------------------------------------------*/

void   printer(word_s *p_lpt)
{
  word lpt,i;
  byte stat,c;

  if(*p_lpt==1) lpt=0x378; else lpt=0x278;

READ_CHN:
  if(endrun) {
        if(flag_print_screen) {
          kill_task(task_print_screen);
         _bios_printer(1,lpt,0);
        }
        return;
  }

  c=read_pipe(prt_chn,0L);
  if(!fl_prt) goto READ_CHN;   /* ¥á«¨ á¡à®è¥­ ä« £ à §à¥è.¯¥ç â¨ */
  i=0x30;
  tsk_outp(lpt,c);       pause(10);

OUT_CHR:
  stat=tsk_inp(lpt+1);   pause(10);
  if(!(stat & 0x80)) {if (i--) {schedule(); goto OUT_CHR;} goto err; }

  tsk_outp(lpt+2,0x0D);  pause(10);
  tsk_outp(lpt+2,0x0C);  pause(10);

  goto READ_CHN;

err:;
  if(1)
  {    /* ¥á«¨ ­¥ £®â®¢ ¨«¨ ­¥â ¡ã¬. */
    eprintf(WHITE_BR_,"%X",stat);
//    eprintf(15,"Ž„ƒŽ’Ž‚œ’… ˆ’… Š €Ž’…");
    t_delay(3*HZ);
    eprintf(BLACK_,"");
    goto OUT_CHR;
  }

  fl_prt=0;                       /* ¥á«¨ ¢ëª«î祭 ¨«¨ ­¥ ¯®¤ª«î祭 */
  goto READ_CHN;
}
/*-------------------------------------------------------------------*/

void prnt_scr(void)             /* § ¯ã᪠§ ¤ ç¨ ¯¥ç â¨ íªà ­  */
{
  if(flag_print_screen) {
    eprintf(YELLOW_,"‡€„€ˆ… … ˆŸ’Ž: …—€’œ ‡€Ÿ’€");
    return;
  }

  screen_copy=screen;
  copy_scr();
  fon_screen = c_fonT;
  task_print_screen = create_task(NULL,(funcptr)PRINT_SCREEN,NULL,1500,PRI_STD-PRI_OFF+1,NULL,"PRNTSCR");
  start_task(task_print_screen);
}
/*-------------------------------------------------------------------*/

void PRINT_SCREEN(void)        /* § ¤ ça ¯¥ç â¨ íªà ­  */
{
#if (PRINTER == 2)             /* ¥á«¨ 梥⭮© */
  word_s i,j,k,n,mbit;
  char cl,wc,ic,px,mask,uscl,ms;
  char *pv,*pp,*bm,*p0,*p1,*p2,*p3,*pc,*ps;
  unsigned char ox,om;
  word w0,w1;
  word_s *pb;

  if(take_printer(0L)) return;
  flag_print_screen = 1;

  pv=(char *)0xa8000L;          /*  ¤à¥á ¢â®à®© ¢¨¤¥®áâà ­¨æë */
  pb=(word_s *)calloc(350*2,2);      /* ®¡«.ä®à¬¨à.¤ ­­ëå ¤«ï ¯à¨­â¥à  */
  pp=(char *)calloc(350,8);       /* ®¡«.ä®à¬¨à.梥⮢ 8-¨ â®ç¥ª ¯®«®áë */
  bm=(char *)calloc(350,4);       /* ®¡«.¤ ­­ëå ¢¨¤¥®¯. ¯® 4-¬ ¡¨â.¯«®áª. */

  prt_byte(27); prt_byte('r'); prt_byte(4);
  for(i=0; i<12; i++) prt_byte('\n');

  ms=8;
  ox=om=0xff;

  for(i=0; i<80 && fl_prt; i++,pv++) {   /* ¯® ª®«¨ç.8-¡¨â®¢ëå ¯®«®á */

    if(screen!=screen_copy)set_screen(screen_copy);

    ps=bm;
    for(ic=0; ic<4; ic++)
    {                     /* ¯® ¡¨â®¢ë¬ ¯«®áª®áâï¬ */
     outpw(0x3CE,(ic<<8)|4);
     for(j=0,pc=pv; j<350; j++,pc+=80) *ps++ = *pc;     /* ¯® áâப ¬ */
    }

    if(screen!=screen_copy) set_screen(screen);

        uscl=0;
        mask=0x01;
        pc=pp;
        for(k=0; k<8; k++) {                         /* ¯® 8 ¡¨â ¬ ¯®«®áë */
        mask=ror_as(mask);
//          _asm ror mask,1
          p0=bm;  p1=p0+350;  p2=p1+350;  p3=p2+350;
          for(j=0; j<350; j++) {                      /* ¯® áâப ¬ */
                px=0;
                if(*p0++ & mask) px |= 1;               /* ¯® ¡¨â®¢ë¬ ¯«®áª®áâï¬ */
                if(*p1++ & mask) px |= 2;
                if(*p2++ & mask) px |= 4;
                if(*p3++ & mask) px |= 8;
                if(px==fon_screen) px=0;
                if(px != ox) {
                  ox=px;
                  switch(px) {                 /* á®®â¢. 梥⮢ ­  íªà. ¨ ¯à¨­â. */
                        case  0 : cl=0x00; break;
                        case  2 :
                        case 10 : cl=0x0c; break;
                        case 15 : cl=0x01; break;
                        case  4 :
                        case  6 :
                        case 12 : cl=0x0a; break;
                        case 14 : cl=0x08; break;
                        case  7 :
                        case  8 : cl=0x21; break;
                        case  5 :
                        case 13 : cl=0x02; break;
                        case  3 :
                        case 11 : cl=0x04; break;
                        case  1 :
                        case  9 : cl=0x06; break;
                  }
                  uscl |= cl;                     /* § ¯®¬¨­ ­¨¥ ¨á¯®«ì§.梥⮢ */
                }
                *pc++ = cl;
          }
        }

        prt_byte(27); prt_byte(43); prt_byte(0);   /* '\n'=0 */
        for(ic=0; ic<4; ic++) {                    /* ¯® ç¨áâë¬ æ¢¥â ¬ ¯à¨­â. */
          if(uscl & ms) {                        /* ¥á«¨ 梥â ms ¥áâì ¢ ¯®«®á¥ */
                for(j=0,n=0,pc=pp; j<350; j++,pc++) {    /* ¯® áâப ¬ */
                  w0=w1=0;
                  mbit=0x0003;
                  for(k=0,ps=pc; k<8; k++,ps+=350) {     /* ¯® ¡¨â ¬ ¯®«®áë */
                  mbit=ror_as1(mbit);
                  mbit=ror_as1(mbit);
//                        _asm {  ror mbit,1
//                                        ror mbit,1
//                                 }
                        wc=*ps;
                        if(wc&ms) {           /* ¥á«¨ ¢ 梥⥠â®çª¨ wc ¥áâì æ¢¥â ms */
                          w0 |= mbit;
                          if(!(wc&0x20)) w1 |= mbit;    /* ¥á«¨ 梥⠭¥ "á¥àë©" */
                        }
                  }
                  if(ms==1) {
                        if(j==0 || j==349) w0=w1=0xffff;
                        else if(i==0) { w0 |= 0xc000; w1 |= 0xc000; }
                        else if(i==79) { w0 |= 0x0003; w1 |= 0x0003; }
                  }
                  pb[n++]=w0;
                  pb[n++]=w1;
                }

                if(ms != om) {
                  om=ms;
                  prt_byte(27); prt_byte('r'); prt_byte((byte)(ms>>1)); /* ãáâ.梥â */
                }

                for(j=0; j<12; j++) prt_byte(' ');
                prt_byte(27); prt_byte('*'); prt_byte(33);    /* ãáâ. ¯«®â­. */
                prt_byte((byte)188);  prt_byte(2);

                for(j=1399,pc=(byte *)pb+1399; j>=0; j--,j--) {
                  prt_byte(*pc--);
                  prt_byte(*pc--);
                  prt_byte(0);
                }
                prt_byte('\n');
          }
          if(ic < 3) switch(ms) {
                                   case 8: ms=2; break;
                                   case 2: ms=4; break;
                                   case 4: ms=1; break;
                                   case 1: ms=8;
                                 }
        }
        prt_byte(27); prt_byte(43); prt_byte(32);
        prt_byte('\n');
  }

  if(!fl_prt) eprintf(YELLOW_,"…—€’œ  Š€€  …‚€€");

  prt_byte(27); prt_byte('@');
  prt_byte(12);
  fon_screen = 0;
  flag_print_screen = 0;
  free(bm);
  free(pp);
  free(pb);
  free_printer();
//}
#endif
#if (PRINTER == 1)
//{
  word_s a,i,s,l,c,k;
  unsigned char column[4],bit[4];
  char instr[]={27,'*',3,120,5};  /*350 â®ç¥ª ¯® 4=1400->1400/256=5 ¨ 120*/
  char inst[] ={27,'A',8};

  if(take_printer(0L)) return;
  flag_print_screen = 1;

  for(i=0;i<2;i++)  prt_byte('\n');           /* 4 */
  for(i=0;i<3;i++)  prt_byte(inst[i]);

  for(k=0,i=0;i<80;i++) {
        for(l=0; l<12; l++) prt_byte(' ');
        for(l=0;l<5;l++) prt_byte(instr[l]);
        for(c=0;c<=349;c++) {
          column[0]=column[1]=column[2]=column[3]=0;

          if(screen!=screen_copy) set_screen(screen_copy);

          for(s=0;s<8;s++) {
                a=getpix(k+s,349-c);  if(a==fon_screen) a=0;
                bit[0] = (a)? 1 : 0;
                switch(a) {
                  case 1:  case 9: case 4: case 12:
                                  bit[1]=bit[2]=bit[3]=1; break;    /*â-ᨭ¨©  */
                  case 2:  case 10: case 8: case 0:
                                  bit[1]=bit[2]=bit[3]=0; break;    /*â-§¥«¥­  */
                  case 3:  case 11:
                                  bit[1]=bit[3]=1; bit[2]=0; break; /*â-£®«ã¡  */
                  case 5:  case 13: case 7: case 15:
                                  bit[1]=0; bit[2]=bit[3]=1; break; /*â-       */
                  case 6:  case 14:
                                  bit[1]=1; bit[2]=bit[3]=0; break; /*â-       */
                }
                column[0]=(column[0]<<1)+bit[0];
                column[1]=(column[1]<<1)+bit[1];
                column[2]=(column[2]<<1)+bit[2];
                column[3]=(column[3]<<1)+bit[3];
          }

          if(screen!=screen_copy) set_screen(screen);

          prt_byte(column[0]); prt_byte(column[1]);
          prt_byte(column[2]); prt_byte(column[3]);
        }
        a=prt_byte('\n'); k+=8;
        if(a) break;
  }

  if(!fl_prt) eprintf(YELLOW_,"…—€’œ  Š€€  …‚€€");

  prt_byte((char)27); prt_byte('@');
  prt_byte(12);
  free_printer();
  fon_screen = 0;
  flag_print_screen = 0;

#endif
}


/*-------------------------------------------------------------------*/