home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / disks / disk400.lzh / SetCPU / expdev.c < prev    next >
C/C++ Source or Header  |  1990-11-03  |  6KB  |  200 lines

  1. /*
  2.     SetCPU V1.60
  3.     by Dave Haynie, April 13, 1990
  4.     Released to the Public Domain
  5.  
  6.     EXPANSION DEVICE MODULE
  7.     
  8.     This module maintains the code used to detect and translate
  9.     a given expansion device.
  10. */
  11.  
  12. #include "setcpu.h"
  13.  
  14. /* ====================================================================== */
  15.  
  16. /* Stuff I need for this module. */
  17.  
  18. char *malloc();
  19. int sscanf();
  20.  
  21. /* ====================================================================== */
  22.  
  23. /* This section manages devices with on-board ROM.  The actual 
  24.    implementation of this stuff is pretty well hidden in this
  25.    module. */
  26.    
  27. /* This structure manages the expansion devices that we know about. */
  28.  
  29. struct ExpDev {
  30.    struct Node node;
  31.    ULONG manuf;
  32.    ULONG board;
  33.    ULONG size;
  34.    ULONG romoffset;
  35.    ULONG romsize;
  36. };
  37.    
  38. /* Here's the list of all the devices we know about. */
  39.  
  40. static struct List Devices = 
  41.    {(struct Node *)&Devices.lh_Tail,NULL,(struct Node *)&Devices.lh_Head,0,0};
  42.  
  43. static struct ExpDev *CurrentDevice = NULL;
  44.  
  45. /* This function reads the list of expansion devices from the given file.
  46.    The file should contain data for one device per line, with the 
  47.    following format:
  48.    
  49.        MANUF    PROD    SIZE    START    LENGTH    id-string
  50.        
  51.    Except for the last field, all numbers are integers, which may be 
  52.    expressed as decimal or hexidecimal.  The last field is a text
  53.    string which may contain any information.  It's very likely that
  54.    the line for each device will have to be supplied by the maker
  55.    of any device, since there's no way to figure out if a device's
  56.    ROM is on the same MMU page as an important I/O register which
  57.    shouldn't ever be translated.  The description I use for the Amiga
  58.    2090A controller is:
  59.    
  60.       0x202 0x01 0x10000 0x8000 0x4000 CBM 2090A Disk Controller
  61.  
  62.    The actual fields are:
  63.    
  64.     MANUF        The Manufacturer's code for the PIC
  65.     PROD        The Product code for the PIC
  66.     SIZE        The configured size of the PIC
  67.     START        The offset from the PIC base for the start of ROM
  68.     LENGTH        The length of the ROM    
  69.     id-string    Whatever the hell you want
  70. */
  71.  
  72. LONG ReadExpDevs(name)
  73. char *name;
  74. {
  75.    FILE *file;
  76.    char buf[256],msg[256];
  77.    struct ExpDev *ed;
  78.    int len,i;
  79.    
  80.    if (!(file = fopen(name,"r"))) return FALSE;
  81.    
  82.    while (fgets(buf,256,file)) {
  83.       ed = (struct ExpDev *)malloc(sizeof(struct ExpDev));
  84.       if (sscanf(buf,"%lx%lx%lx%lx%lx%s",&ed->manuf,&ed->board,&ed->size,
  85.                  &ed->romoffset,&ed->romsize,msg) >= 5) {
  86.          if (len = strlen(msg)) {
  87.             ed->node.ln_Name = (char *)malloc(len+1);
  88.             for (i = 0; i <= len; ++i)
  89.                ed->node.ln_Name[i] = (msg[i] == '_')?' ':msg[i];
  90.          }
  91.          if (ed->romsize = ((ed->romsize/DEVROUND)*DEVROUND))
  92.             AddHead(&Devices,(struct Node *)ed);
  93.          else
  94.             free(ed);
  95.       } else
  96.          free(ed);
  97.    }
  98.    fclose(file);
  99.    CurrentDevice = (struct ExpDev *)Devices.lh_Head;
  100.    return TRUE;
  101. }
  102.  
  103. /* ====================================================================== */
  104.  
  105. /* This function returns the ROM information I'll need for a given 
  106.    expansion device.  Because of some Commodore screwups, the A2090A
  107.    appears the same device as other boards like the Commodore RAM
  108.    board.  So I have the size passed as well, as a consistency 
  109.    check.  The returned ExpROMData structure is allocated here, and
  110.    can be freed when no longer needed. */
  111.     
  112. struct ExpROMData *GetExpROM() 
  113. {
  114.    struct ConfigDev *cd;
  115.    struct DiagArea *da;   
  116.    struct ExpROMData *ed;
  117.    
  118.    if (!CurrentDevice || !ExpansionBase) return NULL;
  119.    cd = FindConfigDev(NULL,CurrentDevice->manuf,CurrentDevice->board);
  120.  
  121.    while (cd) {
  122.       if (((ULONG)cd->cd_BoardSize == CurrentDevice->size) && 
  123.           (cd->cd_Rom.er_Type & ERTF_DIAGVALID)) {
  124.          da = (struct DiagArea *)(((ULONG)cd->cd_BoardAddr)+((ULONG)cd->cd_Rom.er_InitDiagVec));
  125.  
  126.         /* This is just a sanity check to make sure we really use the
  127.            ROM out on this card -- a nybble or byte wide ROM will be in
  128.            RAM already. */
  129.          if ((da->da_Config & DAC_BUSWIDTH) == DAC_WORDWIDE)  {
  130.             ed = (struct ExpROMData *)AllocMem(SizeOf(struct ExpROMData),MEMF_CLEAR);
  131.             ed->ROMbase = ((ULONG)cd->cd_BoardAddr) + CurrentDevice->romoffset;
  132.             ed->ROMsize = CurrentDevice->romsize;
  133.             ed->imagebase = NULL;
  134.             ed->tablebase = NULL;
  135.             ed->name = (char *)AllocMem((ULONG)
  136.                                strlen(CurrentDevice->node.ln_Name)+1,0L);
  137.             strcpy(ed->name,CurrentDevice->node.ln_Name);
  138.             ++CurrentDevice;
  139.             return ed;
  140.          }
  141.       }
  142.       cd = FindConfigDev(cd,CurrentDevice->manuf,CurrentDevice->board); 
  143.    }
  144.    CurrentDevice = (struct ExpDev *)CurrentDevice->node.ln_Succ;
  145.    return NULL;
  146. }
  147.  
  148. /* This function removes a CardROMFile generated I/O ROM table list. */
  149.  
  150. void FreeExpROM(emem)
  151. struct ExpROMData *emem;
  152. {
  153.    struct ExpROMData *edel;
  154.  
  155.    while (emem) {
  156.       edel = emem;
  157.       emem = emem->next;
  158.       FreeMem(edel->imagebase,edel->ROMsize);
  159.       FreeMem(edel->name,(ULONG)strlen(edel->name)+1);
  160.       FreeMem(edel,SizeOf(struct ExpROMData));
  161.    }
  162. }
  163.  
  164. /* ====================================================================== */
  165.  
  166. /* This routine is called to configure the system devices without calling any
  167.    ROM routines that could possibly goober up on older OS releases.  Other
  168.    than skipping ROMs, this should do the same thing as the ConfigChain()
  169.    function in expansion.library. */
  170.    
  171. void SafeConfigDevs()
  172. {
  173.    struct ConfigDev *cd;
  174.    char *base = (char *)0xe80000;
  175.  
  176.    if (!ExpansionBase) return;
  177.  
  178.    /* Should also loop only as long as 
  179.          !(ExpansionBase->eb_Flags & EBB_CLOGGED), 
  180.       but I don't know what EBB_CLOGGED is yet.. */
  181.  
  182.    while (cd = AllocConfigDev()) {
  183.       if (ReadExpansionRom(base,cd)) {
  184.          FreeConfigDev(cd); 
  185.          break;
  186.       }
  187.  
  188.      /* Got it, let's get rid of any ROM critters. */
  189.       cd->cd_Rom.er_Type &= ~ERTF_DIAGVALID;
  190.  
  191.     /* Now adding the board should be safe! */
  192.       if (ConfigBoard(base,cd)) {
  193.          FreeConfigDev(cd);
  194.          break;
  195.       }
  196.       AddConfigDev(cd);
  197.    }
  198. }
  199.  
  200.