/*
               ＴＶ☆ＴＯＷＮＳ  −リアルタイムエフェクタ−

                     Version  1.0       1990/04/25　　　 

                         by Pumpkin (MHD00746)     
*/
/*
                     Version  2.01      1990/05/05　　　 
                     Version  2.02      1990/05/24　　　 
                     Version  2.03      1990/06/02　　　 

                         by  ムンパッパ (MHB02550)     
*/
          .text
          .data

          /* 初期化 */

          call   G_INIT
          call   KEY_INIT

          movl   %esp,(esp_w)           /* パレットテーブル領域を作る */
          movl   $0x8000,%ecx
ini_lp:   pushw  $0
          loop   ini_lp
          movl   %esp,(table)

          mov    $0,%al                 /* 320×240 ロウスキャン */
          mov    $11,%dx
          call   SCREEN_MODE
          mov    $1,%al
          mov    $11,%dx
          call   SCREEN_MODE

          mov    $1,%al                 /* レイヤ１が前、レイヤ０非表示 */ 
          mov    $2,%edx
          call   DISPLAY_PAGE

          mov    $0x43,%ah
          mov    $0,%bl
          mov    $0x7f7f,%dx
          lcall  %fs:(0x80)             /* ライン入力オン */

          /* メインルーチン */

          movb   $0x4e,%dl

Main_loop:
          cmpb   $13,%dl
          je     Main_Bye

          cmpb   $0x4d,%dl              /* M, m */
          je     mono_sub
          cmpb   $0x6d,%dl
          je     mono_sub

          cmpb   $0x53,%dl              /* S, s */
          je     sep_sub 
          cmpb   $0x73,%dl
          je     sep_sub 

          cmpb   $0x42,%dl              /* B, b */
          je     border
          cmpb   $0x62,%dl
          je     border

          cmpb   $0x4b,%dl              /* K, k */
          je     shadow
          cmpb   $0x6b,%dl
          je     shadow

          cmpb   $0x39,%dl
          jg     default

          cmpb   $0x30,%dl
          jl     default

          call   mask_set
          jmp    qeffect
default:
          jmp     normal

Main_ret:         
          call   effect
          jmp    Main_loop

          /* 後処理 */

Main_Bye:
          mov    $0x43,%ah
          mov    $0,%bl
          xor    %dx,%dx
          lcall  %fs:(0x80)           /* ライン入力オフ */
          
          call   G_INIT

          mov    $0,%al               /* MS-DOSの画面 */
          mov    $1,%dx
          call   SCREEN_MODE
          mov    $1,%al
          mov    $1,%dx
          call   SCREEN_MODE
          mov    $1,%al               /* レイヤ１が前、レイヤ全表示 */ 
          mov    $3,%edx
          call   DISPLAY_PAGE
          mov    $0x440,%dx
          movb   $0x18,%al
          outb   %al,%dx              /* REG No. set */
          addw   $2,%dx
          movw   $0x80,%ax
          outw   %ax,%dx              /* 1024 x 512 */

          /* パレットセット */

          movl   $0,%ebx
          movl   $0,%ecx
plt_lp:
	  movw	 $0xfd90,%dx
          movb   %cl,%al
          outb   %al,%dx              /* パレット No. セット */

	  addw   $2,%dx
          movw   palette(,%ebx,1),%ax   /* 青 */
          outw   %ax,%dx 
          inc	 %ebx

	  addw   $2,%dx
          movw   palette(,%ebx,1),%ax   /* 赤 */
          outw   %ax,%dx 
          inc	 %ebx

	  addw   $2,%dx
          movw   palette(,%ebx,1),%ax   /* 緑 */
          outw   %ax,%dx 
          inc	 %ebx

          inc	 %ecx
          cmpl   $16,%ecx
          jb     plt_lp

          call   KEY_OFF              /* クリック音 ＯＦＦ */

          movl   (esp_w),%esp

          mov    $0x4c00,%ax          /* さよなら */
          int    $0x21

          /* 通常表示 */
normal:
          mov    $1,%al               /* レイヤ１を透明にする */
          call   WRITE_PAGE
          mov    $0x8000,%edx
          call   BACK_COLOR
          call   CLS

          movw   $0x1a81,%ax
          lcall  %fs:(0x20)           /* インポーズオン */

