// Micro-BOS interface
// translates bios calles into something more readable
// Version c
// 6 April 2009

// This should be used in conjunction with Micro-BOS Microcontroller
// Operating system

// www.byvac.co.uk

//-------------------------------------------------------------
// this is a convenient way to use the single point of entry
// using a static ram loaction. The base address
// is where the entry point is
int bios()
{
    int rv;
    
    func bios1=(func)(*adr2); 
    rv=bios1(&bs);
    errorn=bs.error;
    return rv;
}
// =========== BIOS Calls  =====================
//
//-------------------------------------------------------------
// resets the processor
void reset()
{
    bs.function=0;
    bios();
}
//-------------------------------------------------------------
// initialise processor
void initProc()
{
    bs.function=1;
    bios();
}
//-------------------------------------------------------------
// Opens UART either 1 or 2, the USB is connected to UART2
// Also set the baud rate with this
// mode is 3 bits:
// 2    1   0
// 0    0   0   = 8 bits no parity, 1 stop
// 0    1   0   = 8 bits even, 1 stop
// 1    0   0   = 8 bits odd, 1 stop
// 1    1   0   = 9 bits no parity, 1 stop
// <as above> 1 = 2 stop bits
void openIO(int port, int baudRate, unsigned int mode)
{
    bs.function=2;
    bs.i1=port;
    bs.i2=baudRate;
    bs.u1=mode;
    bios();
}
// ======== Cntrolled by setIO =================
//-------------------------------------------------------------
// outputs 1 character
void b_putc(int port, char c)
{
    bs.function=3;
    bs.i1=port;
    bs.c=c;
    bios();
}
//-------------------------------------------------------------
// Output string to terminal, returns # caracters o/p
int b_puts(int port,char *s)
{
    bs.function=4;
    bs.i1=port;
    bs.cp=s;
    return bios();
}
//-------------------------------------------------------------
// gets byte from console, i/o set by setCom
// returns with byte, set echo to 1 if required
int b_getc(int port,unsigned char echo)
{
    bs.function=5;
    bs.i1=port;
    bs.uc=echo;
    return bios();
}    
//-------------------------------------------------------------
// key query, checks for i/p from i/o, it available
// returns 1, else returns 0
int b_getcq(int port)
{
    bs.function=6;
    bs.i1=port;
    return bios();
}
//-------------------------------------------------------------
// hardware flow control 1 turns it on 0 turns it off
// at start up it is off.
int flowcontrol(int bon)
{
    bs.function=7;
    bs.i1=bon;
    bios();
}    
//-------------------------------------------------------------
// gets string from i/o, device set by setCom
// returns number of characters input
// *s gets filled with i/p, 0 terminated string
// max is max characters, if exceeded just ignores
// er is any error number - can chack for ^c with this
int b_gets(int port,char *s, int max)
{
    bs.function=8;
    bs.i1=port;
    bs.cp=s;
    bs.i2=max;
    return bios();
}
//-------------------------------------------------------------
// closes UART so that the pins can be used for other purposes.
void closeIO(int port)
{
    bs.function=9;
    bs.i1=port;
    bios();
}    
//-------------------------------------------------------------
// hex loader, loads a hex format (32 bit) to memory
// loads from UART or file determined by IO-byte
void hexLoader()
{
    bs.function=11;
    bios();
}    
//-------------------------------------------------------------
// xmodem(1k) loader, start. This sets the packet number to 1
// and initiates an xmodem transfer. This will not return until
// ASCII 'C' has been recieved
int xm_start()
{
    bs.function=12;
    return bios();
}    
//-------------------------------------------------------------
// xmodem(1k) loader, loads binary data from the uart in up to 1k
// byte blocks into the buffer supplied, must call xm_start first
// which will initialise the xmodem transfer and set packet to 1
// returns with the number of bytes loaded into buffer
int xm_load(char *buf)
{
    bs.function=13;
    bs.cp=buf;
    return bios();
}    
//-------------------------------------------------------------
// gets default port s set by bios, this refers to a UART and
// is used when accessing terminal i/o
int get_defp()
{
    bs.function=14;
    return bios();
}    
//-------------------------------------------------------------
// gets end of application, this is placed in the bios flash
// when the application is loaded
int get_eop()
{
    bs.function=15;
    return bios();
}    
//-------------------------------------------------------------
// system clock speed in Hz
int get_sysclock()
{
    bs.function=16;
    return bios();
}    
//-------------------------------------------------------------
// perif bus clock speed in Hz
int get_pbclock()
{
    bs.function=17;
    return bios();
}    
// ======= end of control by setIO ==============
//-------------------------------------------------------------
// erases flash pages. This is device specific
// for the PIC32 a page is 4096 bytes
void erasePages(unsigned address, unsigned pages)
{
    bs.function=20;
    bs.u1=address;
    bs.u2=pages;
    bios();
}
//-------------------------------------------------------------
// write one row to flash, a row is 512bytes on the PIC32
void programFlash(unsigned address, int size, char *data)
{
    bs.function=21;
    bs.u1=address;
    bs.i1=size;
    bs.cp=data;
    bios();
}
//-------------------------------------------------------------
// Sets, gets the value of the system timer register. One timer
// is dedicated for system use and is device specific
// value returned when set=0, value set when set <>0
// i.e. if you want to know the value make set=0 and value=0
// returns the value of the counter
int tick()
{
    bs.function=24;
    return bios();
}
//-------------------------------------------------------------
// blocking delay, halts processor for a number of milliseconds
void delayMS(unsigned ms)
{
    bs.function=26;
    bs.u1=ms;
    bios();
}
// ========= File functions DIRECT SD  ========================
// = = = = The following are for direct sector = = = = =
// = = = = read and write, ignor for proper    = = = = =
// = = = = file use                            = = = = =
// = The possible advantage is that the card does not need to have
// = afiling system present to use
//-------------------------------------------------------------
// initialise Media for raw read and write to sectors, this enables
// cards to be read and written without having any file system
// on them, return -1 on error
// is present
int initSDCARD(int card)
{
    bs.function=30;
    bs.i1=card;
    return bios();
}    
//-------------------------------------------------------------
// see if MMC inserted, card is 0 or 1, returns 1 if card
// is present
int getCD(int card)
{
    bs.function=32;
    bs.i1=card;
    return bios();
}    
//-------------------------------------------------------------
// read sector
// returns  0 on sucess
//          -1 on error
int readSector(int card, int sect, char *buf)
{
    bs.function=33;
    bs.i1=card;
    bs.u1=sect;
    bs.cp=buf;
    return bios();
}    
//-------------------------------------------------------------
// write sector
int writeSector(int card, int sect, char *buf)
{
    bs.function=34;
    bs.i1=card;
    bs.u1=sect;
    bs.cp=buf;
    return bios();
}    
//-------------------------------------------------------------
// returns file mode, which will be an integer representation of a
// character either 'x', 'r', 'w', 'a'
int fmode(int fn)
{
    bs.function=36;
    bs.fn=fn;
    return bios();
}    
//-------------------------------------------------------------
// formats SD card
// returns -1 on error
int ffd(int card)
{
    bs.function=37;
    bs.i1=card;
    return bios();
}    
//-------------------------------------------------------------
// file buffer, returns a pointer to the file buffer, can be used as
// a general putpose buffer or to work directly with the file
// returns -1 on error
int fbuf(int fn)
{
    bs.function=38;
    bs.fn=fn;
    return bios();
}    
// ========= File functions DOS  ==============================
// = = = = The following require a FAT16 file system to be present
// = on the card
//-------------------------------------------------------------
// returns the last file error, cluld aslo be end of file
int ferror()
{
    bs.function=42;
    return bios();
}
//-------------------------------------------------------------
// mount media
// returns -1 on fail, ferror contains error number
int mount(int card)
{
    bs.function=43;
    bs.i1=card;
    return bios();
}
//-------------------------------------------------------------
// unmount media
// returns 0 always and clears ferror
int unmount(int card)
{
    bs.function=44;
    bs.i1=card;
    return bios();
}
//-------------------------------------------------------------
// opens file for 'mode'
// where mode is r=read, a=append to existing file
// w=write, file is created first
// Card must be mounted before using, returns error (-1) otherwise
// returns with file number to use for file operations, file number is a
// number between 1 and 4, path names can be used, i.e. sub1\myfile.txt
int fileOpen(int card, char *name, char mode)
{
    bs.function=45;
    bs.i1=card;
    bs.cp=name;
    bs.c=mode;
    return bios();
}
//-------------------------------------------------------------
// closes file, important when writing to flush buffers
// but this also frees up a file buffer
// always returns 0 and clears ferror
int fileclose(int fn)
{
    bs.function=46;
    bs.fn=fn;
    return bios();
}
//-------------------------------------------------------------
// list current dir to default i/o in sorted order 
// device should be mounted before using this, borrows
// a free file so one should be available, return -1 on error so check
// the current directory is stored on the media structure
int dir(int card)
{
    bs.function=47;
    bs.i1=card;
    return bios();
}
//-------------------------------------------------------------
// changes the current directory and stores this on the media structure
// for subsiquent use, returns -1 on error
int cd(int card, char *dname)
{
    bs.function=48;
    bs.i1=card;
    bs.cp=dname;
    return bios();
}
//-------------------------------------------------------------
// makes a new directory within the current directory
// returns -1 on error
int md(int card, char *dname)
{
    bs.function=49;
    bs.i1=card;
    bs.cp=dname;
    return bios();
}
//-------------------------------------------------------------
// deletes a file or subdirectory, the sub must be empty to get
// deltetd
// returns -1 on error
int del(int card, char *dname)
{
    bs.function=50;
    bs.i1=card;
    bs.cp=dname;
    return bios();
}

