#include    <stdio.h>
#include    <stdlib.h>
#include    <stdarg.h>
#include    <setjmp.h>
#include    <fmcfrb.h>
#include    <mos.h>
#include    "graphic.h"
#include    "file.h"
#include    "event.h"
#include    "coldef.h"

#define	TRUE	1
#define	FALSE	0
#define	ERR	(-1)

#define	FUJITU		0
#define	ESCP		1

#define	PRN_PAGE	0x80
#define	PRN_KINSOKU	0x40

#define	TAB		8

int	PRN_putc(char ch);
int	PRN_puts(char *str);
int	PRN_open(int mod,int mspc,int lspc,int mrg,int mmax,int lmax);
void	PRN_close(void);

void	PRN_char(char ch);

static jmp_buf	mark;
static int	prnt_mod=0;
static int	left_spc=4;
static int	moji_spc=0;
static int	line_spc=0;
static int	moji_cnt=0;
static int	line_cnt=0;
static int	page_cnt=0;
static int	moji_max=80;
static int	line_max=59;
static int	kanj_sft=0;
static int	kanj_bak=0;

static int hantozen(unsigned char code)
{
    static unsigned short ank_tbl[]={
        0x8140,0x8149,0x8168,0x8194,0x8190,0x8193,0x8195,0x8166,
        0x8169,0x816A,0x8196,0x817B,0x8143,0x817C,0x8144,0x815E,
        0x824F,0x8250,0x8251,0x8252,0x8253,0x8254,0x8255,0x8256,
        0x8257,0x8258,0x8146,0x8147,0x8183,0x8181,0x8184,0x8148,
        0x8197,0x8260,0x8261,0x8262,0x8263,0x8264,0x8265,0x8266,
	0x8267,0x8268,0x8269,0x826A,0x826B,0x826C,0x826D,0x826E,
        0x826F,0x8270,0x8271,0x8272,0x8273,0x8274,0x8275,0x8276,
        0x8277,0x8278,0x8279,0x816D,0x818F,0x816E,0x814F,0x8151,
        0x8166,0x8281,0x8282,0x8283,0x8284,0x8285,0x8286,0x8287,
        0x8288,0x8289,0x828A,0x828B,0x828C,0x828D,0x828E,0x828F,
        0x8290,0x8291,0x8292,0x8293,0x8294,0x8295,0x8296,0x8297,
        0x8298,0x8299,0x829A,0x816F,0x8162,0x8170,0x8150,0x85A1 };
    static unsigned short kana_tbl[]={
        0x8140,0x8142,0x8175,0x8176,0x8141,0x8145,0x8392,0x8340,
        0x8342,0x8344,0x8346,0x8348,0x8383,0x8385,0x8387,0x8362,
        0x815B,0x8341,0x8343,0x8345,0x8347,0x8349,0x834A,0x834C,
        0x834E,0x8350,0x8352,0x8354,0x8356,0x8358,0x835A,0x835C,
        0x835E,0x8360,0x8363,0x8365,0x8367,0x8369,0x836A,0x836B,
        0x836C,0x836D,0x836E,0x8371,0x8374,0x8377,0x837A,0x837D,
        0x837E,0x8380,0x8381,0x8382,0x8384,0x8386,0x8388,0x8389,
        0x838A,0x838B,0x838C,0x838D,0x838F,0x8393,0x814A,0x814B };

    if ( '\x20' <= code && code <= '\x7F' )
        return ank_tbl[code-0x20];
    else if ( '\xA0' <= code && code <= '\xDF' )
	return kana_tbl[code-0xA0];
    else
        return 0x85A1;
}
static int     kinsoku(unsigned short i)
{
    if ( (prnt_mod & PRN_KINSOKU) == 0 )
	return FALSE;

    if ( (i & 0xFF00) == 0 ) {
        switch(i) {
            case 0x27: case 0x29: case 0x2c: case 0x2e: case 0x3a:
            case 0x3b: case 0x7d:
            case 0xa1: case 0xa3: case 0xa4: case 0xde: case 0xdf:
                return TRUE;
        }
        return FALSE;
    }

    if (i >= 0x8141 && i <= 0x814c)
        return TRUE;
    if (i >= 0x8165 && i <= 0x817a) {
        if ((i % 2) == 0)
            return TRUE;
    }
    switch(i) {
        case 0x829f: case 0x82a1: case 0x82a3: case 0x82a5: case 0x82a7:
        case 0x82c1: case 0x82e1: case 0x82e3: case 0x82e5: case 0x82ec:
        case 0x8340: case 0x8342: case 0x8344: case 0x8346: case 0x8348:
        case 0x8362: case 0x8383: case 0x8385: case 0x8387: case 0x838e:
        case 0x8395: case 0x8396:
            return TRUE;
    }
    return FALSE;
}
static void	PRN_byte(char ch)
{
    int     sts;

    while ( (sts = PRB_chr(ch)) != 0x00 ) {
	if ( yesno("%s",
		( sts == 0x04 ? "プリンタに紙をセットしてください":
		( sts == 0x05 ? "プリンタをオンラインにしてください":
		( sts == 0x80 ? "プリンタの動作エラ−です":
			        "プリンタに異常が発生しました")))) == ERR )
	    longjmp(mark,sts);
    }
}
static void	PRN_word(short ch)
{
    PRN_byte(ch >> 8);
    PRN_byte((char)ch);
}
static void	PRN_printf(char *form,...)
{
    va_list arg;
    char    *p;
    char    tmp[256];

    va_start(arg,form);
    vsprintf(tmp,form,arg);
    va_end(arg);

    for ( p = tmp ; *p != '\0' ; )
	PRN_byte(*(p++));
}
static void	PRN_nprintf(int n,char *form,...)
{
    va_list arg;
    char    *p;
    char    tmp[256];

    va_start(arg,form);
    vsprintf(tmp,form,arg);
    va_end(arg);

    for ( p = tmp ; n > 0 ; n-- )
	PRN_byte(*(p++));
}
static unsigned short	lin_cvt(unsigned short ch)
{
    int     i;
    static struct {
	unsigned short sjis;
	unsigned short jis83;
    } cnv_tbl[]={
	{ 0xEF88,	0x84a5 },	/*  */
	{ 0xEF89,	0x84a6 },	/*  */
	{ 0xEF8A,	0x84a7 },	/*  */
	{ 0xEF87,	0x84a8 },	/*  */
	{ 0xEF8B,	0x84a9 },	/*  */

	{ 0xEF85,	0x849f },	/*  */
	{ 0xEF86,	0x84a0 },	/*  */
	{ 0xEF81,	0x84a1 },	/*  */
	{ 0xEF82,	0x84a2 },	/*  */
	{ 0xEF84,	0x84a3 },	/*  */
	{ 0xEF83,	0x84a4 },	/*  */

	{ 0xEF64,	0x84aa },	/* d */
	{ 0xEF65,	0x84ab },	/* e */
	{ 0xEF60,	0x84ac },	/* ` */
	{ 0xEF61,	0x84ad },	/* a */
	{ 0xEF63,	0x84ae },	/* c */
	{ 0xEF62,	0x84af },	/* b */

	{ 0xEF67,	0x84b0 },	/* g */
	{ 0xEF68,	0x84b1 },	/* h */
	{ 0xEF69,	0x84b2 },	/* i */
	{ 0xEF66,	0x84b3 },	/* f */
	{ 0xEF6A,	0x84b4 },	/* j */

	{ 0xEF74,	0x84b5 },	/* t */
	{ 0xEF76,	0x84b6 },	/* v */
	{ 0xEF78,	0x84b7 },	/* x */
	{ 0xEF72,	0x84b8 },	/* r */
	{ 0xEF7A,	0x84b9 },	/* z */
	{ 0xEF95,	0x84ba },	/*  */
	{ 0xEF97,	0x84bb },	/*  */
	{ 0xEF99,	0x84bc },	/*  */
	{ 0xEF93,	0x84bd },	/*  */
	{ 0xEF9B,	0x84be },	/*  */

	{ 0,0 } };

    for ( i = 0 ; cnv_tbl[i].sjis != 0 ; i++ ) {
	if ( cnv_tbl[i].sjis == ch ) {
	    ch = cnv_tbl[i].jis83;
	    break;
	}
    }
    return ch;
}
static void	PRN_kan_sub(short kan)
{
    switch(prnt_mod & 3) {
    case FUJITU:
	if ( kanj_sft == 0 )
	    PRN_printf("\x1b$B");	/* Kanji In */
	kan = lin_cvt(kan);
	PRN_word(sjistojis(kan));
	break;

    case ESCP:
	if ( kanj_sft == 0 )
	    PRN_printf("\x1c\x12");	/* Kanji in */
	PRN_word(sjistojis(kan));
	break;
    }
    kanj_sft = 1;
}
static void	PRN_ank_sub(char ank)
{
    switch(prnt_mod & 3) {
    case FUJITU:
	if ( kanj_sft != 0 )
	    PRN_printf("\x1b(H");	/* Kanji Out */
	PRN_byte(ank);
	break;

    case ESCP:
	if ( kanj_sft != 0 )
	    PRN_printf("\x1c\x0f");	/* Kanji Out (use KANJI code) */
	PRN_word(sjistojis(hantozen(ank)));
	break;
    }
    kanj_sft = 0;
}
static void	PRN_left_spc(void)
{
    int     n;

    switch(prnt_mod & 3) {
    case FUJITU:
	PRN_printf("\x1bQ1 |");
	break;
    case ESCP:
	PRN_printf("\x1c&\x1c\x0f");
        kanj_sft = 0;
	break;
    }
    for ( n = left_spc ; n > 0 ; n-- )
	PRN_ank_sub(' ');
}
static void	PRN_page_spc(void)
{
    int     n;
    char    tmp[32];

    if ( (prnt_mod & PRN_PAGE) == 0 )
	goto ENDOF;

    while ( line_cnt++ <= line_max ) {
	PRN_byte('\r');
	PRN_byte('\n');
    }

    PRN_left_spc();
    for ( n = moji_max / 2 - 3 ; n > 0 ; n-- )
	PRN_ank_sub(' ');
    sprintf(tmp,"- %d -",++page_cnt);
    for ( n = 0 ; tmp[n] != '\0' ; n++ )
	PRN_ank_sub(tmp[n]);
    PRN_byte('\r');
    PRN_byte('\n');

ENDOF:

    PRN_byte('\x0C');
}
static void	PRN_kan(short kan)
{
    if ( (moji_cnt + 1) >= moji_max && !kinsoku(kan) ) {
	PRN_char('\r');
	PRN_char('\n');
    }

    if ( moji_cnt == 0 )
	PRN_left_spc();

    PRN_kan_sub(kan);

    moji_cnt += 2;
}
static void	PRN_ank(char ank)
{
    if ( moji_cnt >= moji_max && !kinsoku(ank) ) {
	PRN_char('\r');
	PRN_char('\n');
    }

    if ( moji_cnt == 0 )
	PRN_left_spc();

    PRN_ank_sub(ank);

    moji_cnt++;
}
static void	PRN_char(char ch)
{
    int     n;

    if ( kanj_bak != 0 ) {
	if ( iskanji2(ch) ) {
	    n = (kanj_bak << 8) | (unsigned char)ch;
	    kanj_bak = 0;
	    PRN_kan(n);
	    return;
	}
	PRN_ank(kanj_bak);
	kanj_bak = 0;
    }

    if ( iskanji(ch) )
	kanj_bak = ch;

    else if ( ch >= ' ' )
	PRN_ank(ch);

    else if ( ch == '\r' ) {
	PRN_byte(ch);
	moji_cnt = 0;

    } else if ( ch == '\n' ) {
	PRN_byte(ch);
	moji_cnt = 0;
	if ( ++line_cnt >= line_max )
	    PRN_char('\x0C');

    } else if ( ch == '\t' ) {
	n = TAB - moji_cnt % TAB;
	while ( n-- > 0 )
	    PRN_ank(' ');

    } else if ( ch == '\x0C' ) {
	PRN_page_spc();
	moji_cnt = line_cnt = 0;
    }
}
int	PRN_putc(char ch)
{
    int     i;

    if ( (i = setjmp(mark)) != 0 )
	return ERR;

    PRN_char(ch);

    return FALSE;
}
int	PRN_puts(char *str)
{
    int     i;

    if ( (i = setjmp(mark)) != 0 )
	return ERR;

/******************************
    while ( *str != '\0' ) {
	if ( *str == '\n' )
	    PRN_char('\r');
	PRN_char(*(str++));
    }
*******************************/

    while ( *str != '\0' )
	PRN_char(*(str++));

    PRN_char('\r');
    PRN_char('\n');

    return FALSE;
}
void	PRN_file(char *file)
{
    int     ch;
    FILE    *fp;

    if ( setjmp(mark) != 0 )
	return;

    if ( (fp = fopen(file,"r")) == NULL )
	return;

    while ( (ch = getc(fp)) != EOF ) {
	if ( ch == '\n' )
	    PRN_char('\r');
	PRN_char(ch);
    }

    fclose(fp);
}
int	PRN_open(int mod,int mspc,int lspc,int mrg,int mmax,int lmax)
{
    int     i;

    prnt_mod = mod;
    moji_spc = mspc;
    line_spc = lspc;
    moji_max = mmax;
    line_max = lmax;
    left_spc = mrg;
    moji_cnt = line_cnt = page_cnt = 0;
    kanj_sft = kanj_bak = 0;

    if ( (i = setjmp(mark)) != 0 )
	return ERR;

    switch(prnt_mod & 3) {
    case FUJITU:
	PRN_printf("\x1bQ3 \x5c");
	i = moji_spc + 24;
	PRN_printf("\x1c$%c%c",i/10+0x20,i%10+0x70);
	i = line_spc + 24;
	PRN_printf("\x1c%%%c%c\x1b(H",i/10+0x20,i%10+0x70);
	break;

    case ESCP:
	i = moji_spc / 2;
	PRN_nprintf(4,"\x1cS%c%c",i,moji_spc-i);
	i = (moji_spc + 24) / 2 - 11;
	PRN_nprintf(4,"\x1cT%c%c",i/2,i-i/2);
	PRN_printf("%s",(moji_spc & 1) != 0 ? "\x1cU":"\x1cV");
	PRN_nprintf(3,"\x1b\x33%c",line_spc+24);
	PRN_printf("\x1c\x0f");
	break;
    }

    return FALSE;
}
void	PRN_close(void)
{
    if ( line_cnt > 0 )
	PRN_putc('\x0C');
}

