home *** CD-ROM | disk | FTP | other *** search
- /*
-
- bios.c - CP/M BIOS in C
-
- (C) MCMXM - Nick Sayer - All rights reserved.
-
- See COPYRIGHT file for more details.
-
- */
-
- #include <stdio.h>
- #include "z80.h"
- #include "upm.h"
-
- #include <sys/ioctl.h>
-
- #define IO_BYTE 3
-
- WORD trk,sec,dma,dsk;
-
- char cold_flag=0;
-
- /*
-
- Our Z-80 BIOS is just HALT, RET, NOP, HALT, RET, NOP..... We find out
- which BIOS jump it is by dividing the LSB of PC by 3.
-
- THIS PRESUMES BIOS BEGINS ON AN EVEN PAGE BOUNDARY. This is a pretty
- good assumption.
-
- BIOS Memory map:
-
- 0000 - jump table
- 0080 - DIRBUF
- 0100 - disk buffers - this set up in upm.c
-
- It is up to upm.c to set up the disk buffers as necessary for
- different size devices, and set up the pointers in diskbufs[].
-
- */
-
- char bios()
- {
- register char bios_call;
-
- bios_call=(PC&0xff)/3;
- PC++; /* Skip past the HALT */
-
- if(debugflag) printf("\tBios! - %d from %x\n\r",bios_call,PC);
-
- switch(bios_call)
- {
- case 0:cold_boot(); /* DON'T break... we WANT to fall into warm boot! */
- case 1:warm_boot();
- break;
- case 2:stat_con();
- break;
- case 3:read_con();
- break;
- case 4:write_con();
- break;
- case 5:write_lst();
- break;
- case 6:write_pun();
- break;
- case 7:read_rdr();
- break;
- case 8:home_dsk();
- break;
- case 9:sel_dsk();
- break;
- case 10:set_trk();
- break;
- case 11:set_sec();
- break;
- case 12:set_dma();
- break;
- case 13:read_dsk();
- break;
- case 14:write_dsk();
- break;
- case 15:stat_lst();
- break;
- case 16:sec_trans();
- break;
- case 30:shell_escape();
- break;
- case 31:quit(); return 1;
- default:
- printf("unhandled bios call %d\n\r",bios_call);
- debugit();
- }
-
- return 0;
- }
-
- quit()
- {
- }
-
- shell_escape()
- {
- debugit();
- }
-
- cold_boot()
- {
-
- real_z80_mem[IO_BYTE]=0x95; /* CRT, PUN, RDR, LPT */
- real_z80_mem[0]=0xC3;
- real_z80_mem[1]=0x03;
- real_z80_mem[2]=(ccp_start>>8)+8+0xe; /* First page of BIOS */
- real_z80_mem[5]=0xC3;
- real_z80_mem[6]=0x06;
- real_z80_mem[7]=(ccp_start>>8)+8; /* First page of BDOS */
- printf("\n\r\n\rCP/M Ver 2.2\n\rCopyright Digital Research, Inc.\n\r");
- printf("UP/M Version 1.0B\n\rCopyright Nick Sayer\n\r\n\r");
- cold_flag++;
-
- }
-
- warm_boot()
- {
- register WORD i;
-
- for(i=0;i<SIZE_CCP_IMAGE;i++)
- real_z80_mem[i+ccp_start]=ccp_image[i];
-
- if (cold_flag)
- {
- cold_flag=0;
- PC=ccp_start;
- }
- else
- PC=ccp_start+3;
-
- BC=0;
- debugit();
- }
-
- stat_con()
- {
- FILE *which;
- int ret;
-
- switch (real_z80_mem[IO_BYTE]&0x3)
- {
- case 0:which=devices[F_TY]; break;
- case 1:which=stdin; break;
- case 2:which=stdin; break;
- case 3:which=devices[F_U1]; break;
- }
-
- ioctl(fileno(which),FIONREAD,&ret);
- AF=(AF&0xff)|(ret?0xff00:0);
- /* */
- /* if(!ret) AF |= FLAG_Z; else AF &= ~FLAG_Z; */
- AF |= FLAG_Z;
-
- }
-
- read_con()
- {
- FILE *which;
-
- switch (real_z80_mem[IO_BYTE]&0x3)
- {
- case 0:which=devices[F_TY]; break;
- case 1:which=stdin; break;
- case 2:which=stdin; break;
- case 3:which=devices[F_U1]; break;
- }
- if (which==NULL)
- {
- AF&=0xff;
- return;
- }
- AF=(AF&0xff)|(getc(which)<<8);
- }
-
- write_con()
- {
- FILE *which;
-
- switch(real_z80_mem[IO_BYTE]&0x3)
- {
- case 0:which=devices[F_TY]; break;
- case 1:which=stdout; break;
- case 2:write_lst(); which=stdout; break;
- case 3:which=devices[F_U1]; break;
- }
- if (which!=NULL)
- putc(BC&0xff,which);
- }
-
- stat_lst()
- {
- FILE *which;
-
- /*
- switch((real_z80_mem[IO_BYTE]>>6)&0x3)
- {
- case 0:which=devices[F_TY]; break;
- case 1:which=stdout; break;
- case 2:which=devices[F_LP]; break;
- case 3:which=devices[F_U1]; break;
- }
-
- Under unix, writing is always fine.
-
- */
- AF|=0xff00;
- }
-
- write_lst()
- {
- FILE *which;
-
- switch((real_z80_mem[IO_BYTE]>>6)&0x3)
- {
- case 0:which=devices[F_TY]; break;
- case 1:which=stdout; break;
- case 2:which=devices[F_LP]; break;
- case 3:which=devices[F_U1]; break;
- }
- if (which!=NULL)
- putc(BC&0xff,which);
- }
-
- write_pun()
- {
- FILE *which;
-
- switch((real_z80_mem[IO_BYTE]>>4)&0x3)
- {
- case 0:which=devices[F_TY]; break;
- case 1:which=devices[F_PT]; break;
- case 2:which=devices[F_U1]; break;
- case 3:which=devices[F_U2]; break;
- }
- if (which!=NULL)
- putc(BC&0xff,which);
- }
-
- read_rdr()
- {
- FILE *which;
-
- switch((real_z80_mem[IO_BYTE]>>2)&0x3)
- {
- case 0:which=devices[F_TY]; break;
- case 1:which=devices[F_PT]; break;
- case 2:which=devices[F_U1]; break;
- case 3:which=devices[F_U2]; break;
- }
- if (which==NULL)
- {
- AF&=0xff;
- return;
- }
- AF=(AF&0xff)|(getc(which)<<8);
- }
-
- home_dsk()
- {
- bioslog("home disk\n\r");
- trk = 0;
- }
-
- sec_trans()
- {
- bioslog("set trans to 0x%04x\n\r",BC);
- HL=BC;
- }
-
- sel_dsk()
- {
- if (disks[BC&0xf]==NULL)
- {
- HL=0;
- bioslog("Invalid disk select 0x%04x\n\r",BC);
- }
- else
- {
- HL=diskbufs[BC&0xf];
- dsk=BC&0xf;
- bioslog("Valid disk select [%x] 0x%4x\n\r",BC&0xf,HL);
- }
- }
-
- set_trk()
- {
- bioslog("set track to 0x%02x\n\r",BC&0xff);
- trk=BC&0xff;
- }
-
- set_sec()
- {
- bioslog("set sec to 0x%02x\n\r",BC&0xff);
- sec=BC&0xff;
- }
-
- set_dma()
- {
- bioslog("set dma to 0x%04x\n\r",BC);
- dma=BC;
- }
-
- read_dsk()
- {
- bioslog("Reading: track %d, sec %d, offset %d, dma 0x%4x\n\r",
- trk, sec, 128*((trk*0x40)+sec), dma);
- fseek(disks[dsk],128*((trk*0x40)+sec),0);
- AF=(AF&0xff)|((fread(real_z80_mem+dma,128,1,disks[dsk])!=1)<<8);
- }
-
- write_dsk()
- {
- bioslog("Writing: track %d, sec %d, offset %d, dma 0x%4x\n\r",
- trk, sec, 128*((trk*0x40)+sec), dma);
- fseek(disks[dsk],128*((trk*0x40)+sec),0);
- AF=(AF&0xff)|((fwrite(real_z80_mem+dma,128,1,disks[dsk])!=1)<<8);
- }
-