no_lp:    call   INKEY                /* while inkey$="":wend */
          cmpb   $0xff,%dl
          je     no_lp

          cmpb   $0x6e,%dl              /* キー内容チェック */
          je     no_lp
          cmpb   $0x4e,%dl
          je     no_lp
no_bye:
          movw   $0x1a00,%ax
          lcall  %fs:(0x20)           /* インポーズオフ */

          jmp    Main_loop

          /* エフェクト表示 */
effect:
	  call   DIGITIZE

          movl   (table),%ebp
ef_lp0:
          xor    %esi,%esi
          movl   $239,%ecx
ef_lp1:   push   %ecx
          movl   $319,%ecx
ef_lp2:
          movw   %es:(%esi),%dx       /* レイヤ０からとる */
          movw   (%ebp,%edx,2),%ax    /* パレットアクセス */
          movw   %ax,%es:0x40000(%esi)
          inc    %esi
          inc    %esi
          loop   ef_lp2
          pop    %ecx
          addl   $386,%esi
          loop   ef_lp1

	  inb	 $0602,%al           /* STATUS チェック */
          and    $01,%al
          jne    ef_lp0

          call   INKEY
          cmpb   $0xff,%dl
          je     ef_lp0
ef_bye:
          mov    $0x1b00,%ax
          lcall  %fs:(0x20)           /* デジタイズオフ */
          ret

          /* クイック エフェクト表示 */
qeffect:
	  call   DIGITIZE
qef_lp0:
          movl   (mask),%ebx
          xor    %esi,%esi
          movl   $239,%ecx
qef_lp1:  push   %ecx
          movl   $159,%ecx
qef_lp2:
          movl   %es:(%esi),%eax      /* レイヤ０からとる */
qef_and:
          andl   %ebx,%eax    /* mask  */
          movl   %eax,%es:0x40000(%esi)

          addl   $4,%esi
          loop   qef_lp2

          pop    %ecx
          addl   $388,%esi
          loop   qef_lp1

          call   INKEY
          cmpb   $0xff,%dl
          je     qef_lp0

          cmpb   $0x30,%dl           /* キー内容チェック */
          jl     qef_bye
          cmpb   $0x39,%dl
          jg     qef_bye

          call   mask_set
          jmp    qef_lp0
qef_bye:
          mov    $0x1b00,%ax
          lcall  %fs:(0x20)           /* デジタイズオフ */
          jmp    Main_loop

          /* ボ−ダ− エフェクト表示 */
border:
	  call   DIGITIZE
bd_lp0:
          movl   $42104210,%bx
          xor    %esi,%esi
          movl   $239,%ecx
bd_lp1:   push   %ecx
          movl   $159,%ecx
bd_lp2:
          movl   %es:(%esi),%eax      /* レイヤ０からとる */
          movw   %ax,%dx
          xorw   %bx,%ax
          rorl   $16,%eax
          movw   %ax,%bx
          xorw   %dx,%ax
          rorl   $16,%eax
          movl   %eax,%es:0x40000(%esi)

          addl   $4,%esi
          loop   bd_lp2

          pop    %ecx
          addl   $388,%esi
          loop   bd_lp1

          call   INKEY
          cmpb   $0xff,%dl
          je     bd_lp0

          cmpb   $0x42,%dl           /* キー内容チェック */
          je     bd_lp0
          cmpb   $0x62,%dl
          je     bd_lp0
bd_bye:
          mov    $0x1b00,%ax
          lcall  %fs:(0x20)           /* デジタイズオフ */
          jmp    Main_loop

          /* シャドウ エフェクト表示 */
shadow:
	  call   DIGITIZE
sh_lp0:
          movl   $42104210,%ebx
          xor    %esi,%esi
          movl   $239,%ecx
sh_lp1:   push   %ecx
          movl   $159,%ecx
sh_lp2:
          movl   %es:(%esi),%eax      /* レイヤ０からとる */
          pushl  %eax
          orl    $0x84218421,%ebx     /* ２ドット前の反転デ−タを */
          andl   $0x7bdf7bdf,%eax     /* 加算して２で割る         */
          subl   %ebx,%eax
          shrl   $1,%eax
          andl   $0x7fff7fff,%eax
          movl   %eax,%es:0x40000(%esi)
	  popl   %ebx

          addl   $4,%esi
          loop   sh_lp2

          pop    %ecx
          addl   $388,%esi
          loop   sh_lp1

          call   INKEY
          cmpb   $0xff,%dl
          je     sh_lp0

          cmpb   $0x4b,%dl           /* キー内容チェック */
          je     sh_lp0
          cmpb   $0x6B,%dl
          je     sh_lp0