//-------------------------------------------------------------
// puts character to file given in fcb 
// returns -1 on error
int b_fputc(int fn, char c)
{
    bs.function=51;
    bs.fn=fn;
    bs.c=c;
    return bios();
}
//-------------------------------------------------------------
// puts string to file given in fcb ** does not write the terminating 0
// returns -1 on error
int b_fputs(int fn, char *buf)
{
    bs.function=52;
    bs.fn=fn;
    bs.cp=buf;
    return bios();
}
//-------------------------------------------------------------
// gets character from file given in fcb
int b_fgetc(int fn)
{
    bs.function=53;
    bs.fn=fn;
    return bios();
}
//-------------------------------------------------------------
// gets string from file given in fcb, retunrs number of
// characters input
// return EOF (-2) or number of bytes read
int b_fgets(int fn, char *s, int max)
{
    bs.function=54;
    bs.fn=fn;
    bs.cp=s;
    bs.u1=max;
    return bios();
}

//-------------------------------------------------------------
// gets current postion of file pointer, this gets updated when
// reading and writing. 
int fpos(int fn)
{
    bs.function=55;
    bs.fn=fn;
    return bios();
}
//-------------------------------------------------------------
// reads a number of bytes to the supplied buffer starting at
// start for length number of bytes, returns the actual number
// of bytes read or -1, will not read past the end of file
int b_fread(int fn, char *buf, int start, int length)
{ 
    bs.function=56;
    bs.fn=fn;
    bs.cp=buf;
    bs.i1=start;
    bs.i2=length;
    return bios();
}
//-------------------------------------------------------------
// wtites data in buffer from start to length, will expand file to 
// accomodate data. If start is specified beyond the end of file then
// the space is padded with 0
// returns -1 on error
int b_fwrite(int fn, char *data, int start, int length)
{
    bs.function=57;
    bs.fn=fn;
    bs.cp=data;
    bs.i1=start;
    bs.i2=length;
    return bios();
}
//-------------------------------------------------------------
// check file exists
// SD card should be mounted before using this, check for error
// as it borrows a free file buffer. 
// Returns 0 on error or not found - check ferror
// 1 on found
int fileExists(int card, char *name)
{
    bs.function=58;
    bs.i1=card;
    bs.cp=name;
    return bios();
}
//-------------------------------------------------------------
// returns size of file
// clears ferror
int fileSize(int fn)
{
    bs.function=59;
    bs.fn=fn;
    return bios();
//    return bs.u1; // size
}
//================== date and time ================
//-------------------------------------------------------------
// start cloack
int startRTC()
{
    bs.function=60;
    return bios();
}
//-------------------------------------------------------------
// set time 
int setTime(int h, int m, unsigned s)
{
    bs.function=61;
    bs.i1=h;
    bs.i2=m;
    bs.u1=s;
    return bios();
}
//-------------------------------------------------------------
// set time 
int getTime(int *h, int *m, unsigned *s)
{
    int rv;
    
    bs.function=62;
    rv=bios();
    *h=bs.i1;
    *m=bs.i2;
    *s=bs.u1;
    return rv;
}
//-------------------------------------------------------------
// set date Full year should be entred i.e. 1988, internally
// stored as 2 digits so assumes anything > then 50 is +1900
int setDate(int wday, int mday, unsigned mon, unsigned year)
{
    bs.function=63;
    bs.i1=wday;
    bs.i2=mday;
    bs.u1=mon;
    bs.u2=year;
    return bios();
}
//-------------------------------------------------------------
// get date
int getDate(int *wday, int *mday, unsigned *mon, unsigned *year)
{
    int rv;
    
    bs.function=64;
    rv=bios();
    *wday=bs.i1;
    *mday=bs.i2;
    *mon=bs.u1;
    *year=bs.u2;
    return rv;
}

//-------------------------------------------------------------
// DOS line end fo CR+LF
void b_line_end(int port)
{
	b_putc(port,'\r'); // CR=0x0d
	b_putc(port,'\n'); // LF=0x0a
}	

