コード例 #1
0
ファイル: bdos.c プロジェクト: jhallen/cpm
void check_BDOS_hook(z80info *z80) {
    int i;
    char name[32];
    char name2[32];
    FILE *fp;
    char *s, *t;
    const char *mode;
    if (trace_bdos)
    {
        printf("\r\nbdos %d %s (AF=%04x BC=%04x DE=%04x HL =%04x SP=%04x STACK=", C, bdos_decode(C), AF, BC, DE, HL, SP);
	for (i = 0; i < 8; ++i)
	    printf(" %4x", z80->mem[SP + 2*i]
		   + 256 * z80->mem[SP + 2*i + 1]);
	printf(")\r\n");
    }
    switch (C) {
    case  0:    /* System Reset */
	warmboot(z80);
	return;
#if 0
	for (i = 0; i < 0x1600; ++i)
	    z80->mem[i+BIOS-0x1600] = cpmsys[i];
	BC = 0;
	PC = BIOS-0x1600+3;
	SP = 0x80;
#endif
	break;
    case 1:     /* Console Input */
	HL = kget(0);
	B = H; A = L;
	if (A < ' ') {
	    switch(A) {
	    case '\r':
	    case '\n':
	    case '\t':
		vt52(A);
		break;
	    default:
		vt52('^');
		vt52((A & 0xff)+'@');
		if (A == 3) {	/* ctrl-C pressed */
		    /* PC = BIOS+3;
		       check_BIOS_hook(); */
		    warmboot(z80);
		    return;
		}
	    }
	} else {
	    vt52(A);
	}
	break;
    case 2:     /* Console Output */
	vt52(0x7F & E);
	HL = 0;
        B = H; A = L;
	break;
    case 6:     /* direct I/O */
	switch (E) {
	case 0xff:  if (!constat()) {
	    HL = 0;
            B = H; A = L;
	    F = 0;
	    break;
	}
	case 0xfd:  HL = kget(0);
            B = H; A = L;
	    F = 0;
	    break;
	case 0xfe:  HL = constat() ? 0xff : 0;
            B = H; A = L;
	    F = 0;
	    break;
	default:    vt52(0x7F & E);
            HL = 0;
            B = H; A = L;
	}
	break;
    case 9:	/* Print String */
	s = (char *)(z80->mem + DE);
	while (*s != '$')
	    vt52(0x7F & *s++);
        HL = 0;
        B = H; A = L;
	break;
    case 10:    /* Read Command Line */
	s = rdcmdline(z80, *(unsigned char *)(t = (char *)(z80->mem + DE)), 1);
	if (PC == BIOS+3) { 	/* ctrl-C pressed */
	    /* check_BIOS_hook(); */		/* execute WBOOT */
	    warmboot(z80);
	    return;
	}
	++t;
	for (i = 0; i <= *(unsigned char *)s; ++i)
	    t[i] = s[i];
        HL = 0;
        B = H; A = L;
	break;
    case 12:    /* Return Version Number */
	HL = 0x22; /* Emulate CP/M 2.2 */
        B = H; A = L;
	F = 0;
	break;
    case 26:    /* Set DMA Address */
	z80->dma = DE;
	HL = 0;
        B = H; A = L;
	break;
    case 32:    /* Get/Set User Code */
	if (E == 0xff) {  /* Get Code */
	    HL = usercode;
            B = H; A = L;
	} else {
	    usercode = E;
            HL = 0; /* Or does it get usercode? */
            B = H; A = L;
        }
	break;

	/* dunno if these are correct */

    case 11:	/* Console Status */
	HL = (constat() ? 0xff : 0x00);
        B = H; A = L;
	F = 0;
	break;

    case 13:	/* reset disk system */
	/* storedfps = 0; */	/* WS crashes then */
	if (dp)
	    closedir(dp);
	dp = NULL;
	z80->dma = 0x80;
	HL = 0;
        B = H; A = L;
	/* select only A:, all r/w */
	break;
    case 14:	/* select disk */
	HL = 0;
        B = H; A = L;
	break;
    case 15:	/* open file */
	mode = "r+b";
    fileio:
	FCB_to_filename(z80->mem+DE, name); /* Try lowercase */
	if (!(fp = fopen(name, mode))) {
	    FCB_to_ufilename(z80->mem+DE, name); /* Try all uppercase instead */
            if (!(fp = fopen(name, mode))) {
	            FCB_to_filename(z80->mem+DE, name);
		    if (*mode == 'r') {
			char ss[50];
			sprintf(ss, "%s/%s", CPMLIBDIR, name);
			fp = fopen(ss, mode);
			if (!fp)
			  fp = fopen(ss, "rb");
		    }
		    if (!fp) {
			/* still no success */
			HL = 0xFF;
                        B = H; A = L;
			F = 0;
			break;
		    }
            }
	}
	/* success */

	/* memset(z80->mem + DE + 12, 0, 33-12); */

	/* User has to set EX, S2, and CR: don't change these- some set them to non-zero */
	z80->mem[DE + FCB_S1] = 0;
	/* memset(z80->mem + DE + 16, 0, 16); */ /* Clear D0-Dn */

	/* Should we clear R0 - R2? Nope: then we overlap the following area. */
	/* memset(z80->mem + DE + 33, 0, 3); */

	/* We need to set high bit of S2: means file is open? */
	z80->mem[DE + FCB_S2] |= 0x80;

	z80->mem[DE + FCB_RC] = 0;	/* rc field of FCB */

	if (fixrc(z80, fp)) { /* Not a real file? */
	    HL = 0xFF;
            B = H; A = L;
	    F = 0;
	    fclose(fp);
	    break;
	}
	HL = 0;
        B = H; A = L;
	F = 0;
	/* where to store fp? */
	storefp(z80, fp, DE);
	/* printf("opening file %s\n", name); */
	break;
    case 16:	/* close file */
    	z80->mem[DE + FCB_S2] &= 0x7F; /* Clear high bit: indicates closed */
	fp = getfp(z80, DE);
	delfp(z80, DE);
	fclose(fp);
	HL = 0;
        B = H; A = L;
	/* printf("close file\n"); */
	break;
    case 17:	/* search for first */
	if (dp)
	    closedir(dp);
	if (!(dp = opendir("."))) {
	    fprintf(stderr, "opendir fails\n");
            resetterm();
	    exit(1);
	}
	sfn = DE;
	/* fall through */
    case 18:	/* search for next */
	if (!dp)
	    goto retbad;
	{   struct dirent *de;
	    unsigned char *p;
	    const char *sr;
	nocpmname:
	    if (!(de = readdir(dp))) {
		closedir(dp);
		dp = NULL;
	    retbad:
	        HL = 0xff;
                B = H; A = L;
		F = 0;
		break;
	    }
	    /* printf("\r\nlooking at %s\r\n", de->d_name); */
	    /* compare data */
	    memset(p = z80->mem+z80->dma, 0, 128);	/* dmaaddr instead of DIRBUF!! */
	    if (*de->d_name == '.')
		goto nocpmname;
	    if (strchr(sr = de->d_name, '.')) {
		if (strlen(de->d_name) > 12)	/* POSIX: namlen */
		    goto nocpmname;
	    } else if (strlen(de->d_name) > 8)
		    goto nocpmname;
	    /* seems OK */
	    for (i = 0; i < 8; ++i)
		if (*sr != '.' && *sr) {
		    *++p = toupper(*(unsigned char *)sr); sr++;
		} else
		    *++p = ' ';
	    /* skip dot */
	    while (*sr && *sr != '.')
		++sr;
	    while (*sr == '.')
		++sr;
	    for (i = 0; i < 3; ++i)
		if (*sr != '.' && *sr) {
		    *++p = toupper(*(unsigned char *)sr); sr++;
		} else
		    *++p = ' ';
	    /* OK, fcb block is filled */
	    /* match name */
	    p -= 11;
	    sr = (char *)(z80->mem + sfn);
	    for (i = 1; i <= 12; ++i)
		if (sr[i] != '?' && sr[i] != p[i])
		    goto nocpmname;
	    /* yup, it matches */
	    HL = 0x00;	/* always at pos 0 */
            B = H; A = L;
	    F = 0;
	    p[32] = p[64] = p[96] = 0xe5;
	}
	break;
    case 19:	/* delete file (no wildcards yet) */
	FCB_to_filename(z80->mem + DE, name);
	unlink(name);
	HL = 0;
        B = H; A = L;
	break;
    case 20:	/* read sequential */
	fp = getfp(z80, DE);
    readseq:
	if (!fseek(fp, SEQ_ADDRESS, SEEK_SET) && ((i = fread(z80->mem+z80->dma, 1, 128, fp)) > 0)) {
	    long ofst = ftell(fp) + 127;
	    if (i != 128)
		memset(z80->mem+z80->dma+i, 0x1a, 128-i);
	    z80->mem[DE + FCB_CR] = SEQ_CR(ofst);
	    z80->mem[DE + FCB_EX] = SEQ_EX(ofst);
	    z80->mem[DE + FCB_S2] = (0x80 | SEQ_S2(ofst));
	    fixrc(z80, fp);
	    HL = 0x00;
            B = H; A = L;
	} else {
	    HL = 0x1;	/* ff => pip error */
            B = H; A = L;
	}    
	break;
    case 21:	/* write sequential */
	fp = getfp(z80, DE);
    writeseq:
	if (!fseek(fp, SEQ_ADDRESS, SEEK_SET) && fwrite(z80->mem+z80->dma, 1, 128, fp) == 128) {
	    long ofst = ftell(fp);
	    z80->mem[DE + FCB_CR] = SEQ_CR(ofst);
	    z80->mem[DE + FCB_EX] = SEQ_EX(ofst);
	    z80->mem[DE + FCB_S2] = (0x80 | SEQ_S2(ofst));
	    fixrc(z80, fp);
	    HL = 0x00;
            B = H; A = L;
	} else {
	    HL = 0xff;
            B = H; A = L;
	}
	break;
    case 22:	/* make file */
	mode = "w+b";
	goto fileio;
    case 23:	/* rename file */
	FCB_to_filename(z80->mem + DE, name);
	FCB_to_filename(z80->mem + DE + 16, name2);
	/* printf("rename %s %s called\n", name, name2); */
	rename(name, name2);
	HL = 0;
        B = H; A = L;
	break;
    case 24:	/* return login vector */
	HL = 1;	/* only A: online */
        B = H; A = L;
	F = 0;
	break;
    case 25:	/* return current disk */
	HL = 0;	/* only A: */
        B = H; A = L;
	F = 0;
	break;
    case 29:	/* return r/o vector */
	HL = 0;	/* none r/o */
        B = H; A = L;
	F = 0;
	break;
    case 31:    /* get disk parameters */
        HL = DPB0;    /* only A: */
        B = H; A = L;
        break;
    case 33:	/* read random record */
        {
        long ofst;
	fp = getfp(z80, DE);
	/* printf("data is %02x %02x %02x\n", z80->mem[z80->regde+33],
	       z80->mem[z80->regde+34], z80->mem[z80->regde+35]); */
	ofst = ADDRESS;
        z80->mem[DE + FCB_CR] = SEQ_CR(ofst);
	z80->mem[DE + FCB_EX] = SEQ_EX(ofst);
	z80->mem[DE + FCB_S2] = (0x80 | SEQ_S2(ofst));
	goto readseq;
	}
    case 34:	/* write random record */
        {
        long ofst;
	fp = getfp(z80, DE);
	/* printf("data is %02x %02x %02x\n", z80->mem[z80->regde+33],
	       z80->mem[z80->regde+34], z80->mem[z80->regde+35]); */
	ofst = ADDRESS;
        z80->mem[DE + FCB_CR] = SEQ_CR(ofst);
	z80->mem[DE + FCB_EX] = SEQ_EX(ofst);
	z80->mem[DE + FCB_S2] = (0x80 | SEQ_S2(ofst));
	goto writeseq;
	}
    case 35:	/* compute file size */
	fp = getfp(z80, DE);
	fseek(fp, 0L, SEEK_END);
	/* fall through */
    case 36:	/* set random record */
	fp = getfp(z80, DE);
	{   
	    long ofst = ftell(fp) + 127;
	    long pos = (ofst >> 7);
	    HL = 0x00;	/* dunno, if necessary */
            B = H; A = L;
	    z80->mem[DE + FCB_R0] = pos & 0xff;
	    z80->mem[DE + FCB_R1] = pos >> 8;
	    z80->mem[DE + FCB_R2] = pos >> 16;
            z80->mem[DE + FCB_CR] = SEQ_CR(ofst);
	    z80->mem[DE + FCB_EX] = SEQ_EX(ofst);
	    z80->mem[DE + FCB_S2] = (0x80 | SEQ_S2(ofst));
	    fixrc(z80, fp);
	}
	break;
    case 41:
	for (s = (char *)(z80->mem + DE); *s; ++s)
	    *s = tolower(*(unsigned char *)s);
	HL = (restricted_mode || chdir((char  *)(z80->mem + DE))) ? 0xff : 0x00;
        B = H; A = L;
	break;
    default:
	printf("\n\nUnrecognized BDOS-Function:\n");
	printf("AF=%04x  BC=%04x  DE=%04x  HL=%04x  SP=%04x\nStack =",
	       AF, BC, DE, HL, SP);
	for (i = 0; i < 8; ++i)
	    printf(" %4x", z80->mem[SP + 2*i]
		   + 256 * z80->mem[SP + 2*i + 1]);
	printf("\r\n");
	resetterm();
	exit(1);
    }
    z80->mem[PC = DIRBUF-1] = 0xc9; /* Return instruction */
    return;
}
コード例 #2
0
ファイル: bios.c プロジェクト: jhallen/cpm
static void
boot(z80info *z80)
{
	z80->drive = 0;
	warmboot(z80);
}
コード例 #3
0
ファイル: WARM.C プロジェクト: krattai/flosh
void main(void)
{
	warmboot();
}