/*
 * Memory special file
 * minor device 0 is physical memory
 * minor device 1 is kernel memory
 * minor device 2 is EOF/BITBUCKET
 *
 * Block device stuff added
 */

/*** Rewritten for Interdata 7-8/32
 *** Code is made simpler (and less portable!) by the assumption
 *** that all physical memory is contiguous and directly addressable.
 ***/

#include "../h/local.h"

#ifdef  SCCS_ID
static char SCCS_ID [] = "@(#)mem.c    	5.1	 13:40:24 - 82/05/21 ";
#endif  SCCS_ID

#include "../h/param.h"
#include "../h/systm.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/buf.h"
#include "../h/conf.h"
#include "../h/seg.h"

/*
 * If you think some of these expressions look weird, remember
 * that memtop contains the last valid address. Thus,
 * addresses <= memtop are valid (as opposed to < memtop)
 */

mmread(dev)
dev_t dev;
{
	caddr_t addr  = u.u_offset;
	register c    = u.u_count;

	if(minor(dev) == 0 || minor(dev) == 1) {
	    if(addr <= memtop) {
		if(&addr[c] > memtop)
		    c = memtop - addr + 1;
		iomove (addr, c, B_READ);
	    } else
		u.u_error = ENODEV;
	} else if(minor(dev) == 2) {
	    ;
	} else
	    u.u_error = ENODEV;
}

mmwrite(dev)
dev_t dev;
{
	caddr_t  addr = u.u_offset;
	register c    = u.u_count;

	if(minor(dev) == 0 || minor(dev) == 1) {
	    if(addr <= memtop) {
		if(&addr[c] > memtop)
		    c = memtop - addr + 1;
		iomove(addr, c, B_WRITE);
	    } else
		u.u_error = ENODEV;
	} else if(minor(dev) == 2) {
		u.u_count = 0;
		u.u_base += c;
		u.u_offset += c;
		return;
	} else
	    u.u_error = ENODEV;
}

#ifdef  GWW_BD

struct buf   mmtab;                     /* Imagine, 'block memory' */

extern struct {
	int     mm_start;
	int     mm_blocks;
} mmmap[];
extern int mmndev;


mmstrategy(bp)
  struct buf    *bp;
{
    int         dev;

    dev = minor(bp->b_dev);

    if(bp->b_blkno < mmmap[dev].mm_blocks) {
	bp->b_un.b_addr =
	    (caddr_t) ((bp->b_blkno + mmmap[dev].mm_start) * PGSIZE);
	bp->b_resid = 0;
	iodone(bp);
    } else {
	bp->b_flags |= B_ERROR;
	bp->b_resid = bp->b_bcount;
	iodone(bp);
    }
}

mmopen(dev) {
}

mmclose(dev) {
}

#endif  GWW_BD