sh_bye:
          mov    $0x1b00,%ax
          lcall  %fs:(0x20)           /* デジタイズオフ */
          jmp    Main_loop

          /* モノクロのパレットテーブル作成 */

mono_sub:
          movl   (table),%ebp         /* レジスタに定数設定 */

          movl   $0,%ecx
mono_lp0: push   %ecx
          sar    $10,%ecx             /* ＲＧＢの分離 */
          andl   $0x1f,%ecx
          movl   %ecx,%eax

          movl   (%esp),%ecx
          sar    $5,%ecx
          andl   $0x1f,%ecx
          dec    %ecx                 /* 人の目にはG>R>Bと見えるので輝度補正 */
          cmpl   $0,%ecx
          jge    mono_jp1
          xor    %ecx,%ecx
mono_jp1: addl   %ecx,%eax

          movl   (%esp),%ecx
          andl   $0x1f,%ecx
          dec    %ecx                 /* 人の目にはG>R>Bと見えるので輝度補正 */
          dec    %ecx
          cmpl   $0,%ecx
          jge    mono_jp2
          xor    %ecx,%ecx
mono_jp2: addl   %ecx,%eax

          movb   $3,%cl
          divb   %cl
          andl   $0xff,%eax            /* ahは余りが入っているので */          
          movw   $1057,%cx
          mull   %cx

          pop    %ecx
          movw   %ax,(%ebp,%ecx,2)    /* addr=ebp+ecx*2 */

          inc    %ecx
          cmpl   $0x8000,%ecx
          jne    mono_lp0

          jmp    Main_ret

          /* セピア色のパレットテーブル作成 */

sep_sub:
          movl   (table),%ebp         /* レジスタに定数設定 */

          movl   $0,%ecx
sep_lp0:  push   %ecx
          sar    $10,%ecx             /* ＲＧＢの分離 */
          andl   $0x1f,%ecx
          movl   %ecx,%eax

          movl   (%esp),%ecx
          sar    $5,%ecx
          andl   $0x1f,%ecx
          addl   %ecx,%eax

          movl   (%esp),%ecx
          andl   $0x1f,%ecx
          addl   %ecx,%eax

          movb   $3,%cl
          divb   %cl
          andl   $0xff,%eax            /* ahは余りが入っているので */
          dec    %eax                  /* セピア色の調合 */
          dec    %eax
          cmpl   $0,%eax
          jge    sep_jp0
          xor    %eax,%eax
sep_jp0:  movl   %eax,(red)
          dec    %eax
          cmpl   $0,%eax
          jge    sep_jp1
          xor    %eax,%eax
sep_jp1:  movl   %eax,(green)
          dec    %eax
          cmpl   $0,%eax
          jge    sep_jp2
          xor    %eax,%eax
sep_jp2:  movl   %eax,(blue)
          movl   (green),%eax
          shl    $5,%eax
          addl   (red),%eax
          shl    $5,%eax
          addl   (blue),%eax

          pop    %ecx
          movw   %ax,(%ebp,%ecx,2)    /* addr=ebp+ecx*2 */

          inc    %ecx
          cmpl   $0x8000,%ecx
          jne    sep_lp0

          jmp    Main_ret

          /* サブルーチン */
          
          /* カラ−マスクのセット */
mask_set:
          cmpb   $0x39,%dl
          je     ms_jp0
          movw   (andcode),%ax       /* パッチオフ */
	  jmp    ms_jp1
ms_jp0:
          movw   (negacode),%ax       /* パッチ */
ms_jp1:
          movw   %ax,(qef_and)

          andl   $0xff,%edx
	  subl   $0x30,%edx
          movl   mask_tab(,%edx,4),%eax
          movl   %eax,(mask)
          ret

          /* デジタイズ */
DIGITIZE:
          mov    $1,%al               /* レイヤ１を黒にする */
          call   WRITE_PAGE
          xor    %edx,%edx            /* レジスタに定数設定 */
          call   BACK_COLOR
          call   CLS

          mov    $0,%al               /* デジタイズはレイヤ０へ */
          call   WRITE_PAGE

          pushl  $0x104               /* ２画面モードのセグメント */
          pop    %es

          mov    $0x1b01,%ax
          lcall  %fs:(0x20)           /* デジタイズオン */
          ret

          /* G-BIOSの初期化 */