/**************************************************************

01234567890123456789012345678901234567890123456789012345678901234567890123456789               012345678901234567890123456789012345678901234567890123
0          +----------------------------------------------------+
1          |                                                    |
2          |           テキスト印刷の設定および印刷             |
3          |                                                    |
4          | 用 紙  選 択  A4  B4  B5       +----------------+  |
5          | １行の文字数  ＜ 000 ＞        | +------------+ |  |
6          | １ペ−ジ行数  ＜ 000 ＞        | |            | |  |
7          | 左余白文字数  ＜ 000 ＞        | |            | |  |
8          | 文 字  間 隔  ＜ 000 ＞        | |            | |  |
9          |   行   間 隔  ＜ 000 ＞        | +------------+ |  |
10         | ﾌﾟﾘﾝﾀの種 類  FM系 ESCP系      +----------------+  |
11         |                                                    |
12         |                | 印  刷 | | 取  消 |               |
13         |                                                    |
14         +----------------------------------------------------+

*****************************************************************/

#define	LPT_X1		(15*8-4)
#define	LPT_Y1		(240-7*22)
#define	LPT_X2		(65*8+3)
#define	LPT_Y2		(LPT_Y1+12*22)

#define	LPT_MSG_X	(LPT_X1+12*8)
#define	LPT_MSG_Y	(LPT_Y1+1*22)

