home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume15 / upm / part01 / bios.c next >
C/C++ Source or Header  |  1990-12-17  |  6KB  |  324 lines

  1. /*
  2.  
  3. bios.c - CP/M BIOS in C
  4.  
  5. (C) MCMXM - Nick Sayer - All rights reserved.
  6.  
  7. See COPYRIGHT file for more details.
  8.  
  9. */
  10.  
  11. #include <stdio.h>
  12. #include "z80.h"
  13. #include "upm.h"
  14.  
  15. #include <sys/ioctl.h>
  16.  
  17. #define IO_BYTE 3
  18.  
  19. WORD trk,sec,dma,dsk;
  20.  
  21. char cold_flag=0;
  22.  
  23. /*
  24.  
  25. Our Z-80 BIOS is just HALT, RET, NOP, HALT, RET, NOP..... We find out
  26. which BIOS jump it is by dividing the LSB of PC by 3.
  27.  
  28. THIS PRESUMES BIOS BEGINS ON AN EVEN PAGE BOUNDARY. This is a pretty
  29. good assumption.
  30.  
  31. BIOS Memory map:
  32.  
  33. 0000 -     jump table
  34. 0080 -     DIRBUF
  35. 0100 -     disk buffers - this set up in upm.c
  36.  
  37. It is up to upm.c to set up the disk buffers as necessary for
  38. different size devices, and set up the pointers in diskbufs[].
  39.  
  40. */
  41.  
  42. char bios()
  43. {
  44.   register char bios_call;
  45.  
  46.   bios_call=(PC&0xff)/3;
  47.   PC++; /* Skip past the HALT */
  48.  
  49. if(debugflag) printf("\tBios! - %d from %x\n\r",bios_call,PC);
  50.  
  51.   switch(bios_call)
  52.   {
  53.     case 0:cold_boot(); /* DON'T break... we WANT to fall into warm boot! */
  54.     case 1:warm_boot();
  55.     break;
  56.     case 2:stat_con();
  57.     break;
  58.     case 3:read_con();
  59.     break;
  60.     case 4:write_con();
  61.     break;
  62.     case 5:write_lst();
  63.     break;
  64.     case 6:write_pun();
  65.     break;
  66.     case 7:read_rdr();
  67.     break;
  68.     case 8:home_dsk();
  69.     break;
  70.     case 9:sel_dsk();
  71.     break;
  72.     case 10:set_trk();
  73.     break;
  74.     case 11:set_sec();
  75.     break;
  76.     case 12:set_dma();
  77.     break;
  78.     case 13:read_dsk();
  79.     break;
  80.     case 14:write_dsk();
  81.     break;
  82.     case 15:stat_lst();
  83.     break;
  84.     case 16:sec_trans();
  85.     break;
  86.     case 30:shell_escape();
  87.     break;
  88.     case 31:quit(); return 1;
  89.     default:
  90.     printf("unhandled bios call %d\n\r",bios_call);
  91.     debugit();
  92.   }
  93.  
  94.   return 0;
  95. }
  96.  
  97. quit()
  98. {
  99. }
  100.  
  101. shell_escape()
  102. {
  103.     debugit();
  104. }
  105.  
  106. cold_boot()
  107. {
  108.  
  109.   real_z80_mem[IO_BYTE]=0x95; /* CRT, PUN, RDR, LPT */
  110.   real_z80_mem[0]=0xC3;
  111.   real_z80_mem[1]=0x03;
  112.   real_z80_mem[2]=(ccp_start>>8)+8+0xe; /* First page of BIOS */
  113.   real_z80_mem[5]=0xC3;
  114.   real_z80_mem[6]=0x06;
  115.   real_z80_mem[7]=(ccp_start>>8)+8; /* First page of BDOS */
  116.   printf("\n\r\n\rCP/M Ver 2.2\n\rCopyright Digital Research, Inc.\n\r");
  117.   printf("UP/M Version 1.0B\n\rCopyright Nick Sayer\n\r\n\r");
  118.   cold_flag++;
  119.  
  120. }
  121.  
  122. warm_boot()
  123. {
  124.   register WORD i;
  125.  
  126.   for(i=0;i<SIZE_CCP_IMAGE;i++)
  127.     real_z80_mem[i+ccp_start]=ccp_image[i];
  128.  
  129.   if (cold_flag)
  130.   {
  131.     cold_flag=0;
  132.     PC=ccp_start;
  133.   }
  134.   else
  135.     PC=ccp_start+3;
  136.  
  137.   BC=0;
  138.   debugit();
  139. }
  140.  
  141. stat_con()
  142. {
  143.   FILE *which;
  144.   int ret;
  145.  
  146.   switch (real_z80_mem[IO_BYTE]&0x3)
  147.   {
  148.     case 0:which=devices[F_TY]; break;
  149.     case 1:which=stdin; break;
  150.     case 2:which=stdin; break;
  151.     case 3:which=devices[F_U1]; break;
  152.   }
  153.  
  154.   ioctl(fileno(which),FIONREAD,&ret);
  155.   AF=(AF&0xff)|(ret?0xff00:0);
  156. /* */
  157. /*  if(!ret) AF |= FLAG_Z; else AF &= ~FLAG_Z; */
  158.   AF |= FLAG_Z;
  159.  
  160. }
  161.  
  162. read_con()
  163. {
  164.   FILE *which;
  165.  
  166.   switch (real_z80_mem[IO_BYTE]&0x3)
  167.   {
  168.     case 0:which=devices[F_TY]; break;
  169.     case 1:which=stdin; break;
  170.     case 2:which=stdin; break;
  171.     case 3:which=devices[F_U1]; break;
  172.   }
  173.   if (which==NULL)
  174.   {
  175.     AF&=0xff;
  176.     return;
  177.   }
  178.   AF=(AF&0xff)|(getc(which)<<8);
  179. }
  180.  
  181. write_con()
  182. {
  183.   FILE *which;
  184.  
  185.   switch(real_z80_mem[IO_BYTE]&0x3)
  186.   {
  187.     case 0:which=devices[F_TY]; break;
  188.     case 1:which=stdout; break;
  189.     case 2:write_lst(); which=stdout; break;
  190.     case 3:which=devices[F_U1]; break;
  191.   }
  192.   if (which!=NULL)
  193.     putc(BC&0xff,which);
  194. }
  195.  
  196. stat_lst()
  197. {
  198.   FILE *which;
  199.  
  200. /*
  201.   switch((real_z80_mem[IO_BYTE]>>6)&0x3)
  202.   {
  203.     case 0:which=devices[F_TY]; break;
  204.     case 1:which=stdout; break;
  205.     case 2:which=devices[F_LP]; break;
  206.     case 3:which=devices[F_U1]; break;
  207.   }
  208.  
  209. Under unix, writing is always fine.
  210.  
  211. */
  212.   AF|=0xff00;
  213. }
  214.  
  215. write_lst()
  216. {
  217.   FILE *which;
  218.  
  219.   switch((real_z80_mem[IO_BYTE]>>6)&0x3)
  220.   {
  221.     case 0:which=devices[F_TY]; break;
  222.     case 1:which=stdout; break;
  223.     case 2:which=devices[F_LP]; break;
  224.     case 3:which=devices[F_U1]; break;
  225.   }
  226.   if (which!=NULL)
  227.     putc(BC&0xff,which);
  228. }
  229.  
  230. write_pun()
  231. {
  232.   FILE *which;
  233.  
  234.   switch((real_z80_mem[IO_BYTE]>>4)&0x3)
  235.   {
  236.     case 0:which=devices[F_TY]; break;
  237.     case 1:which=devices[F_PT]; break;
  238.     case 2:which=devices[F_U1]; break;
  239.     case 3:which=devices[F_U2]; break;
  240.   }
  241.   if (which!=NULL)
  242.     putc(BC&0xff,which);
  243. }
  244.  
  245. read_rdr()
  246. {
  247.   FILE *which;
  248.  
  249.   switch((real_z80_mem[IO_BYTE]>>2)&0x3)
  250.   {
  251.     case 0:which=devices[F_TY]; break;
  252.     case 1:which=devices[F_PT]; break;
  253.     case 2:which=devices[F_U1]; break;
  254.     case 3:which=devices[F_U2]; break;
  255.   }
  256.   if (which==NULL)
  257.   {
  258.     AF&=0xff;
  259.     return;
  260.   }
  261.   AF=(AF&0xff)|(getc(which)<<8);
  262. }
  263.  
  264. home_dsk()
  265. {
  266.   bioslog("home disk\n\r");
  267.   trk = 0;
  268. }
  269.  
  270. sec_trans()
  271. {
  272.   bioslog("set trans to 0x%04x\n\r",BC);
  273.   HL=BC;
  274. }
  275.  
  276. sel_dsk()
  277. {
  278.   if (disks[BC&0xf]==NULL)
  279.   {
  280.     HL=0;
  281.     bioslog("Invalid disk select 0x%04x\n\r",BC);
  282.   }
  283.   else
  284.   {
  285.     HL=diskbufs[BC&0xf];
  286.     dsk=BC&0xf;
  287.     bioslog("Valid disk select [%x] 0x%4x\n\r",BC&0xf,HL);
  288.   }
  289. }
  290.  
  291. set_trk()
  292. {
  293.   bioslog("set track to 0x%02x\n\r",BC&0xff);
  294.   trk=BC&0xff;
  295. }
  296.  
  297. set_sec()
  298. {
  299.   bioslog("set sec to 0x%02x\n\r",BC&0xff);
  300.   sec=BC&0xff;
  301. }
  302.  
  303. set_dma()
  304. {
  305.   bioslog("set dma to 0x%04x\n\r",BC);
  306.   dma=BC;
  307. }
  308.  
  309. read_dsk()
  310. {
  311.   bioslog("Reading: track %d, sec %d, offset %d, dma 0x%4x\n\r",
  312.      trk, sec, 128*((trk*0x40)+sec), dma);
  313.   fseek(disks[dsk],128*((trk*0x40)+sec),0);
  314.   AF=(AF&0xff)|((fread(real_z80_mem+dma,128,1,disks[dsk])!=1)<<8);
  315. }
  316.  
  317. write_dsk()
  318. {
  319.   bioslog("Writing: track %d, sec %d, offset %d, dma 0x%4x\n\r",
  320.      trk, sec, 128*((trk*0x40)+sec), dma);
  321.   fseek(disks[dsk],128*((trk*0x40)+sec),0);
  322.   AF=(AF&0xff)|((fwrite(real_z80_mem+dma,128,1,disks[dsk])!=1)<<8);
  323. }
  324.