home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ARM Club 3
/
TheARMClub_PDCD3.iso
/
programs
/
emulaton
/
trash80
/
!Trash80
/
c
/
EmuDiskT
< prev
next >
Wrap
Text File
|
1992-10-15
|
4KB
|
252 lines
#include <stdio.h>
#include <string.h>
#include "bbc.h"
#include "general.h"
#include "Externals.h"
#define BITBUSY (1<<0)
#define BITDRQ (1<<1)
#define BITNOTREADY (1<<7)
#define RESTORE (0<<4)
#define SEEK (1<<4)
#define STEP (2<<4)
#define STEPu (3<<4)
#define STEPIN (4<<4)
#define STEPINu (5<<4)
#define STEPOUT (6<<4)
#define STEPOUTu (7<<4)
#define READ (8<<4)
#define READm (9<<4)
#define WRITE (10<<4)
#define WRITEm (11<<4)
#define FORCEINTERRUPT (13<<4)
FILE *diskfile= NULL;
u_char com;
BOOL busy= FALSE, crcerr= FALSE, recnfnd= FALSE, writeprot= FALSE, seekerror= FALSE;
BOOL drq;
BOOL direction= FALSE;
BOOL multisec= FALSE;
BOOL motorON= FALSE;
char track= 0;
u_char sector= 0;
u_char dr;
char realtrack;
u_char offset;
BOOL dwriteprot;
static void Pulse(BOOL direction)
{
int position;
realtrack+= direction ? 1 : -1;
if(realtrack < 35)
{
position= realtrack * 2560;
if(position < 0)
{
position= 0;
realtrack= 0;
}
if(diskfile) (void) fseek(diskfile,position,SEEK_SET);
}
}
static u_char lecture(char realtrack, u_char sector, int offset)
{
u_char vl;
long pos= (((long) realtrack * 10 + sector)<<8) + offset;
fseek(diskfile, pos, SEEK_SET);
fread(&vl, 1, 1, diskfile);
return(vl);
}
static void handleCMDT1(u_char v)
{
BOOL update, verify;
switch(v)
{
case STEPIN:
case STEPOUT:
direction= (v == STEPOUT);
case STEP:
update= (com & 0x10)!= 0;
if(update)
track+= direction ? 1 : -1;
if(!realtrack && !direction)
track= 0;
else Pulse(direction);
break;
case RESTORE:
track= 0xff;
dr= 0;
case SEEK:
while(track!= dr)
{
direction= (dr > track);
track+= direction ? 1 : -1;
if(!realtrack && !direction)
{
track= 0;
break;
}
Pulse(direction);
}
}
verify= (com & 0x04)!= 0;
if(verify)
if(!motorON || (realtrack!= track))
seekerror= TRUE;
busy= FALSE;
}
static void handleCMDT2(u_char v)
{
if((v == WRITE) && dwriteprot)
{
writeprot= TRUE;
return;
}
if((!motorON) || (realtrack!= track) || (sector > 9))
{
recnfnd= TRUE;
return;
}
busy= TRUE;
offset= 0;
multisec= (com & 0x10)!= 0;
if(v == READ)
dr= lecture(realtrack,sector,offset);
drq= TRUE;
}
static void handleCMDT4(u_char v)
{
}
void HandleCMD(u_char command)
{
u_char v= command & 0xf0;
if((v != FORCEINTERRUPT) && busy) return;
com= command;
switch(v)
{
case RESTORE:
case SEEK:
case STEP:
case STEPu:
case STEPIN:
case STEPINu:
case STEPOUT:
case STEPOUTu:
busy= FALSE;
crcerr= seekerror= FALSE;
drq= FALSE;
handleCMDT1(v & 0xe0);
break;
case READ:
case READm:
case WRITE:
case WRITEm:
busy= FALSE;
crcerr= recnfnd= FALSE;
drq= FALSE;
handleCMDT2(v & 0xe0);
break;
case FORCEINTERRUPT:
busy= FALSE;
drq= FALSE;
handleCMDT4(v);
}
}
static void ecriture(char realtrack, u_char sector, int offset, u_char vl)
{
u_char *pvl;
*pvl= vl;
fseek(diskfile, (((long) realtrack * 10 + sector)<<8) + offset, SEEK_SET);
fwrite(pvl, 1, 1, diskfile);
}
static void EcrDR(u_char vl)
{
if((com & 0xe0)!= WRITE || !drq || !motorON) return;
ecriture(realtrack,sector,offset,vl);
if(!(offset= ++offset & 0xff))
{
if(multisec)
{
if(++sector > 9)
{
recnfnd= TRUE;
busy= drq= FALSE;
}
}
else busy= drq= FALSE;
}
}
static u_char LecDR(void)
{
u_char tampon;
if((com & 0xe0)!= READ || !drq || !motorON) return(dr);
tampon= dr;
if(!(offset= ++offset & 0xff))
if(multisec)
{
if(++sector > 9)
{
recnfnd= TRUE;
busy= drq= FALSE;
}
else dr= lecture(realtrack, sector, offset);
}
else busy= drq= FALSE;
else dr= lecture(realtrack, sector, offset);
return(tampon);
}
void WrDisk(u_char lad, u_char vx)
{
switch(lad)
{
case 0xe0:
case 0xe1:
motorON= (vx == 1);
break;
case 0xec:
HandleCMD(vx);
break;
case 0xed:
track= (char) vx;
break;
case 0xee:
sector= vx;
break;
case 0xef:
EcrDR(vx);
break;
}
}
u_char RdDisk(u_int ax)
{
switch(ax & 0xff)
{
case 0xec:
return(busy | (drq<<1) | (seekerror<<2) | (writeprot<<6));
case 0xed: /* Track register */
return(track);
case 0xee: /* Sector register */
return(sector);
case 0xef: /* Data register */
return(LecDR());
}
return(0);
}