#define	LPT_PAP_X	(LPT_X1+2*8)
#define	LPT_PAP_Y	(LPT_Y1+3*22)

#define	LPT_MMX_X	(LPT_X1+2*8)
#define	LPT_MMX_Y	(LPT_Y1+4*22)

#define	LPT_LMX_X	(LPT_X1+2*8)
#define	LPT_LMX_Y	(LPT_Y1+5*22)

#define	LPT_MRG_X	(LPT_X1+2*8)
#define	LPT_MRG_Y	(LPT_Y1+6*22)

#define	LPT_MSC_X	(LPT_X1+2*8)
#define	LPT_MSC_Y	(LPT_Y1+7*22)

#define	LPT_LSC_X	(LPT_X1+2*8)
#define	LPT_LSC_Y	(LPT_Y1+8*22)

#define	LPT_MOD_X	(LPT_X1+2*8)
#define	LPT_MOD_Y	(LPT_Y1+9*22)

#define	LPT_YES_X	((LPT_X1+LPT_X2)/2-(10*8))
#define	LPT_YES_Y	(LPT_Y1+11*22-8)

#define	LPT_NO_X	((LPT_X1+LPT_X2)/2+(2*8))
#define	LPT_NO_Y	(LPT_Y1+11*22-8)

#define	LPT_IMG_X	(LPT_X1+32*8)
#define	LPT_IMG_Y	(LPT_Y1+3*22)