G_INIT:
          push   %ds
          pop    %gs
          push   %ds
          pop    %es
          movl   $1536,%ecx
          movl   $G_work,%edi
          movb   $0,%ah
          pushl  $0x0110
          pop    %fs    
          lcall  %fs:(0x20)
          ret

          /* スクリーンモードの指定 */
SCREEN_MODE:
          /* al:レイヤ  dx:スクリーンモード  */
          movb   $1,%ah
          movl   $G_work,%edi
          lcall  %fs:(0x20)
          ret

          /* 画面表示位置の指定 */
SCREEN_POS:
          /* bx:縦位置 dx:横位置 */
          movw   $0x201,%ax
          movl   $G_work,%edi
          lcall  %fs:(0x20)
          ret

          /* 画面拡大率の指定 */
ZOOM_SCREEN:
          /* bx:縦倍率 dx:横倍率 */
          movw   $0x202,%ax
          movl   $G_work,%edi
          lcall  %fs:(0x20)
          ret

          /* WIDTHの指定 */
SCREEN_WIDTH:
          /* bx:縦ドット数 dx:横ドット数 */
          movw   $0x203,%ax
          movl   $G_work,%edi
          lcall  %fs:(0x20)
          ret

          /* 書き込みページの設定 */
WRITE_PAGE:
          /* al:ページ */
          movb  $5,%ah
          movl  $G_work,%edi
          lcall %fs:(0x20)
          ret

          /* 表示ページの設定 */
DISPLAY_PAGE:
          /* al:プライオリティ edx:表示データ */
          movb  $6,%ah
          movl  $G_work,%edi
          lcall %fs:(0x20)
          ret

          /* 背景色指定 */
BACK_COLOR:
          /* edx:色 */
          mov   $0x701,%ax
          movl  $G_work,%edi
          lcall %fs:(0x20)
          ret

          /* 画面消去 */
CLS:
          movb  $0x20,%ah
          movl  $G_work,%edi
          lcall %fs:(0x20)
          ret

          /* キー入力の初期化 */
KEY_INIT:
          movb   $0,%ah
          int    $0x90
          ret

          /* キー入力の初期化 */
KEY_OFF:
          movw   $0x501,%ax
          int    $0x90
          ret

          /* キー入力を待つ */

          .align 4   
KEY_INP:
          movw   $0x900,%ax 
          int    $0x90
          ret

          /* キー入力を待たない */

          .align 4   
INKEY:
          movw   $0x901,%ax 
          int    $0x90
          ret

          /* デバッグランプ */

lamp:     push   %eax
          push   %edx
          movb   $0x48,%ah
          movb   $0x01,%dl
          lcall  %fs:(0x80)
          pop    %edx
          pop    %eax
          ret

negacode:
          xorl   %ebx,%eax
andcode:
          andl   %ebx,%eax

          /* ワーク */
mask_tab:  .long  0,0x42104210,0x63186318,0x739c739c,0x7bde7bde,0x7fff7fff
           .long  0x7c007c00,0x03e003e0,0x001f001f,0x7fff7fff
mask:      .long  0x7fff7fff
vsync_d:   .long  0,0
green:     .long  0
red:       .long  0
blue:      .long  0
table:     .long  0
esp_w:     .long  0
G_work:    .space 1536
palette:
           /*		青	赤	緑	/* パレットNo. */
	   .byte	0,	0,	0	/*      0      */
	   .byte	176,	0,	0	/*      1      */
	   .byte	0,	176,	0	/*      2      */
	   .byte	176,	176,	0	/*      3      */
	   .byte	0,	0,	176	/*      4      */
	   .byte	176,	0,	176	/*      5      */
	   .byte	0,	176,	176	/*      6      */
	   .byte	176,	176,	176	/*      7      */
	   .byte	64,	64,	64	/*      8      */
	   .byte	255,	0,	0	/*      9      */
	   .byte	0,	255,	0	/*     10      */
	   .byte	255,	255,	0	/*     11      */
	   .byte	0,	0,	255	/*     12      */
	   .byte	255,	0,	255	/*     13      */
	   .byte	0,	255,	255	/*     14      */
	   .byte	255,	255,	255	/*     15      */