int	LPT_open(void)
{
    int    sw,bx,by;
    int    cd,x1,x2,y1,y2;
    BLOCK  *sp;
    EVENT  *ep=NULL;
    static int     pap=0,mod=0;
    static struct {
	int	mmx,lmx,mrg,msc,lsc;
	int	yoko,tate;
    } you[3]={
	{  80,59,10,4,6,1494,2106 },	/* A4 */
	{  80,48, 4,4,6,1296,1818 },	/* B4 */
	{ 100,74,12,4,6,1818,2592 },
    };
    static struct {
	int	yofs,tofs;
    } prn[2]={
	{ 63,144 },{ 0,177 },
    };

    MOS_disp(OFF);
    sp = DSP_push_vram(LPT_X1,LPT_Y1,LPT_X2,LPT_Y2);
    DSP_opbox(LPT_X1,LPT_Y1,LPT_X2,LPT_Y2);
    DSP_wbox(LPT_X1,LPT_Y1,LPT_X2,LPT_Y2,LINE_COL,FILD_COL,M_PSET);

    gputs(LPT_MSG_X,LPT_MSG_Y,CHR_COL,FILD_COL,"テキスト印刷の設定および印刷");
    gputs(LPT_PAP_X,LPT_PAP_Y,CHR_COL,FILD_COL,"用 紙  選 択");
    gputs(LPT_MMX_X,LPT_MMX_Y,CHR_COL,FILD_COL,"１行の文字数");
    gputs(LPT_LMX_X,LPT_LMX_Y,CHR_COL,FILD_COL,"１ペ−ジ行数");
    gputs(LPT_MRG_X,LPT_MRG_Y,CHR_COL,FILD_COL,"左余白文字数");
    gputs(LPT_MSC_X,LPT_MSC_Y,CHR_COL,FILD_COL,"文 字  間 隔");
    gputs(LPT_LSC_X,LPT_LSC_Y,CHR_COL,FILD_COL,"  行   間 隔");
    gputs(LPT_MOD_X,LPT_MOD_Y,CHR_COL,FILD_COL,"ﾌﾟﾘﾝﾀの種 類");

    ep = EVT_sw(ep,0,LPT_PAP_X+14*8,LPT_PAP_Y,CHR_COL,WIND_COL,"A4");
    ep = EVT_sw(ep,1,LPT_PAP_X+18*8,LPT_PAP_Y,CHR_COL,WIND_COL,"B5");
    ep = EVT_sw(ep,2,LPT_PAP_X+22*8,LPT_PAP_Y,CHR_COL,WIND_COL,"B4");

    ep = EVT_sw(ep,3,LPT_MMX_X+14*8,LPT_MMX_Y,CHR_COL,WIND_COL,"＜");
    ep = EVT_sw(ep,4,LPT_MMX_X+21*8,LPT_MMX_Y,CHR_COL,WIND_COL,"＞");

    ep = EVT_sw(ep,5,LPT_LMX_X+14*8,LPT_LMX_Y,CHR_COL,WIND_COL,"＜");
    ep = EVT_sw(ep,6,LPT_LMX_X+21*8,LPT_LMX_Y,CHR_COL,WIND_COL,"＞");

    ep = EVT_sw(ep,7,LPT_MRG_X+14*8,LPT_MRG_Y,CHR_COL,WIND_COL,"＜");
    ep = EVT_sw(ep,8,LPT_MRG_X+21*8,LPT_MRG_Y,CHR_COL,WIND_COL,"＞");

    ep = EVT_sw(ep,9,LPT_MSC_X+14*8,LPT_MSC_Y,CHR_COL,WIND_COL,"＜");
    ep = EVT_sw(ep,10,LPT_MSC_X+21*8,LPT_MSC_Y,CHR_COL,WIND_COL,"＞");

    ep = EVT_sw(ep,11,LPT_LSC_X+14*8,LPT_LSC_Y,CHR_COL,WIND_COL,"＜");
    ep = EVT_sw(ep,12,LPT_LSC_X+21*8,LPT_LSC_Y,CHR_COL,WIND_COL,"＞");

    ep = EVT_sw(ep,13,LPT_MOD_X+14*8,LPT_MOD_Y,CHR_COL,WIND_COL,"FM系");
    ep = EVT_sw(ep,14,LPT_MOD_X+20*8,LPT_MOD_Y,CHR_COL,WIND_COL,"ESCP系");

    ep = EVT_sw(ep,15,LPT_YES_X,LPT_YES_Y,CHR_COL,WIND_COL," 印  刷");
    ep = EVT_sw(ep,16,LPT_NO_X,LPT_NO_Y,CHR_COL,WIND_COL," 取  消 ");

    MOS_rdpos(&sw,&bx,&by);
    MOS_setpos((LPT_X1+LPT_X2)/2,(LPT_Y1+LPT_Y2)/2);
    MOS_disp(ON);

    for ( cd = FALSE ; cd == FALSE ; ) {
	MOS_disp(OFF);

	gprintf(LPT_PAP_X+14*8,LPT_PAP_Y,
			pap != 0 ? CHR_COL:XERR_COL,WIND_COL,"A4");
	gprintf(LPT_PAP_X+18*8,LPT_PAP_Y,
			pap != 1 ? CHR_COL:XERR_COL,WIND_COL,"B5");
	gprintf(LPT_PAP_X+22*8,LPT_PAP_Y,
			pap != 2 ? CHR_COL:XERR_COL,WIND_COL,"B4");

	gprintf(LPT_MMX_X+17*8,LPT_MMX_Y,CHR_COL,FILD_COL,"%3d",you[pap].mmx);
	gprintf(LPT_LMX_X+17*8,LPT_LMX_Y,CHR_COL,FILD_COL,"%3d",you[pap].lmx);
	gprintf(LPT_MRG_X+17*8,LPT_MRG_Y,CHR_COL,FILD_COL,"%3d",you[pap].mrg);
	gprintf(LPT_MSC_X+17*8,LPT_MSC_Y,CHR_COL,FILD_COL,"%3d",you[pap].msc);
	gprintf(LPT_LSC_X+17*8,LPT_LSC_Y,CHR_COL,FILD_COL,"%3d",you[pap].lsc);

	gprintf(LPT_MOD_X+14*8,LPT_MOD_Y,
			mod != 0 ? CHR_COL:XERR_COL,WIND_COL,"FM系");
	gprintf(LPT_MOD_X+20*8,LPT_MOD_Y,
			mod != 1 ? CHR_COL:XERR_COL,WIND_COL,"ESCP系");

	DSP_box(LPT_IMG_X,LPT_IMG_Y,LPT_IMG_X+120,LPT_IMG_Y+150,
			FILD_COL,M_PSET);

	x1 = 0;
	y1 = 0;
	x2 = you[pap].yoko;
	y2 = you[pap].tate;

	x1 = x1 / 18 + LPT_IMG_X;
	y1 = y1 / 18 + LPT_IMG_Y;
	x2 = x2 / 18 + LPT_IMG_X;
	y2 = y2 / 18 + LPT_IMG_Y;
	DSP_rbox(x1,y1,x2,y2,LINE_COL,WIND_COL,M_PSET);

	x1 = prn[mod].yofs + (you[pap].mrg*(24+you[pap].msc)/2);
	y1 = prn[mod].tofs;
	x2 = x1 + (you[pap].mmx*(24+you[pap].msc)/2);
	y2 = y1 + (you[pap].lmx*(24+you[pap].lsc));

	x1 = x1 / 18 + LPT_IMG_X;
	y1 = y1 / 18 + LPT_IMG_Y;
	x2 = x2 / 18 + LPT_IMG_X;
	y2 = y2 / 18 + LPT_IMG_Y;
	DSP_box(x1,y1,x2,y2,XWIND_COL,M_PSET);

	MOS_disp(ON);

	switch(EVT_wait(ep)) {
	case 0: pap = 0; break;
	case 1: pap = 1; break;
	case 2: pap = 2; break;

	case 3:
	    if ( you[pap].mmx > 1 )
		you[pap].mmx--;
	    break;
	case 4:
	    if ( you[pap].yoko > 
	(prn[mod].yofs+(you[pap].mrg+you[pap].mmx+1)*(24+you[pap].msc)/2) )
		you[pap].mmx++;
	    break;

	case 5:
	    if ( you[pap].lmx > 3 )
		you[pap].lmx--;
	    break;
	case 6:
	    if ( you[pap].tate >
		(prn[mod].tofs+(you[pap].lmx+1)*(24+you[pap].lsc)) )
		you[pap].lmx++;
	    break;

	case 7:
	    if ( you[pap].mrg > 0 )
		you[pap].mrg--;
	    break;
	case 8:
	    if ( you[pap].yoko > 
	(prn[mod].yofs+(you[pap].mrg+you[pap].mmx+1)*(24+you[pap].msc)/2) )
		you[pap].mrg++;
	    break;

	case 9:
	    if ( you[pap].msc > 0 )
		you[pap].msc--;
	    break;
	case 10:
	    if ( you[pap].yoko > 
	(prn[mod].yofs+(you[pap].mrg+you[pap].mmx)*(24+you[pap].msc+1)/2) )
		you[pap].msc++;
	    break;

	case 11:
	    if ( you[pap].lsc > 0 )
		you[pap].lsc--;
	    break;
	case 12:
	    if ( you[pap].tate >
		(prn[mod].tofs+you[pap].lmx*(24+you[pap].lsc+1)) )
		you[pap].lsc++;
	    break;

	case 13: mod = FUJITU; break;
	case 14: mod = ESCP;   break;

	case 15: cd = TRUE; break;
	case 16: cd = ERR;  break;
	}
    }

    EVT_free(ep);
    MOS_disp(OFF);
    DSP_pop_vram(sp);
    DSP_clbox(LPT_X1,LPT_Y1,LPT_X2,LPT_Y2);
    MOS_setpos(bx,by);
    MOS_disp(ON);

    if ( cd == TRUE )
	return PRN_open(mod|0x80,you[pap].msc,you[pap].lsc,you[pap].mrg,
		you[pap].mmx,you[pap].lmx-2);
    return ERR;
}
