mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
Upload
Digital Research
This commit is contained in:
1342
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/bios.c
Normal file
1342
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/bios.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
$ set nover
|
||||
$ set noon
|
||||
$ set def c:[cpm68k.source.bios]
|
||||
$ copy normbios.h biostype.h
|
||||
$ num
|
||||
bios.c
|
||||
bios.num
|
||||
$ cc68 bios
|
||||
$ as68 -u -l -p biosa.s >biosa.lis
|
||||
$ lo68 -r -t5000 -o bios.68k biosa.o bios.o
|
||||
$ pr/nofeed bios.num,bios.lis,biosa.lis
|
1945
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/bios.s
Normal file
1945
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/bios.s
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,15 @@
|
||||
$ set nover
|
||||
$ set noon
|
||||
$ set def [bill.cpm68k.bios]
|
||||
$ num
|
||||
bios.c
|
||||
bios.num
|
||||
$ cc68 :== @cc68.com
|
||||
$ as68 :== $bin:as68.exe
|
||||
$ ld68 :== $bin:lo68.exe
|
||||
$ cc68 bios
|
||||
$ as68 -u -l -p biosa.s >biosa.lis
|
||||
$ as68 -u -l -p ldbiosa.s >ldbiosa.lis
|
||||
$ ld68 -r -t5000 -o bios.68k biosa.o bios.o
|
||||
$ s68 - bios.68k >[bill.cpm68k.object]bios.sr
|
||||
$ pr/nofeed/copies=7 bios.num,biosa.lis,ldbiosa.lis
|
50
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/biosa.s
Normal file
50
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/biosa.s
Normal file
@@ -0,0 +1,50 @@
|
||||
.text
|
||||
.globl _init
|
||||
.globl _biosinit
|
||||
.globl _flush
|
||||
.globl _wboot
|
||||
.globl _cbios
|
||||
.globl _dskia
|
||||
.globl _dskic
|
||||
.globl _setimask
|
||||
.globl _ccp
|
||||
*
|
||||
*
|
||||
_init: lea entry,a0
|
||||
move.l a0,$8C
|
||||
lea _dskia,a0
|
||||
move.l a0,$3fc
|
||||
move #$2000,sr
|
||||
jsr _biosinit
|
||||
clr.l d0
|
||||
rts
|
||||
*
|
||||
_wboot: clr.l d0
|
||||
jmp _ccp
|
||||
*
|
||||
entry: move.l d2,-(a7)
|
||||
move.l d1,-(a7)
|
||||
move.w d0,-(a7)
|
||||
jsr _cbios
|
||||
add #10,a7
|
||||
rte
|
||||
*
|
||||
_dskia: link a6,#0
|
||||
movem.l d0-d7/a0-a5,-(a7)
|
||||
jsr _dskic
|
||||
movem.l (a7)+,d0-d7/a0-a5
|
||||
unlk a6
|
||||
rte
|
||||
*
|
||||
_setimask: move sr,d0
|
||||
lsr #8,d0
|
||||
and.l #7,d0
|
||||
move sr,d1
|
||||
ror.w #8,d1
|
||||
and.w #$fff8,d1
|
||||
add.w 4(a7),d1
|
||||
ror.w #8,d1
|
||||
move d1,sr
|
||||
rts
|
||||
*
|
||||
.end
|
@@ -0,0 +1,3 @@
|
||||
#define LOADER 0
|
||||
#define CTLTYPE 0
|
||||
#define MEMDSK 4
|
@@ -0,0 +1,23 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Portable type definitions for use */
|
||||
/* with the C BIOS according to */
|
||||
/* CP/M-68K (tm) standard usage. */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
#define LONG long
|
||||
#define ULONG unsigned long
|
||||
#define WORD short int
|
||||
#define UWORD unsigned short
|
||||
#define BYTE char
|
||||
#define UBYTE unsigned char
|
||||
#define VOID
|
||||
|
||||
#define REG register
|
||||
#define LOCAL auto
|
||||
#define MLOCAL static
|
||||
#define GLOBAL extern
|
||||
#define EXTERN extern
|
||||
|
||||
/************************************************/
|
@@ -0,0 +1,12 @@
|
||||
$ set nover
|
||||
$ set noon
|
||||
$ c68 :== $bin:c68.exe
|
||||
$ c068 :== $bin:c068.exe
|
||||
$ c168 :== $bin:c168.exe
|
||||
$ as68 :== $bin:as68.exe
|
||||
$ lo68 :== $bin:lo68.exe
|
||||
$ c68 'p1'.c 'p1'.i
|
||||
$ c068 'p1'.i 'p1'.ic 'p1'.st
|
||||
$ c168 'p1'.ic 'p1'.s -LD
|
||||
$ as68 -l -u -p 'p1'.s >'p1'.lis
|
||||
$ delete 'p1'.s;*,'p1'.ic;*,'p1'.i;*,'p1'.st;*
|
@@ -0,0 +1,12 @@
|
||||
$ set nover
|
||||
$ set noon
|
||||
$ c68 :== $bin:c68.exe
|
||||
$ c068 :== $bin:c068.exe
|
||||
$ c168 :== $bin:c168.exe
|
||||
$ as68 :== $bin:as68.exe
|
||||
$ lo68 :== $bin:lo68.exe
|
||||
$ c68 'p1'.c 'p1'.i
|
||||
$ c068 'p1'.i 'p1'.ic 'p1'.st
|
||||
$ c168 'p1'.ic 'p1'.s -LD
|
||||
$ as68 -l -u -p 'p1'.s >'p1'.lis
|
||||
$ delete 'p1'.s;*,'p1'.ic;*,'p1'.i;*,'p1'.st;*
|
641
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/chbios.c
Normal file
641
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/chbios.c
Normal file
@@ -0,0 +1,641 @@
|
||||
/*=======================================================================*/
|
||||
/*/---------------------------------------------------------------------\*/
|
||||
/*| |*/
|
||||
/*| CP/M-68K(tm) BIOS for the EXORMACS |*/
|
||||
/*| |*/
|
||||
/*| Copyright 1982, Digital Research. |*/
|
||||
/*| |*/
|
||||
/*\---------------------------------------------------------------------/*/
|
||||
/*=======================================================================*/
|
||||
|
||||
|
||||
|
||||
char copyright[] = "Copyright 1982, Digital Research";
|
||||
|
||||
struct memb { char byte; };
|
||||
struct memw { int word; };
|
||||
struct meml { long lword;};
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* I/O Device Definitions */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Define the two ACIA ports on the Debug board */
|
||||
/************************************************************************/
|
||||
|
||||
#define PORT1 0xFFEE011
|
||||
#define PORT2 0xFFEE015
|
||||
|
||||
#define PORTCTRL 0
|
||||
#define PORTSTAT 0
|
||||
#define PORTRDR 2
|
||||
#define PORTTDR 2
|
||||
|
||||
#define PORTRSET 3
|
||||
#define PORTINIT 0x11
|
||||
|
||||
#define PORTRDRF 1
|
||||
#define PORTTDRE 2
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Define Disk I/O Addresses and Related Constants */
|
||||
/************************************************************************/
|
||||
|
||||
#define DSKIPC 0xFF0000 /* IPC Base Address */
|
||||
|
||||
#define DSKINTV 0x3FC /* Address of Disk Interrupt Vector */
|
||||
|
||||
#define INTTOIPC 0xD /* offsets */
|
||||
#define RSTTOIPC 0xF
|
||||
#define MSGTOIPC 0x101
|
||||
#define ACKFMIPC 0x103
|
||||
#define PKTTOIPC 0x105
|
||||
#define MSGFMIPC 0x181
|
||||
#define ACKTOIPC 0x183
|
||||
#define PKTFMIPC 0x185
|
||||
|
||||
#define STX 0x02
|
||||
#define ETX 0x03
|
||||
#define ACK 0x06
|
||||
#define NAK 0x15
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* BIOS Table Definitions */
|
||||
/************************************************************************/
|
||||
|
||||
struct dpb
|
||||
{
|
||||
int spt;
|
||||
char bsh;
|
||||
char blm;
|
||||
char exm;
|
||||
char dpbjunk;
|
||||
int dsm;
|
||||
int drm;
|
||||
char al0;
|
||||
char al1;
|
||||
int cks;
|
||||
int off;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct dph
|
||||
{
|
||||
char *xltp;
|
||||
int dphscr[3];
|
||||
char *dirbufp;
|
||||
struct dpb *dpbp;
|
||||
char *csvp;
|
||||
char *alvp;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Directory Buffer for use by the BDOS */
|
||||
/************************************************************************/
|
||||
|
||||
char dirbuf[128];
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* CSV's */
|
||||
/************************************************************************/
|
||||
|
||||
char csv0[16];
|
||||
char csv1[16];
|
||||
char csv2[16];
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* ALV's */
|
||||
/************************************************************************/
|
||||
|
||||
char alv0[32]; /* (dsm0 / 8) + 1 */
|
||||
char alv1[32]; /* (dsm1 / 8) + 1 */
|
||||
char alv2[2002]; /* (dsm2 / 8) + 1 */
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Disk Parameter Blocks */
|
||||
/************************************************************************/
|
||||
|
||||
/* The following dpb definitions express the intent of the writer, */
|
||||
/* unfortunately, due to a compiler bug, these lines cannot be used. */
|
||||
/* Therefore, the obscure code following them has been inserted. */
|
||||
|
||||
/************* spt, bsh, blm, exm, jnk, dsm, drm, al0, al1, cks, off
|
||||
|
||||
struct dpb dpb0={ 26, 3, 7, 0, 0, 242, 63, 0xC0, 0, 16, 2};
|
||||
struct dpb dpb1={ 26, 4, 15, 0, 0, 242, 63, 0xC0, 0, 16, 2};
|
||||
struct dpb dpb2={ 26, 3, 7, 0, 0, 16008, 63, 0xC0, 0, 16, 2};
|
||||
|
||||
********** end of readable definitions *************/
|
||||
|
||||
/* The Alcyon C compiler assumes all structures are arrays of int, so */
|
||||
/* in the following definitions, adjacent pairs of chars have been */
|
||||
/* combined into int constants --- what a kludge! **********************/
|
||||
|
||||
struct dpb dpb0 = { 26, 1799, 0, 242, 63, -16384, 16, 2 };
|
||||
struct dpb dpb1 = { 26, 1039, 0, 242, 63, -16384, 16, 2 };
|
||||
struct dpb dpb2 = { 26, 1799, 0, 16008, 63, -16384, 16, 2 };
|
||||
|
||||
/*************** End of kludge *****************/
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Sector Translate Table */
|
||||
/************************************************************************/
|
||||
|
||||
char xlt[26] = { 1, 7, 13, 19, 25, 5, 11, 17, 23, 3, 9, 15, 21,
|
||||
2, 8, 14, 20, 26, 6, 12, 18, 24, 4, 10, 16, 22 };
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Disk Parameter Headers */
|
||||
/* */
|
||||
/* Four disks are defined : dsk a: diskno=0, dev name=#fd04 */
|
||||
/* dsk b: diskno=1, dev name=#fd05 */
|
||||
/* dsk c: diskno=2, dev name=#hd00 */
|
||||
/* dsk d: diskno=3, dev name=#hd01 */
|
||||
/************************************************************************/
|
||||
|
||||
struct dph dphtab[4] =
|
||||
{ {&xlt, 0, 0, 0, &dirbuf, &dpb0, &csv0, &alv0}, /*dsk a*/
|
||||
{&xlt, 0, 0, 0, &dirbuf, &dpb0, &csv1, &alv1}, /*dsk b*/
|
||||
{ 0L, 0, 0, 0, &dirbuf, &dpb2, &csv2, &alv2}, /*dsk c*/
|
||||
{ 0L, 0, 0, 0, &dirbuf, &dpb2, &csv2, &alv2}, /*dsk d*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Memory Region Table */
|
||||
/************************************************************************/
|
||||
|
||||
struct mrt { int count;
|
||||
long tpalow;
|
||||
long tpalen;
|
||||
}
|
||||
memtab = { 1, 0x400L, 0xFC00 };
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* IOBYTE */
|
||||
/************************************************************************/
|
||||
|
||||
int iobyte;
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Currently Selected Disk Stuff */
|
||||
/************************************************************************/
|
||||
|
||||
int settrk, setsec, setdsk;
|
||||
char *setdma;
|
||||
|
||||
|
||||
char trkbuf[26 * 128];
|
||||
int tbvalid = 0;
|
||||
int tbdirty = 0;
|
||||
int tbtrk;
|
||||
int tbdsk;
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Disk I/O Packets for the UDC and other Disk I/O Variables */
|
||||
/************************************************************************/
|
||||
|
||||
struct hmpkst {
|
||||
char a1;
|
||||
char a2;
|
||||
char a3;
|
||||
char dskno;
|
||||
char com1;
|
||||
char com2;
|
||||
char a6;
|
||||
char a7;
|
||||
}
|
||||
hmpack = { 512, 1792, 0, 768 }; /* kludge init by words */
|
||||
|
||||
|
||||
struct rwpkst {
|
||||
char stxchr;
|
||||
char pktid;
|
||||
char pktsize;
|
||||
char dskno;
|
||||
char chcmd;
|
||||
char devcmd;
|
||||
int numblks;
|
||||
int blksize;
|
||||
long iobf;
|
||||
int cksum;
|
||||
long lsect;
|
||||
char etxchr;
|
||||
char rwpad;
|
||||
};
|
||||
|
||||
struct rwpkst rwpack = { 512, 5376, 4097, 13, 256, 0, 0, 0, 0, 0, 768 };
|
||||
|
||||
|
||||
char cnvdsk[4] = { 4, 5, 0, 1 }; /* convert from CP/M dsk # to Exormacs */
|
||||
|
||||
char flag2; /* used by the disk interrupt handler */
|
||||
char flag3; /* ditto */
|
||||
|
||||
#define MAXDSK 3
|
||||
|
||||
/************************************************************************/
|
||||
/* Generic Serial Port I/O Procedures */
|
||||
/************************************************************************/
|
||||
|
||||
portinit(port)
|
||||
char *port;
|
||||
{
|
||||
*(port + PORTCTRL) = PORTRSET;
|
||||
*(port + PORTCTRL) = PORTINIT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
portstat(port)
|
||||
char *port;
|
||||
{
|
||||
return ( *(port + PORTSTAT) & PORTRDRF) == PORTRDRF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
char portin(port)
|
||||
char *port;
|
||||
{
|
||||
while (portstat(port) == 0) ;
|
||||
return *(port + PORTRDR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
portout(port, ch)
|
||||
char *port;
|
||||
char ch;
|
||||
{
|
||||
while ( (*(port + PORTSTAT) & PORTTDRE) != PORTTDRE) ;
|
||||
*(port + PORTTDR) = ch;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Error procedure for BIOS */
|
||||
/************************************************************************/
|
||||
|
||||
bioserr(errmsg)
|
||||
char *errmsg;
|
||||
{
|
||||
printstr("\n\rBIOS ERROR -- ");
|
||||
printstr(errmsg);
|
||||
printstr(".\n\r");
|
||||
while(1);
|
||||
}
|
||||
|
||||
printstr(s) /* used by bioserr */
|
||||
register char *s;
|
||||
{
|
||||
while (*s) {portout(PORT1,*s); s += 1; };
|
||||
}
|
||||
|
||||
printnum(n)
|
||||
register long n;
|
||||
{
|
||||
register int i;
|
||||
register char c, j;
|
||||
|
||||
i = 32;
|
||||
do {
|
||||
i -= 4;
|
||||
j = (n>>i) & 0x0F;
|
||||
if ( j < 10 ) c = '0' + j;
|
||||
else c = 'A' + j - 10;
|
||||
portout(PORT2, c);
|
||||
} while (i);
|
||||
portout(PORT2, ' ');
|
||||
}
|
||||
|
||||
printrace(s)
|
||||
register char *s;
|
||||
{
|
||||
while (*s) {portout(PORT2, *s); s += 1;}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Disk I/O Procedures */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
extern dskia();
|
||||
|
||||
dskic()
|
||||
{
|
||||
/* Disk Interrupt Handler -- C Language Portion */
|
||||
|
||||
if ( ! (DSKIPC+MSGFMIPC)->byte )
|
||||
{
|
||||
if ( (DSKIPC+ACKTOIPC)->byte != ACK )
|
||||
{
|
||||
(DSKIPC+ACKTOIPC)->byte = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
(DSKIPC+ACKTOIPC)->byte = 0;
|
||||
flag2 = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (DSKIPC+PKTFMIPC)->byte == 2 )
|
||||
{
|
||||
(DSKIPC+ACKFMIPC)->byte = ACK;
|
||||
(DSKIPC+MSGFMIPC)->byte = 0;
|
||||
(DSKIPC+INTTOIPC)->byte = 0;
|
||||
if ( ((DSKIPC+PKTFMIPC+8 )->byte == 0xFF) &&
|
||||
((DSKIPC+PKTFMIPC+10)->byte == 0x80) )
|
||||
{
|
||||
tbtrk = 0xDFFFFFL;
|
||||
}
|
||||
flag3 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} /* end of dskic */
|
||||
|
||||
|
||||
sendpkt(pktadr, pktsize)
|
||||
register char *pktadr;
|
||||
register int pktsize;
|
||||
{
|
||||
int i;
|
||||
register char *iopackp;
|
||||
|
||||
flag2 = 0xFF;
|
||||
flag3 = 0xFF;
|
||||
DSKINTV->lword = &dskia;
|
||||
i = pktsize;
|
||||
iopackp = (DSKIPC + PKTTOIPC);
|
||||
do { *iopackp = *pktadr++; iopackp += 2; i -= 1;} while (i);
|
||||
(DSKIPC+MSGTOIPC)->byte = 0x80;
|
||||
(DSKIPC+ACKTOIPC)->byte = 0;
|
||||
(DSKIPC+INTTOIPC)->byte = 0;
|
||||
while (flag2 == 0xFF);
|
||||
while (flag3 == 0xFF);
|
||||
}
|
||||
|
||||
|
||||
#define wrongtk ((! tbvalid) || (tbtrk != settrk) || (tbdsk != setdsk))
|
||||
#define gettrk if (wrongtk) filltb()
|
||||
|
||||
|
||||
flush()
|
||||
{
|
||||
|
||||
if ( tbvalid ) /* write out the contents of the track buffer */
|
||||
{
|
||||
rwpack.dskno = cnvdsk[tbdsk];
|
||||
rwpack.iobf = &trkbuf;
|
||||
rwpack.lsect = tbtrk * 13;
|
||||
rwpack.chcmd = 0x20;
|
||||
(DSKIPC + ACKFMIPC)->byte = ACK;
|
||||
if ( (DSKIPC + MSGTOIPC)->byte ) bioserr("ERR2");
|
||||
sendpkt(&rwpack, 21);
|
||||
}
|
||||
|
||||
tbdirty = 0;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
filltb()
|
||||
{
|
||||
|
||||
if ( tbvalid && tbdirty ) flush();
|
||||
|
||||
rwpack.dskno = cnvdsk[setdsk];
|
||||
rwpack.iobf = &trkbuf;
|
||||
rwpack.lsect = settrk * 13;
|
||||
rwpack.chcmd = 0x10;
|
||||
(DSKIPC + ACKFMIPC)->byte = ACK;
|
||||
if ( (DSKIPC + MSGTOIPC)->byte ) bioserr("ERR2");
|
||||
sendpkt(&rwpack, 21);
|
||||
|
||||
tbvalid = 1;
|
||||
tbdirty = 0;
|
||||
tbtrk = settrk;
|
||||
tbdsk = setdsk;
|
||||
|
||||
}
|
||||
|
||||
|
||||
read()
|
||||
{
|
||||
register char *p;
|
||||
register char *q;
|
||||
register int i;
|
||||
|
||||
gettrk;
|
||||
p = &trkbuf[128 * (setsec-1)];
|
||||
q = setdma;
|
||||
i = 128;
|
||||
do {*q++ = *p++; i -= 1;} while (i);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
write(mode)
|
||||
char mode;
|
||||
{
|
||||
register char *p;
|
||||
register char *q;
|
||||
register int i;
|
||||
|
||||
gettrk;
|
||||
p = &trkbuf[128 * (setsec-1)];
|
||||
q = setdma;
|
||||
i = 128;
|
||||
do {*p++ = *q++; i -= 1;} while (i);
|
||||
tbdirty = 1;
|
||||
if ( mode == 1 ) flush();
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
char sectran(s, xp)
|
||||
int s;
|
||||
char *xp;
|
||||
{
|
||||
return xp[s];
|
||||
}
|
||||
|
||||
|
||||
setxvect()
|
||||
{
|
||||
/* dummy */
|
||||
}
|
||||
|
||||
|
||||
long seldsk(dsk, logged)
|
||||
register char dsk;
|
||||
char logged;
|
||||
{
|
||||
register struct dph *dphp;
|
||||
register char check;
|
||||
|
||||
if (dsk > MAXDSK) return(0L);
|
||||
setdsk = dsk;
|
||||
dphp = &dphtab[dsk];
|
||||
if ( ! logged )
|
||||
{
|
||||
hmpack.dskno = cnvdsk[setdsk];
|
||||
hmpack.com1 = 0x30;
|
||||
hmpack.com2 = 0x02;
|
||||
(DSKIPC+ACKFMIPC)->byte = 6;
|
||||
if ( (DSKIPC+MSGTOIPC)->byte ) bioserr("ERR 6");
|
||||
else sendpkt(&hmpack, 7);
|
||||
check = (DSKIPC+PKTFMIPC+0x18)->byte;
|
||||
switch ( check )
|
||||
{
|
||||
case 3: dphp->dpbp = &dpb0;
|
||||
break;
|
||||
|
||||
case 7: dphp->dpbp = &dpb1;
|
||||
break;
|
||||
default: bioserr("ERR 7");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(dphp);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* BIOS PROPER */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
biosinit()
|
||||
{
|
||||
portinit(PORT1);
|
||||
portinit(PORT2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
long bios(d0, d1, d2)
|
||||
int d0;
|
||||
long d1, d2;
|
||||
{
|
||||
if ( d0 > 7) {
|
||||
printrace("\n\rBIOS( ");
|
||||
printnum((long)d0);
|
||||
printnum(d1);
|
||||
printnum(d2);
|
||||
printrace(")\n\r");
|
||||
}
|
||||
|
||||
switch(d0)
|
||||
{
|
||||
case 0: init(); /* INIT */
|
||||
break;
|
||||
|
||||
case 1: wboot(); /* WBOOT */
|
||||
break;
|
||||
|
||||
case 2: return(portstat(PORT1)); /* CONST */
|
||||
break;
|
||||
|
||||
case 3: return(portin(PORT1)); /* CONIN */
|
||||
break;
|
||||
|
||||
case 4: portout(PORT1, (char)d1); /* CONOUT */
|
||||
break;
|
||||
|
||||
case 5: ; /* LIST */
|
||||
case 6: portout(PORT2, (char)d1); /* PUNCH */
|
||||
break;
|
||||
|
||||
case 7: return(portin(PORT2)); /* READER */
|
||||
break;
|
||||
|
||||
case 8: settrk = 0; /* HOME */
|
||||
break;
|
||||
|
||||
case 9: return(seldsk((char)d1, (char)d2)); /* SELDSK */
|
||||
break;
|
||||
|
||||
case 10: settrk = (int)d1; /* SETTRK */
|
||||
break;
|
||||
|
||||
case 11: setsec = (int)d1; /* SETSEC */
|
||||
break;
|
||||
|
||||
case 12: setdma = d1; /* SETDMA */
|
||||
break;
|
||||
|
||||
case 13: return(read()); /* READ */
|
||||
break;
|
||||
|
||||
case 14: return(write((char)d1)); /* WRITE */
|
||||
break;
|
||||
|
||||
case 15: return(portstat(PORT2)); /* LISTST */
|
||||
break;
|
||||
|
||||
case 16: return(sectran((int)d1, d2)); /* SECTRAN */
|
||||
break;
|
||||
|
||||
case 17: return(&memtab); /* GMRTA */
|
||||
break;
|
||||
|
||||
case 19: return(iobyte); /* GETIOB */
|
||||
break;
|
||||
|
||||
case 20: iobyte = (int)d1; /* SETIOB */
|
||||
break;
|
||||
|
||||
case 21: return(flush()); /* FLUSH */
|
||||
break;
|
||||
|
||||
case 22: return(setxvect((int)d1,d2)); /* SETXVECT */
|
||||
break;
|
||||
|
||||
|
||||
|
||||
} /* end switch */
|
||||
|
||||
|
||||
} /* end bios procedure */
|
||||
|
||||
|
||||
|
||||
/* End of C Bios */
|
101
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/conv.pli
Normal file
101
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/conv.pli
Normal file
@@ -0,0 +1,101 @@
|
||||
|
||||
conv: proc options(main);
|
||||
|
||||
dcl (inname,outname) char(50) varying;
|
||||
dcl (infile,outfile) file;
|
||||
dcl bytes char(2);
|
||||
dcl wigit char(512);
|
||||
dcl digit char;
|
||||
dcl bdigit(128) bit(8);
|
||||
dcl (j,i,bnum) bin ;
|
||||
Dcl bytesb(2) char(1) based (bp1) ;
|
||||
Dcl bp1 ptr ;
|
||||
dcl (eof,fof) bit(1);
|
||||
dcl (temp,temp2) bit(8);
|
||||
|
||||
on endfile(infile) eof = '1'b;
|
||||
on undefinedfile(infile) begin;
|
||||
put skip list('File not found');
|
||||
stop;
|
||||
end;
|
||||
|
||||
bp1 = addr(bytes) ;
|
||||
|
||||
put skip edit('Source Filename: ')(a(23)); get edit(inname)(a(50));
|
||||
put skip edit('Destination Filename: ')(a(23)); get edit(outname)(a(50));
|
||||
|
||||
open file(infile) input environment(block_io) sequential title(inname);
|
||||
open file(outfile) output stream linesize(80) title(outname);
|
||||
|
||||
eof = '0'b; fof = '0'b;
|
||||
read file(infile) into (wigit);
|
||||
do while( ^fof);
|
||||
fof = eof;
|
||||
do bnum = 1 to 512;
|
||||
temp = unspec(substr(wigit,bnum,1));
|
||||
do i = 1 to 8 ; substr(temp2,i,1) = substr(temp,9-i,1); end;
|
||||
bytes = byte_to_hex(temp2);
|
||||
put file(outfile) edit((bytesb(i) do i = 1 to 2)) (2(a));
|
||||
end;
|
||||
if ^eof then read file(infile) into (wigit);
|
||||
end;
|
||||
|
||||
close file(infile);
|
||||
close file(outfile);
|
||||
|
||||
/* utility routines for conversions */
|
||||
|
||||
bit_to_hex:
|
||||
proc(xb) returns(char(1));
|
||||
dcl
|
||||
xb bit(4),
|
||||
xi fixed bin(7),
|
||||
hex(16) bit(4) static initial
|
||||
('0000','0001','0010','0011',
|
||||
'0100','0101','0110','0111',
|
||||
'1000','1001','1010','1011',
|
||||
'1100','1101','1110','1111'),
|
||||
list char(16) static initial
|
||||
('0123456789ABCDEF');
|
||||
do xi = 1 to 16 while(hex(xi) ^= xb);
|
||||
end;
|
||||
return(substr(list,xi,1));
|
||||
end bit_to_hex;
|
||||
|
||||
hex_to_bit:
|
||||
proc(xc) returns(bit(4));
|
||||
dcl
|
||||
xc char(1),
|
||||
xi fixed bin(7),
|
||||
hex(16) bit(4) static initial
|
||||
('0000','0001','0010','0011',
|
||||
'0100','0101','0110','0111',
|
||||
'1000','1001','1010','1011',
|
||||
'1100','1101','1110','1111'),
|
||||
list char(16) static initial
|
||||
('0123456789ABCDEF');
|
||||
xi = index(list,xc);
|
||||
if xi = 0 then
|
||||
do;
|
||||
put skip list('INVALID HEX CHARACTER:');
|
||||
stop;
|
||||
end;
|
||||
else
|
||||
return(hex(xi));
|
||||
end hex_to_bit;
|
||||
|
||||
byte_to_hex:
|
||||
proc(xb) returns(char(2));
|
||||
dcl
|
||||
xb bit(8);
|
||||
return(bit_to_hex(substr(xb,1,4))||bit_to_hex(substr(xb,5,4)));
|
||||
end byte_to_hex;
|
||||
|
||||
hex_to_byte:
|
||||
proc(xc) returns(bit(8));
|
||||
dcl
|
||||
xc char(2);
|
||||
return(hex_to_bit(substr(xc,1,1))||hex_to_bit(substr(xc,2,1)));
|
||||
end hex_to_byte;
|
||||
|
||||
end;
|
@@ -0,0 +1,20 @@
|
||||
$ set noon
|
||||
$ copy c:[cpm68k.release.bdos]*.c,*.s,*.h,*.com,*.doc [.cbdos]
|
||||
$ pur [.cbdos]
|
||||
$ copy c:[cpm68k.release.boot]*.c,*.s,*.h,*.com [.boot]
|
||||
$ pur [.boot]
|
||||
$ copy c:[cpm68k.release.ccp]*.c,*.s,*.h,*.com [.ccp]
|
||||
$ pur [.ccp]
|
||||
$ copy c:[cpm68k.release.ddt]*.c,*.s,*.h,*.com [.ddt]
|
||||
$ pur [.ddt]
|
||||
$ copy b:[cpm68k.release.bios]*.c,*.s,*.h,*.com [.bios]
|
||||
$ pur [.bios]
|
||||
$ copy c:[cpm68k.release.pipedstat]*.* [.utils]
|
||||
$ copy c:[cpm68k.release.tools]*.* [.utils]
|
||||
$ copy c:[cpm68k.release.serial]*.* [.utils]
|
||||
$ pur [.utils]
|
||||
$ copy c:[cpm68k.release.clib]*.* [.clib]
|
||||
$ pur [.clib]
|
||||
$ copy c:[cpm68k.release.relnotes]*.* [.doc]
|
||||
$ copy c:[cpm68k.release.docs]*.* [.doc]
|
||||
$ pur [.doc]
|
@@ -0,0 +1,15 @@
|
||||
.text
|
||||
.globl _init
|
||||
.globl _ccp
|
||||
*
|
||||
* Init Routine -- User fills in jump address
|
||||
*
|
||||
_init: jmp 0
|
||||
*
|
||||
* This jump to the CCP may be used by the user to achieve a warmboot
|
||||
*
|
||||
jmp _ccp
|
||||
*
|
||||
*
|
||||
.end
|
||||
|
288
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/eldbios.s
Normal file
288
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/eldbios.s
Normal file
@@ -0,0 +1,288 @@
|
||||
*****************************************************************
|
||||
* *
|
||||
* CP/M-68K Loader BIOS *
|
||||
* Basic Input/Output Subsystem *
|
||||
* For ERG 68000 with Tarbell floppy disk controller *
|
||||
* *
|
||||
*****************************************************************
|
||||
|
||||
|
||||
.globl _bios * declare external entry point
|
||||
|
||||
|
||||
_bios:
|
||||
cmpi #nfuncs,d0
|
||||
bge nogood
|
||||
lsl #2,d0 * multiply bios function by 4
|
||||
movea.l 6(pc,d0),a0 * get handler address
|
||||
jsr (a0) * call handler
|
||||
nogood:
|
||||
rts
|
||||
|
||||
biosbase:
|
||||
.dc.l nogood
|
||||
.dc.l nogood
|
||||
.dc.l constat
|
||||
.dc.l conin
|
||||
.dc.l conout
|
||||
.dc.l nogood
|
||||
.dc.l nogood
|
||||
.dc.l nogood
|
||||
.dc.l home
|
||||
.dc.l seldsk
|
||||
.dc.l settrk
|
||||
.dc.l setsec
|
||||
.dc.l setdma
|
||||
.dc.l read
|
||||
.dc.l nogood
|
||||
.dc.l nogood
|
||||
.dc.l sectran
|
||||
.dc.l setdma
|
||||
.dc.l getseg
|
||||
.dc.l nogood
|
||||
.dc.l nogood
|
||||
.dc.l nogood
|
||||
.dc.l setexc
|
||||
|
||||
nfuncs=(*-biosbase)/4
|
||||
|
||||
|
||||
constat: move.b $ffff01,d0 * get status byte
|
||||
andi.w #2,d0 * data available bit on?
|
||||
beq noton * branch if not
|
||||
moveq.l #$1,d0 * set result to true
|
||||
rts
|
||||
|
||||
noton: clr.l d0 * set result to false
|
||||
rts
|
||||
|
||||
conin: bsr constat * see if key pressed
|
||||
tst d0
|
||||
beq conin * wait until key pressed
|
||||
move.b $ffff00,d0 * get key
|
||||
and.l #$7f,d0 * clear all but low 7 bits
|
||||
rts
|
||||
|
||||
conout: move.b $ffff01,d0 * get status
|
||||
and.b #$1,d0 * check for transmitter buffer empty
|
||||
beq conout * wait until our port has aged...
|
||||
move.b d1,$ffff00 * and output it
|
||||
rts * and exit
|
||||
|
||||
|
||||
*
|
||||
* Disk Handlers for Tarbell 1793 floppy disk controller
|
||||
*
|
||||
maxdsk = 2 * this BIOS supports 2 floppy drives
|
||||
dphlen = 26 * length of disk parameter header
|
||||
|
||||
iobase = $00fffff8 * Tarbell floppy disk port base address
|
||||
dcmd = iobase * output port for command
|
||||
dstat = iobase * input status port
|
||||
dtrk = iobase+1 * disk track port
|
||||
dsect = iobase+2 * disk sector port
|
||||
ddata = iobase+3 * disk data port
|
||||
dwait = iobase+4 * input port to wait for op finished
|
||||
dcntrl = iobase+4 * output control port for drive selection
|
||||
|
||||
|
||||
home: clr.b track
|
||||
rts
|
||||
|
||||
seldsk:
|
||||
* select disk A
|
||||
clr.b seldrv * select drive A
|
||||
clr.b selcode * select code is 00 for drv 0, $10 for drv 1
|
||||
move.l #dph0,d0
|
||||
selrtn: rts
|
||||
|
||||
settrk: move.b d1,track
|
||||
rts
|
||||
|
||||
setsec: move.b d1,sector
|
||||
rts
|
||||
|
||||
sectran:
|
||||
* translate sector in d1 with translate table pointed to by d2
|
||||
* result in d0
|
||||
movea.l d2,a0
|
||||
ext.l d1
|
||||
move.b #0(a0,d1),d0
|
||||
ext.l d0
|
||||
rts
|
||||
|
||||
setdma:
|
||||
move.l d1,dma
|
||||
rts
|
||||
|
||||
read:
|
||||
* Read one sector from requested disk, track, sector to dma address
|
||||
* Retry if necessary, return in d0 00 if ok, else non-zero
|
||||
move.b #10,errcnt * set up retry counter
|
||||
rretry:
|
||||
bsr setup
|
||||
ori #$88,d3 * OR read command with head load bit
|
||||
move.b d3,dcmd * output it to FDC
|
||||
rloop: btst #7,dwait
|
||||
beq rdone * if end of read, exit
|
||||
move.b ddata,(a0)+ * else, move next byte of data
|
||||
bra rloop
|
||||
rdone:
|
||||
bsr rstatus * get FDC status
|
||||
bne rerror
|
||||
clr.l d0
|
||||
rts
|
||||
rerror: bsr errchk * go to error handler
|
||||
subq.b #1,errcnt
|
||||
bne rretry
|
||||
move.l #$ffffffff,d0
|
||||
rts
|
||||
|
||||
|
||||
setup:
|
||||
* common read and write setup code
|
||||
* select disk, set track, set sector were all deferred until now
|
||||
move.b #$d0,dcmd * clear controller, get status
|
||||
move.b curdrv,d3
|
||||
cmp.b seldrv,d3
|
||||
bne newdrive * if drive not selected, do it
|
||||
move.b track,d3
|
||||
cmp.b oldtrk,d3
|
||||
bne newtrk * if not on right track, do it
|
||||
clr.l d3 * if head already loaded, no head load delay
|
||||
btst #5,dstat * if head unloaded, treat as new disk
|
||||
bne sexit
|
||||
newdrive:
|
||||
move.b selcode,dcntrl * select the drive
|
||||
move.b seldrv,curdrv
|
||||
newtrk:
|
||||
bsr chkseek * seek to correct track if required
|
||||
moveq #4,d3 * force head load delay
|
||||
sexit:
|
||||
move.b sector,dsect * set up sector number
|
||||
move.b track,dtrk * set up track number
|
||||
move.l dma,a0 * dma address to a0
|
||||
rts
|
||||
|
||||
errchk:
|
||||
btst.b #4,d7
|
||||
bne chkseek * if record not found error, reseek
|
||||
rts
|
||||
|
||||
chkseek:
|
||||
* check for correct track, seek if necessary
|
||||
bsr readid * find out what track we're on
|
||||
beq chks1 * if read id ok, skip restore code
|
||||
restore:
|
||||
* home the drive and reseek to correct track
|
||||
move.b #$0B,dcmd * restore command to command port
|
||||
rstwait:
|
||||
btst #7,dwait
|
||||
bne rstwait * loop until restore completed
|
||||
btst #2,dstat
|
||||
beq restore * if not at track 0, try again
|
||||
clr.l d3 * track number returned in d3 from readid
|
||||
chks1:
|
||||
move.b d3,dtrk * update track register in FDC
|
||||
move.b track,oldtrk * update oldtrk
|
||||
cmp.b track,d3 * are we at right track?
|
||||
beq chkdone * if yes, exit
|
||||
move.b track,ddata * else, put desired track in data reg of FDC
|
||||
move.b #$18,dcmd * and issue a seek command
|
||||
chks2: btst #7,dwait
|
||||
bne chks2 * loop until seek complete
|
||||
move.b dstat,d3 * read status to clear FDC
|
||||
chkdone:
|
||||
rts
|
||||
|
||||
readid:
|
||||
* read track id, return track number in d3
|
||||
move.b #$c4,dcmd * issue read id command
|
||||
move.b dwait,d7 * wait for intrq
|
||||
move.b ddata,d3 * track byte to d3
|
||||
rid2:
|
||||
btst #7,dwait
|
||||
beq rstatus * wait for intrq
|
||||
move.b ddata,d7 * read another byte
|
||||
bra rid2 * and loop
|
||||
rstatus:
|
||||
move.b dstat,d7
|
||||
andi.b #$9d,d7 * set condition codes
|
||||
rts
|
||||
|
||||
|
||||
getseg:
|
||||
move.l #memrgn,d0 * return address of mem region table
|
||||
rts
|
||||
|
||||
|
||||
setexc:
|
||||
andi.l #$ff,d1 * do only for exceptions 0 - 255
|
||||
lsl #2,d1 * multiply exception number by 4
|
||||
movea.l d1,a0
|
||||
move.l (a0),d0 * return old vector value
|
||||
move.l d2,(a0) * insert new vector
|
||||
rts
|
||||
|
||||
|
||||
.data
|
||||
|
||||
seldrv: .dc.b $ff * drive requested by seldsk
|
||||
curdrv: .dc.b $ff * currently selected drive
|
||||
|
||||
track: .dc.b 0 * track requested by settrk
|
||||
oldtrk: .dc.b 0 * track we were on
|
||||
|
||||
sector: .dc.w 0
|
||||
dma: .dc.l 0
|
||||
selcode: .dc.b 0 * drive select code
|
||||
|
||||
errcnt: .dc.b 10 * retry counter
|
||||
|
||||
memrgn: .dc.w 1 * 1 memory region
|
||||
.dc.l $18000 * load the system at 18000 hex
|
||||
.dc.l $8000
|
||||
|
||||
|
||||
* disk parameter headers
|
||||
|
||||
dph0: .dc.l xlt
|
||||
.dc.w 0 * dummy
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.l dirbuf * ptr to directory buffer
|
||||
.dc.l dpb * ptr to disk parameter block
|
||||
.dc.l 0 * ptr to check vector
|
||||
.dc.l 0 * ptr to allocation vector
|
||||
|
||||
|
||||
* disk parameter block
|
||||
|
||||
dpb: .dc.w 26 * sectors per track
|
||||
.dc.b 3 * block shift
|
||||
.dc.b 7 * block mask
|
||||
.dc.b 0 * extent mask
|
||||
.dc.b 0 * dummy fill
|
||||
.dc.w 242 * disk size
|
||||
.dc.w 63 * 64 directory entries
|
||||
.dc.w $c000 * directory mask
|
||||
.dc.w 16 * directory check size
|
||||
.dc.w 2 * track offset
|
||||
|
||||
* sector translate table
|
||||
|
||||
xlt: .dc.b 1, 7,13,19
|
||||
.dc.b 25, 5,11,17
|
||||
.dc.b 23, 3, 9,15
|
||||
.dc.b 21, 2, 8,14
|
||||
.dc.b 20,26, 6,12
|
||||
.dc.b 18,24, 4,10
|
||||
.dc.b 16,22
|
||||
|
||||
|
||||
.bss
|
||||
|
||||
dirbuf: .ds.b 128 * directory buffer
|
||||
|
||||
|
||||
.end
|
360
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/ergbios.s
Normal file
360
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/ergbios.s
Normal file
@@ -0,0 +1,360 @@
|
||||
*****************************************************************
|
||||
* *
|
||||
* CP/M-68K BIOS *
|
||||
* Basic Input/Output Subsystem *
|
||||
* For ERG 68000 with Tarbell floppy disk controller *
|
||||
* *
|
||||
*****************************************************************
|
||||
|
||||
.globl _init * bios initialization entry point
|
||||
.globl _ccp * ccp entry point
|
||||
|
||||
_init: move.l #traphndl,$8c * set up trap #3 handler
|
||||
clr.l d0 * log on disk A, user 0
|
||||
rts
|
||||
|
||||
traphndl:
|
||||
cmpi #nfuncs,d0
|
||||
bcc trapng
|
||||
lsl #2,d0 * multiply bios function by 4
|
||||
movea.l 6(pc,d0),a0 * get handler address
|
||||
jsr (a0) * call handler
|
||||
trapng:
|
||||
rte
|
||||
|
||||
biosbase:
|
||||
.dc.l _init
|
||||
.dc.l wboot
|
||||
.dc.l constat
|
||||
.dc.l conin
|
||||
.dc.l conout
|
||||
.dc.l lstout
|
||||
.dc.l pun
|
||||
.dc.l rdr
|
||||
.dc.l home
|
||||
.dc.l seldsk
|
||||
.dc.l settrk
|
||||
.dc.l setsec
|
||||
.dc.l setdma
|
||||
.dc.l read
|
||||
.dc.l write
|
||||
.dc.l listst
|
||||
.dc.l sectran
|
||||
.dc.l setdma
|
||||
.dc.l getseg
|
||||
.dc.l getiob
|
||||
.dc.l setiob
|
||||
.dc.l flush
|
||||
.dc.l setexc
|
||||
|
||||
nfuncs=(*-biosbase)/4
|
||||
|
||||
wboot: jmp _ccp
|
||||
|
||||
constat: move.b $ffff01,d0 * get status byte
|
||||
andi.w #2,d0 * data available bit on?
|
||||
beq noton * branch if not
|
||||
moveq.l #$1,d0 * set result to true
|
||||
rts
|
||||
|
||||
noton: clr.l d0 * set result to false
|
||||
rts
|
||||
|
||||
conin: bsr constat * see if key pressed
|
||||
tst d0
|
||||
beq conin * wait until key pressed
|
||||
move.b $ffff00,d0 * get key
|
||||
and.l #$7f,d0 * clear all but low 7 bits
|
||||
cmpi.b #1,d0
|
||||
beq break
|
||||
rts
|
||||
break:
|
||||
trap $f
|
||||
.dc.w 0 * return to MACSBUG
|
||||
rts
|
||||
|
||||
conout: move.b $ffff01,d0 * get status
|
||||
and.b #$1,d0 * check for transmitter buffer empty
|
||||
beq conout * wait until our port has aged...
|
||||
move.b d1,$ffff00 * and output it
|
||||
rts * and exit
|
||||
|
||||
lstout: rts
|
||||
|
||||
pun: rts
|
||||
|
||||
rdr: rts
|
||||
|
||||
listst: move.b #$ff,d0
|
||||
rts
|
||||
|
||||
*
|
||||
* Disk Handlers for Tarbell 1793 floppy disk controller
|
||||
*
|
||||
maxdsk = 2 * this BIOS supports 2 floppy drives
|
||||
dphlen = 26 * length of disk parameter header
|
||||
|
||||
iobase = $00fffff8 * Tarbell floppy disk port base address
|
||||
dcmd = iobase * output port for command
|
||||
dstat = iobase * input status port
|
||||
dtrk = iobase+1 * disk track port
|
||||
dsect = iobase+2 * disk sector port
|
||||
ddata = iobase+3 * disk data port
|
||||
dwait = iobase+4 * input port to wait for op finished
|
||||
dcntrl = iobase+4 * output control port for drive selection
|
||||
|
||||
|
||||
home: clr.b track
|
||||
rts
|
||||
|
||||
seldsk:
|
||||
* select disk given by register d1.b
|
||||
moveq #0,d0
|
||||
cmp.b #maxdsk,d1 * valid drive number?
|
||||
bpl selrtn * if no, return 0 in d0
|
||||
move.b d1,seldrv * else, save drive number
|
||||
lsl.b #4,d1
|
||||
move.b d1,selcode * select code is 00 for drv 0, $10 for drv 1
|
||||
move.b seldrv,d0
|
||||
mulu #dphlen,d0
|
||||
add.l #dph0,d0 * point d0 at correct dph
|
||||
selrtn: rts
|
||||
|
||||
settrk: move.b d1,track
|
||||
rts
|
||||
|
||||
setsec: move.b d1,sector
|
||||
rts
|
||||
|
||||
sectran:
|
||||
* translate sector in d1 with translate table pointed to by d2
|
||||
* result in d0
|
||||
movea.l d2,a0
|
||||
ext.l d1
|
||||
move.b #0(a0,d1),d0
|
||||
ext.l d0
|
||||
rts
|
||||
|
||||
setdma:
|
||||
move.l d1,dma
|
||||
rts
|
||||
|
||||
read:
|
||||
* Read one sector from requested disk, track, sector to dma address
|
||||
* Retry if necessary, return in d0 00 if ok, else non-zero
|
||||
move.b #10,errcnt * set up retry counter
|
||||
rretry:
|
||||
bsr setup
|
||||
ori #$88,d3 * OR read command with head load bit
|
||||
move.b d3,dcmd * output it to FDC
|
||||
rloop: btst #7,dwait
|
||||
beq rdone * if end of read, exit
|
||||
move.b ddata,(a0)+ * else, move next byte of data
|
||||
bra rloop
|
||||
rdone:
|
||||
bsr rstatus * get FDC status
|
||||
bne rerror
|
||||
clr.l d0
|
||||
rts
|
||||
rerror: bsr errchk * go to error handler
|
||||
subq.b #1,errcnt
|
||||
bne rretry
|
||||
move.l #$ffffffff,d0
|
||||
rts
|
||||
|
||||
write:
|
||||
* Write one sector to requested disk, track, sector from dma address
|
||||
* Retry if necessary, return in d0 00 if ok, else non-zero
|
||||
move.b #10,errcnt * set up retry counter
|
||||
wretry:
|
||||
bsr setup
|
||||
ori #$a8,d3 * OR write command with head load bit
|
||||
move.b d3,dcmd * output it to FDC
|
||||
wloop: btst #7,dwait
|
||||
beq wdone * if end of read, exit
|
||||
move.b (a0)+,ddata * else, move next byte of data
|
||||
bra wloop
|
||||
wdone:
|
||||
bsr rstatus * get FDC status
|
||||
bne werror
|
||||
clr.l d0
|
||||
rts
|
||||
werror: bsr errchk * go to error handler
|
||||
subq.b #1,errcnt
|
||||
bne wretry
|
||||
move.l #$ffffffff,d0
|
||||
rts
|
||||
|
||||
setup:
|
||||
* common read and write setup code
|
||||
* select disk, set track, set sector were all deferred until now
|
||||
move.b #$d0,dcmd * clear controller, get status
|
||||
move.b curdrv,d3
|
||||
cmp.b seldrv,d3
|
||||
bne newdrive * if drive not selected, do it
|
||||
move.b track,d3
|
||||
cmp.b oldtrk,d3
|
||||
bne newtrk * if not on right track, do it
|
||||
clr.l d3 * if head already loaded, no head load delay
|
||||
btst #5,dstat * if head unloaded, treat as new disk
|
||||
bne sexit
|
||||
newdrive:
|
||||
move.b selcode,dcntrl * select the drive
|
||||
move.b seldrv,curdrv
|
||||
newtrk:
|
||||
bsr chkseek * seek to correct track if required
|
||||
moveq #4,d3 * force head load delay
|
||||
sexit:
|
||||
move.b sector,dsect * set up sector number
|
||||
move.b track,dtrk * set up track number
|
||||
move.l dma,a0 * dma address to a0
|
||||
rts
|
||||
|
||||
errchk:
|
||||
btst.b #4,d7
|
||||
bne chkseek * if record not found error, reseek
|
||||
rts
|
||||
|
||||
chkseek:
|
||||
* check for correct track, seek if necessary
|
||||
bsr readid * find out what track we're on
|
||||
beq chks1 * if read id ok, skip restore code
|
||||
restore:
|
||||
* home the drive and reseek to correct track
|
||||
move.b #$0B,dcmd * restore command to command port
|
||||
rstwait:
|
||||
btst #7,dwait
|
||||
bne rstwait * loop until restore completed
|
||||
btst #2,dstat
|
||||
beq restore * if not at track 0, try again
|
||||
clr.l d3 * track number returned in d3 from readid
|
||||
chks1:
|
||||
move.b d3,dtrk * update track register in FDC
|
||||
move.b track,oldtrk * update oldtrk
|
||||
cmp.b track,d3 * are we at right track?
|
||||
beq chkdone * if yes, exit
|
||||
move.b track,ddata * else, put desired track in data reg of FDC
|
||||
move.b #$18,dcmd * and issue a seek command
|
||||
chks2: btst #7,dwait
|
||||
bne chks2 * loop until seek complete
|
||||
move.b dstat,d3 * read status to clear FDC
|
||||
chkdone:
|
||||
rts
|
||||
|
||||
readid:
|
||||
* read track id, return track number in d3
|
||||
move.b #$c4,dcmd * issue read id command
|
||||
move.b dwait,d7 * wait for intrq
|
||||
move.b ddata,d3 * track byte to d3
|
||||
rid2:
|
||||
btst #7,dwait
|
||||
beq rstatus * wait for intrq
|
||||
move.b ddata,d7 * read another byte
|
||||
bra rid2 * and loop
|
||||
rstatus:
|
||||
move.b dstat,d7
|
||||
andi.b #$9d,d7 * set condition codes
|
||||
rts
|
||||
|
||||
|
||||
flush:
|
||||
clr.l d0 * return successful
|
||||
rts
|
||||
|
||||
getseg:
|
||||
move.l #memrgn,d0 * return address of mem region table
|
||||
rts
|
||||
|
||||
getiob:
|
||||
rts
|
||||
|
||||
setiob:
|
||||
rts
|
||||
|
||||
setexc:
|
||||
andi.l #$ff,d1 * do only for exceptions 0 - 255
|
||||
cmpi #47,d1
|
||||
beq noset * this BIOS doesn't set Trap 15
|
||||
cmpi #9,d1 * or Trace
|
||||
beq noset
|
||||
lsl #2,d1 * multiply exception nmbr by 4
|
||||
movea.l d1,a0
|
||||
move.l (a0),d0 * return old vector value
|
||||
move.l d2,(a0) * insert new vector
|
||||
noset: rts
|
||||
|
||||
|
||||
.data
|
||||
|
||||
seldrv: .dc.b $ff * drive requested by seldsk
|
||||
curdrv: .dc.b $ff * currently selected drive
|
||||
|
||||
track: .dc.b 0 * track requested by settrk
|
||||
oldtrk: .dc.b 0 * track we were on
|
||||
|
||||
sector: .dc.w 0
|
||||
dma: .dc.l 0
|
||||
selcode: .dc.b 0 * drive select code
|
||||
|
||||
errcnt: .dc.b 10 * retry counter
|
||||
|
||||
memrgn: .dc.w 1 * 1 memory region
|
||||
.dc.l $800 * starts at 800 hex
|
||||
.dc.l $17800 * goes until 18000 hex
|
||||
|
||||
|
||||
* disk parameter headers
|
||||
|
||||
dph0: .dc.l xlt
|
||||
.dc.w 0 * dummy
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.l dirbuf * ptr to directory buffer
|
||||
.dc.l dpb * ptr to disk parameter block
|
||||
.dc.l ckv0 * ptr to check vector
|
||||
.dc.l alv0 * ptr to allocation vector
|
||||
|
||||
dph1: .dc.l xlt
|
||||
.dc.w 0 * dummy
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.l dirbuf * ptr to directory buffer
|
||||
.dc.l dpb * ptr to disk parameter block
|
||||
.dc.l ckv1 * ptr to check vector
|
||||
.dc.l alv1 * ptr to allocation vector
|
||||
|
||||
* disk parameter block
|
||||
|
||||
dpb: .dc.w 26 * sectors per track
|
||||
.dc.b 3 * block shift
|
||||
.dc.b 7 * block mask
|
||||
.dc.b 0 * extent mask
|
||||
.dc.b 0 * dummy fill
|
||||
.dc.w 242 * disk size
|
||||
.dc.w 63 * 64 directory entries
|
||||
.dc.w $c000 * directory mask
|
||||
.dc.w 16 * directory check size
|
||||
.dc.w 2 * track offset
|
||||
|
||||
* sector translate table
|
||||
|
||||
xlt: .dc.b 1, 7,13,19
|
||||
.dc.b 25, 5,11,17
|
||||
.dc.b 23, 3, 9,15
|
||||
.dc.b 21, 2, 8,14
|
||||
.dc.b 20,26, 6,12
|
||||
.dc.b 18,24, 4,10
|
||||
.dc.b 16,22
|
||||
|
||||
|
||||
.bss
|
||||
|
||||
dirbuf: .ds.b 128 * directory buffer
|
||||
|
||||
ckv0: .ds.b 16 * check vector
|
||||
ckv1: .ds.b 16
|
||||
|
||||
alv0: .ds.b 32 * allocation vector
|
||||
alv1: .ds.b 32
|
||||
|
||||
.end
|
@@ -0,0 +1,2 @@
|
||||
#define LOADER 0
|
||||
#define CTLTYPE 1
|
@@ -0,0 +1,2 @@
|
||||
#define LOADER 1
|
||||
#define CTLTYPE 1
|
1124
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/hdbios.c
Normal file
1124
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/hdbios.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
$ set nover
|
||||
$ set noon
|
||||
$ set def [bill.cpm68k.bios]
|
||||
$ num
|
||||
hdbios.c
|
||||
hdbios.num
|
||||
$ cc68 :== @cc68.com
|
||||
$ as68 :== $bin:as68.exe
|
||||
$ ld68 :== $bin:lo68.exe
|
||||
$ cc68 hdbios
|
||||
$ as68 -u -l -p biosa.s >biosa.lis
|
||||
$ pr/nofeed hdbios.num,hdbios.lis,biosa.lis
|
@@ -0,0 +1,13 @@
|
||||
$ set nover
|
||||
$ set noon
|
||||
$ set def [bill.cpm68k.bios]
|
||||
$ num
|
||||
hdbios.c
|
||||
hdbios.num
|
||||
$ cc68 :== @cc68.com
|
||||
$ as68 :== $bin:as68.exe
|
||||
$ ld68 :== $bin:lo68.exe
|
||||
$ cc68 hdbios
|
||||
$ as68 -u -l -p biosa.s >biosa.lis
|
||||
$ ld68 -t76400 -o hdbiosys.sys biosa.o hdbios.o
|
||||
$ pr/nofeed hdbios.num,hdbios.lis,biosa.lis
|
@@ -0,0 +1,12 @@
|
||||
$ set nover
|
||||
$ set noon
|
||||
$ set def [bill.cpm68k.bios]
|
||||
$ num
|
||||
hdbios.c
|
||||
hdbios.num
|
||||
$ cc68 :== @cc68.com
|
||||
$ as68 :== $bin:as68.exe
|
||||
$ ld68 :== $bin:lo68.exe
|
||||
$ cc68 hdbios
|
||||
$ as68 -u -l -p ldbiosa.s >ldbiosa.lis
|
||||
$ pr/nofeed hdbios.num,hdbios.lis,ldbiosa.lis
|
@@ -0,0 +1,41 @@
|
||||
.text
|
||||
.globl _bios
|
||||
.globl _biosinit
|
||||
.globl _cbios
|
||||
.globl _dskia
|
||||
.globl _dskic
|
||||
.globl _setimask
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
_bios: link a6,#0
|
||||
move.l d2,-(a7)
|
||||
move.l d1,-(a7)
|
||||
move.w d0,-(a7)
|
||||
move #$2000,sr
|
||||
lea _dskia,a0
|
||||
move.l a0,$3fc
|
||||
jsr _cbios
|
||||
unlk a6
|
||||
rts
|
||||
*
|
||||
_dskia: link a6,#0
|
||||
movem.l d0-d7/a0-a5,-(a7)
|
||||
jsr _dskic
|
||||
movem.l (a7)+,d0-d7/a0-a5
|
||||
unlk a6
|
||||
rte
|
||||
*
|
||||
_setimask: move sr,d0
|
||||
lsr #8,d0
|
||||
and.l #7,d0
|
||||
move sr,d1
|
||||
ror.w #8,d1
|
||||
and.w #$fff8,d1
|
||||
add.w 4(a7),d1
|
||||
ror.w #8,d1
|
||||
move d1,sr
|
||||
rts
|
||||
*
|
||||
.end
|
@@ -0,0 +1,2 @@
|
||||
#define LOADER 1
|
||||
#define CTLTYPE 0
|
@@ -0,0 +1,3 @@
|
||||
#define LOADER 0
|
||||
#define CTLTYPE 0
|
||||
#define MEMDSK 4
|
@@ -0,0 +1 @@
|
||||
$pr/nofeed bios.num,bios.lis,biosa.lis
|
706
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/relbios.c
Normal file
706
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/relbios.c
Normal file
@@ -0,0 +1,706 @@
|
||||
/*=======================================================================*/
|
||||
/*/---------------------------------------------------------------------\*/
|
||||
/*| |*/
|
||||
/*| CP/M-68K(tm) BIOS for the EXORMACS |*/
|
||||
/*| |*/
|
||||
/*| Copyright 1982, Digital Research. |*/
|
||||
/*| |*/
|
||||
/*\---------------------------------------------------------------------/*/
|
||||
/*=======================================================================*/
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
char copyright[] = "Copyright 1982, Digital Research";
|
||||
|
||||
struct memb { char byte; };
|
||||
struct memw { int word; };
|
||||
struct meml { long lword;};
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* I/O Device Definitions */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Define the two ACIA ports on the DEBUG board */
|
||||
/************************************************************************/
|
||||
|
||||
#define PORT1 0xFFEE011
|
||||
#define PORT2 0xFFEE015
|
||||
|
||||
#define PORTCTRL 0
|
||||
#define PORTSTAT 0
|
||||
#define PORTRDR 2
|
||||
#define PORTTDR 2
|
||||
|
||||
#define PORTRSET 3
|
||||
#define PORTINIT 0x11
|
||||
|
||||
#define PORTRDRF 1
|
||||
#define PORTTDRE 2
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Define Disk I/O Addresses and Related Constants */
|
||||
/************************************************************************/
|
||||
|
||||
#define DSKIPC 0xFF0000 /* IPC Base Address */
|
||||
|
||||
#define DSKINTV 0x3FC /* Address of Disk Interrupt Vector */
|
||||
|
||||
#define INTTOIPC 0xD /* offsets */
|
||||
#define RSTTOIPC 0xF
|
||||
#define MSGTOIPC 0x101
|
||||
#define ACKTOIPC 0x103
|
||||
#define PKTTOIPC 0x105
|
||||
#define MSGFMIPC 0x181
|
||||
#define ACKFMIPC 0x183
|
||||
#define PKTFMIPC 0x185
|
||||
|
||||
#define DSKREAD 0x10
|
||||
#define DSKWRITE 0x20
|
||||
|
||||
#define STX 0x02
|
||||
#define ETX 0x03
|
||||
#define ACK 0x06
|
||||
#define NAK 0x15
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* BIOS Table Definitions */
|
||||
/************************************************************************/
|
||||
|
||||
struct dpb
|
||||
{
|
||||
int spt;
|
||||
char bsh;
|
||||
char blm;
|
||||
char exm;
|
||||
char dpbjunk;
|
||||
int dsm;
|
||||
int drm;
|
||||
char al0;
|
||||
char al1;
|
||||
int cks;
|
||||
int off;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct dph
|
||||
{
|
||||
char *xltp;
|
||||
int dphscr[3];
|
||||
char *dirbufp;
|
||||
struct dpb *dpbp;
|
||||
char *csvp;
|
||||
char *alvp;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Directory Buffer for use by the BDOS */
|
||||
/************************************************************************/
|
||||
|
||||
char dirbuf[128];
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* CSV's */
|
||||
/************************************************************************/
|
||||
|
||||
char csv0[16];
|
||||
char csv1[16];
|
||||
char csv2[16];
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* ALV's */
|
||||
/************************************************************************/
|
||||
|
||||
char alv0[32]; /* (dsm0 / 8) + 1 */
|
||||
char alv1[32]; /* (dsm1 / 8) + 1 */
|
||||
char alv2[2002]; /* (dsm2 / 8) + 1 */
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Disk Parameter Blocks */
|
||||
/************************************************************************/
|
||||
|
||||
/* The following dpb definitions express the intent of the writer, */
|
||||
/* unfortunately, due to a compiler bug, these lines cannot be used. */
|
||||
/* Therefore, the obscure code following them has been inserted. */
|
||||
|
||||
/************* spt, bsh, blm, exm, jnk, dsm, drm, al0, al1, cks, off
|
||||
|
||||
struct dpb dpb0={ 26, 3, 7, 0, 0, 242, 63, 0xC0, 0, 16, 2};
|
||||
struct dpb dpb1={ 26, 4, 15, 0, 0, 242, 63, 0xC0, 0, 16, 2};
|
||||
struct dpb dpb2={ 26, 3, 7, 0, 0, 16008, 63, 0xC0, 0, 16, 2};
|
||||
|
||||
********** end of readable definitions *************/
|
||||
|
||||
/* The Alcyon C compiler assumes all structures are arrays of int, so */
|
||||
/* in the following definitions, adjacent pairs of chars have been */
|
||||
/* combined into int constants --- what a kludge! **********************/
|
||||
|
||||
struct dpb dpb0 = { 26, 775, 0, 242, 63, -16384, 16, 2 };
|
||||
struct dpb dpb1 = { 26, 1039, 0, 242, 63, -16384, 16, 2 };
|
||||
struct dpb dpb2 = { 26, 775, 0, 16008, 63, -16384, 16, 2 };
|
||||
|
||||
/*************** End of kludge *****************/
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Sector Translate Table */
|
||||
/************************************************************************/
|
||||
|
||||
char xlt[26] = { 1, 7, 13, 19, 25, 5, 11, 17, 23, 3, 9, 15, 21,
|
||||
2, 8, 14, 20, 26, 6, 12, 18, 24, 4, 10, 16, 22 };
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Disk Parameter Headers */
|
||||
/* */
|
||||
/* Four disks are defined : dsk a: diskno=0, dev name=#fd04 */
|
||||
/* dsk b: diskno=1, dev name=#fd05 */
|
||||
/* dsk c: diskno=2, dev name=#hd00 */
|
||||
/* dsk d: diskno=3, dev name=#hd01 */
|
||||
/************************************************************************/
|
||||
|
||||
struct dph dphtab[4] =
|
||||
{ {&xlt, 0, 0, 0, &dirbuf, &dpb0, &csv0, &alv0}, /*dsk a*/
|
||||
{&xlt, 0, 0, 0, &dirbuf, &dpb0, &csv1, &alv1}, /*dsk b*/
|
||||
{ 0L, 0, 0, 0, &dirbuf, &dpb2, &csv2, &alv2}, /*dsk c*/
|
||||
{ 0L, 0, 0, 0, &dirbuf, &dpb2, &csv2, &alv2}, /*dsk d*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Memory Region Table */
|
||||
/************************************************************************/
|
||||
|
||||
struct mrt { int count;
|
||||
long tpalow;
|
||||
long tpalen;
|
||||
}
|
||||
memtab = { 1, 0x0000,0x400, 0x0001,0x7c00 };/* kludge init by int */
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* IOchar */
|
||||
/************************************************************************/
|
||||
|
||||
int iobyte;
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Currently Selected Disk Stuff */
|
||||
/************************************************************************/
|
||||
|
||||
int settrk, setsec, setdsk;
|
||||
char *setdma;
|
||||
|
||||
|
||||
char trkbuf[26 * 128];
|
||||
int tbvalid = 0;
|
||||
int tbdirty = 0;
|
||||
int tbtrk;
|
||||
int tbdsk;
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Disk I/O Packets for the UDC and other Disk I/O Variables */
|
||||
/************************************************************************/
|
||||
|
||||
struct hmpkst {
|
||||
char a1;
|
||||
char a2;
|
||||
char a3;
|
||||
char dskno;
|
||||
char com1;
|
||||
char com2;
|
||||
char a6;
|
||||
char a7;
|
||||
}
|
||||
hmpack = { 512, 1792, 0, 768 }; /* kludge init by words */
|
||||
|
||||
|
||||
struct rwpkst {
|
||||
char stxchr;
|
||||
char pktid;
|
||||
char pktsize;
|
||||
char dskno;
|
||||
char chcmd;
|
||||
char devcmd;
|
||||
int numblks;
|
||||
int blksize;
|
||||
long iobf;
|
||||
int cksum;
|
||||
long lsect;
|
||||
char etxchr;
|
||||
char rwpad;
|
||||
};
|
||||
|
||||
struct rwpkst rwpack = { 512, 5376, 4097, 13, 256, 0, 0, 0, 0, 0, 768 };
|
||||
|
||||
|
||||
char cnvdsk[4] = { 4, 5, 0, 1 }; /* convert from CP/M dsk # to Exormacs */
|
||||
|
||||
#define MAXDSK 3
|
||||
|
||||
|
||||
#define DSKIDLE 0
|
||||
#define MSGSENT 1
|
||||
#define NAKRCVD 2
|
||||
#define ACKRCVD 3
|
||||
#define IODONE 4
|
||||
|
||||
int dskstate = DSKIDLE;
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Generic Serial Port I/O Procedures */
|
||||
/************************************************************************/
|
||||
|
||||
portinit(port)
|
||||
register char *port;
|
||||
{
|
||||
*(port + PORTCTRL) = PORTRSET;
|
||||
*(port + PORTCTRL) = PORTINIT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
portstat(port)
|
||||
register char *port;
|
||||
{
|
||||
return ( *(port + PORTSTAT) & PORTRDRF) == PORTRDRF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
char portin(port)
|
||||
register char *port;
|
||||
{
|
||||
while (portstat(port) == 0) ;
|
||||
return *(port + PORTRDR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
portout(port, ch)
|
||||
register char *port;
|
||||
register char ch;
|
||||
{
|
||||
while ( (*(port + PORTSTAT) & PORTTDRE) != PORTTDRE) ;
|
||||
*(port + PORTTDR) = ch;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Error procedure for BIOS */
|
||||
/************************************************************************/
|
||||
|
||||
bioserr(errmsg)
|
||||
register char *errmsg;
|
||||
{
|
||||
printstr("\n\rBIOS ERROR -- ");
|
||||
printstr(errmsg);
|
||||
printstr(".\n\r");
|
||||
while(1);
|
||||
}
|
||||
|
||||
printstr(s) /* used by bioserr */
|
||||
register char *s;
|
||||
{
|
||||
while (*s) {portout(PORT1,*s); s += 1; };
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
||||
printds(ds)
|
||||
int ds;
|
||||
{
|
||||
switch(ds){
|
||||
case DSKIDLE: printstr("DSKIDLE");
|
||||
break;
|
||||
case MSGSENT: printstr("MSGSENT");
|
||||
break;
|
||||
case NAKRCVD: printstr("NAKRCVD");
|
||||
break;
|
||||
case ACKRCVD: printstr("ACKRCVD");
|
||||
break;
|
||||
case IODONE: printstr("IODONE");
|
||||
break;
|
||||
default: printstr("Invalid");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/************************************************************************/
|
||||
/* Disk I/O Procedures */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
extern dskia();
|
||||
extern setimask();
|
||||
|
||||
dskic()
|
||||
{
|
||||
/* Disk Interrupt Handler -- C Language Portion */
|
||||
|
||||
#if DEBUG
|
||||
|
||||
printstr("\n\rDisk Interrupt ");
|
||||
printds(dskstate);
|
||||
printstr("->");
|
||||
|
||||
#endif
|
||||
|
||||
switch ( dskstate )
|
||||
{
|
||||
case DSKIDLE: ;
|
||||
case IODONE: ;
|
||||
case NAKRCVD: {
|
||||
if ( ((DSKIPC+ACKFMIPC)->byte == ACK) ||
|
||||
((DSKIPC+ACKFMIPC)->byte == NAK) )
|
||||
{
|
||||
(DSKIPC+ACKFMIPC)->byte = 0;
|
||||
}
|
||||
|
||||
if ( (DSKIPC+MSGFMIPC)->byte == 0x80 )
|
||||
{
|
||||
(DSKIPC+ACKTOIPC)->byte = ACK;
|
||||
(DSKIPC+MSGFMIPC)->byte = 0;
|
||||
(DSKIPC+INTTOIPC)->byte = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSGSENT: {
|
||||
if ( (DSKIPC+ACKFMIPC)->byte == ACK )
|
||||
{
|
||||
(DSKIPC+ACKFMIPC)->byte = 0;
|
||||
dskstate = ACKRCVD;
|
||||
}
|
||||
else if ( (DSKIPC+ACKFMIPC)->byte == NAK )
|
||||
{
|
||||
(DSKIPC+ACKFMIPC)->byte = 0;
|
||||
dskstate = NAKRCVD;
|
||||
}
|
||||
else bioserr("Expected ACK or NAK");
|
||||
if ( (DSKIPC+MSGFMIPC)->byte == 0x80 )
|
||||
{ dskstate = IODONE; }
|
||||
}
|
||||
break;
|
||||
|
||||
case ACKRCVD: {
|
||||
if ( (DSKIPC+MSGFMIPC)->byte != 0x80 )
|
||||
{ bioserr("Expected status packet from IPC");}
|
||||
|
||||
dskstate = IODONE;
|
||||
(DSKIPC+MSGFMIPC)->byte = 0;
|
||||
(DSKIPC+ACKTOIPC)->byte = ACK;
|
||||
(DSKIPC+INTTOIPC)->byte = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
printds(dskstate);
|
||||
printstr("\n\r");
|
||||
#endif
|
||||
|
||||
} /* end of dskic */
|
||||
|
||||
|
||||
sendpkt(pktadr, pktsize)
|
||||
register char *pktadr;
|
||||
register int pktsize;
|
||||
{
|
||||
register char *iopackp;
|
||||
register int imsave;
|
||||
|
||||
while ( (DSKIPC+MSGTOIPC)->byte ); /* wait til ready */
|
||||
if ( (DSKIPC+ACKFMIPC)->byte == NAK ) bioserr("NAK from IPC");
|
||||
(DSKIPC+ACKFMIPC)->byte = 0;
|
||||
(DSKIPC+MSGFMIPC)->byte = 0;
|
||||
iopackp = (DSKIPC+PKTTOIPC);
|
||||
do {*iopackp = *pktadr++; iopackp += 2; pktsize -= 1;} while(pktsize);
|
||||
(DSKIPC+MSGTOIPC)->byte = 0x80;
|
||||
imsave = setimask(7);
|
||||
dskstate = MSGSENT;
|
||||
(DSKIPC+INTTOIPC)->byte = 0;
|
||||
setimask(imsave);
|
||||
}
|
||||
|
||||
|
||||
dskxfer(dsk, trk, bufp, cmd)
|
||||
register int dsk, trk, cmd;
|
||||
register char *bufp;
|
||||
{
|
||||
/* build packet */
|
||||
rwpack.dskno = cnvdsk[dsk];
|
||||
rwpack.iobf = bufp;
|
||||
rwpack.lsect = trk * 13;
|
||||
rwpack.chcmd = cmd;
|
||||
sendpkt(&rwpack, 21);
|
||||
while (dskstate == MSGSENT); /* wait */
|
||||
if (dskstate == NAKRCVD) bioserr("NAK from IPC");
|
||||
while (dskstate == ACKRCVD); /* wait */
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define wrongtk ((! tbvalid) || (tbtrk != settrk) || (tbdsk != setdsk))
|
||||
#define gettrk if (wrongtk) filltb()
|
||||
|
||||
|
||||
flush()
|
||||
{
|
||||
|
||||
if ( tbvalid ) dskxfer(tbdsk, tbtrk, &trkbuf, DSKWRITE);
|
||||
|
||||
tbdirty = 0;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
filltb()
|
||||
{
|
||||
|
||||
if ( tbvalid && tbdirty ) flush();
|
||||
|
||||
dskxfer(setdsk, settrk, &trkbuf, DSKREAD);
|
||||
|
||||
tbvalid = 1;
|
||||
tbdirty = 0;
|
||||
tbtrk = settrk;
|
||||
tbdsk = setdsk;
|
||||
|
||||
}
|
||||
|
||||
|
||||
read()
|
||||
{
|
||||
register char *p;
|
||||
register char *q;
|
||||
register int i;
|
||||
|
||||
gettrk;
|
||||
p = &trkbuf[128 * (setsec-1)];
|
||||
q = setdma;
|
||||
i = 128;
|
||||
do {*q++ = *p++; i -= 1;} while (i);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
write(mode)
|
||||
char mode;
|
||||
{
|
||||
register char *p;
|
||||
register char *q;
|
||||
register int i;
|
||||
|
||||
gettrk;
|
||||
p = &trkbuf[128 * (setsec-1)];
|
||||
q = setdma;
|
||||
i = 128;
|
||||
do {*p++ = *q++; i -= 1;} while (i);
|
||||
tbdirty = 1;
|
||||
if ( mode == 1 ) flush();
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
char sectran(s, xp)
|
||||
int s;
|
||||
char *xp;
|
||||
{
|
||||
return xp[s];
|
||||
}
|
||||
|
||||
|
||||
long setxvect(vnum, vval)
|
||||
int vnum;
|
||||
long vval;
|
||||
{
|
||||
register long oldval;
|
||||
register char *vloc;
|
||||
|
||||
vloc = ( (long)vnum ) << 2;
|
||||
oldval = vloc->lword;
|
||||
vloc->lword = vval;
|
||||
|
||||
return(oldval);
|
||||
|
||||
}
|
||||
|
||||
|
||||
long seldsk(dsk, logged)
|
||||
register char dsk;
|
||||
char logged;
|
||||
{
|
||||
register struct dph *dphp;
|
||||
register char check;
|
||||
|
||||
if (dsk > MAXDSK) return(0L);
|
||||
setdsk = dsk;
|
||||
dphp = &dphtab[dsk];
|
||||
if ( ! logged )
|
||||
{
|
||||
|
||||
hmpack.dskno = cnvdsk[setdsk];
|
||||
hmpack.com1 = 0x30;
|
||||
hmpack.com2 = 0x02;
|
||||
(DSKIPC+ACKFMIPC)->byte = 6;
|
||||
if ( (DSKIPC+MSGTOIPC)->byte ) bioserr("ERR 6");
|
||||
else sendpkt(&hmpack, 7);
|
||||
while ( dskstate == MSGSENT ); /* wait */
|
||||
if (dskstate == NAKRCVD) bioserr("NAK from IPC");
|
||||
while ( dskstate == ACKRCVD ); /* wait */
|
||||
check = (DSKIPC+PKTFMIPC+0x18)->byte;
|
||||
switch ( check )
|
||||
{
|
||||
case 3: dphp->dpbp = &dpb0;
|
||||
break;
|
||||
|
||||
case 7: dphp->dpbp = &dpb1;
|
||||
break;
|
||||
default: bioserr("ERR 7");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(dphp);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* BIOS PROPER */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
biosinit()
|
||||
{
|
||||
portinit(PORT1);
|
||||
portinit(PORT2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
long bios(d0, d1, d2)
|
||||
int d0;
|
||||
long d1, d2;
|
||||
{
|
||||
|
||||
#if DEBUG
|
||||
|
||||
if ( d0 > 7) {
|
||||
printrace("\n\rBIOS( ");
|
||||
printnum((long)d0);
|
||||
printnum(d1);
|
||||
printnum(d2);
|
||||
printrace(")\n\r");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
switch(d0)
|
||||
{
|
||||
case 0: init(); /* INIT */
|
||||
break;
|
||||
|
||||
case 1: wboot(); /* WBOOT */
|
||||
break;
|
||||
|
||||
case 2: return(portstat(PORT1)); /* CONST */
|
||||
break;
|
||||
|
||||
case 3: return(portin(PORT1)); /* CONIN */
|
||||
break;
|
||||
|
||||
case 4: portout(PORT1, (char)d1); /* CONOUT */
|
||||
break;
|
||||
|
||||
case 5: ; /* LIST */
|
||||
case 6: portout(PORT2, (char)d1); /* PUNCH */
|
||||
break;
|
||||
|
||||
case 7: return(portin(PORT2)); /* READER */
|
||||
break;
|
||||
|
||||
case 8: settrk = 0; /* HOME */
|
||||
break;
|
||||
|
||||
case 9: return(seldsk((char)d1, (char)d2)); /* SELDSK */
|
||||
break;
|
||||
|
||||
case 10: settrk = (int)d1; /* SETTRK */
|
||||
break;
|
||||
|
||||
case 11: setsec = (int)d1; /* SETSEC */
|
||||
break;
|
||||
|
||||
case 12: setdma = d1; /* SETDMA */
|
||||
break;
|
||||
|
||||
case 13: return(read()); /* READ */
|
||||
break;
|
||||
|
||||
case 14: return(write((char)d1)); /* WRITE */
|
||||
break;
|
||||
|
||||
case 15: return(portstat(PORT2)); /* LISTST */
|
||||
break;
|
||||
|
||||
case 16: return(sectran((int)d1, d2)); /* SECTRAN */
|
||||
break;
|
||||
|
||||
case 18: return(&memtab); /* GMRTA */
|
||||
break;
|
||||
|
||||
case 19: return(iobyte); /* GETIOB */
|
||||
break;
|
||||
|
||||
case 20: iobyte = (int)d1; /* SETIOB */
|
||||
break;
|
||||
|
||||
case 21: return(flush()); /* FLUSH */
|
||||
break;
|
||||
|
||||
case 22: return(setxvect((int)d1,d2)); /* SETXVECT */
|
||||
break;
|
||||
|
||||
|
||||
|
||||
} /* end switch */
|
||||
|
||||
|
||||
} /* end bios procedure */
|
||||
|
||||
|
||||
|
||||
/* End of C Bios */
|
@@ -0,0 +1,13 @@
|
||||
$ set nover
|
||||
$ set noon
|
||||
$ set def [bill.cpm68k.bios]
|
||||
$ num
|
||||
relbios.c
|
||||
relbios.num
|
||||
$ cc68 :== @cc68.com
|
||||
$ as68 :== $bin:as68.exe
|
||||
$ ld68 :== $bin:lo68.exe
|
||||
$ cc68 relbios
|
||||
$ as68 -u -l -p relbiosa.s >relbiosa.lis
|
||||
$ ld68 -r -t1e000 -o relbios.68k relbiosa.o relbios.o
|
||||
$ s68 relbios.68k >[bill.cpm68k.object]relbios.sr
|
887
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/relbios.s
Normal file
887
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/relbios.s
Normal file
@@ -0,0 +1,887 @@
|
||||
.globl _copyrigh
|
||||
.data
|
||||
_copyrigh:
|
||||
.dc.b 67,111,112,121,114,105,103,104,116,32,49,57,56,50,44,32,68,105,103,105,116,97,108,32,82,101,115,101,97,114,99,104,0
|
||||
.even
|
||||
.globl _dirbuf
|
||||
.comm _dirbuf,128
|
||||
.globl _csv0
|
||||
.comm _csv0,16
|
||||
.globl _csv1
|
||||
.comm _csv1,16
|
||||
.globl _csv2
|
||||
.comm _csv2,16
|
||||
.globl _alv0
|
||||
.comm _alv0,32
|
||||
.globl _alv1
|
||||
.comm _alv1,32
|
||||
.globl _alv2
|
||||
.comm _alv2,2002
|
||||
.globl _dpb0
|
||||
.data
|
||||
_dpb0:
|
||||
.dc.w 26
|
||||
.dc.w 775
|
||||
.dc.w 0
|
||||
.dc.w 242
|
||||
.dc.w 63
|
||||
.dc.w -16384
|
||||
.dc.w 16
|
||||
.dc.w 2
|
||||
.globl _dpb1
|
||||
.data
|
||||
_dpb1:
|
||||
.dc.w 26
|
||||
.dc.w 1039
|
||||
.dc.w 0
|
||||
.dc.w 242
|
||||
.dc.w 63
|
||||
.dc.w -16384
|
||||
.dc.w 16
|
||||
.dc.w 2
|
||||
.globl _dpb2
|
||||
.data
|
||||
_dpb2:
|
||||
.dc.w 26
|
||||
.dc.w 775
|
||||
.dc.w 0
|
||||
.dc.w 16008
|
||||
.dc.w 63
|
||||
.dc.w -16384
|
||||
.dc.w 16
|
||||
.dc.w 2
|
||||
.globl _xlt
|
||||
.data
|
||||
_xlt:
|
||||
.dc.b 1
|
||||
.dc.b 7
|
||||
.dc.b 13
|
||||
.dc.b 19
|
||||
.dc.b 25
|
||||
.dc.b 5
|
||||
.dc.b 11
|
||||
.dc.b 17
|
||||
.dc.b 23
|
||||
.dc.b 3
|
||||
.dc.b 9
|
||||
.dc.b 15
|
||||
.dc.b 21
|
||||
.dc.b 2
|
||||
.dc.b 8
|
||||
.dc.b 14
|
||||
.dc.b 20
|
||||
.dc.b 26
|
||||
.dc.b 6
|
||||
.dc.b 12
|
||||
.dc.b 18
|
||||
.dc.b 24
|
||||
.dc.b 4
|
||||
.dc.b 10
|
||||
.dc.b 16
|
||||
.dc.b 22
|
||||
.globl _dphtab
|
||||
.data
|
||||
_dphtab:
|
||||
.dc.l _xlt
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.l _dirbuf
|
||||
.dc.l _dpb0
|
||||
.dc.l _csv0
|
||||
.dc.l _alv0
|
||||
.dc.l _xlt
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.l _dirbuf
|
||||
.dc.l _dpb0
|
||||
.dc.l _csv1
|
||||
.dc.l _alv1
|
||||
.dc.w 0,0
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.l _dirbuf
|
||||
.dc.l _dpb2
|
||||
.dc.l _csv2
|
||||
.dc.l _alv2
|
||||
.dc.w 0,0
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.l _dirbuf
|
||||
.dc.l _dpb2
|
||||
.dc.l _csv2
|
||||
.dc.l _alv2
|
||||
.globl _memtab
|
||||
.data
|
||||
_memtab:
|
||||
.dc.w 1
|
||||
.dc.w 0
|
||||
.dc.w 1024
|
||||
.dc.w 1
|
||||
.dc.w 31744
|
||||
.globl _iobyte
|
||||
.comm _iobyte,2
|
||||
.globl _settrk
|
||||
.comm _settrk,2
|
||||
.globl _setsec
|
||||
.comm _setsec,2
|
||||
.globl _setdsk
|
||||
.comm _setdsk,2
|
||||
.globl _setdma
|
||||
.comm _setdma,4
|
||||
.globl _trkbuf
|
||||
.comm _trkbuf,3328
|
||||
.globl _tbvalid
|
||||
.data
|
||||
_tbvalid:
|
||||
.dc.w 0
|
||||
.globl _tbdirty
|
||||
.data
|
||||
_tbdirty:
|
||||
.dc.w 0
|
||||
.globl _tbtrk
|
||||
.comm _tbtrk,2
|
||||
.globl _tbdsk
|
||||
.comm _tbdsk,2
|
||||
.globl _hmpack
|
||||
.data
|
||||
_hmpack:
|
||||
.dc.w 512
|
||||
.dc.w 1792
|
||||
.dc.w 0
|
||||
.dc.w 768
|
||||
.globl _rwpack
|
||||
.data
|
||||
_rwpack:
|
||||
.dc.w 512
|
||||
.dc.w 5376
|
||||
.dc.w 4097
|
||||
.dc.w 13
|
||||
.dc.w 256
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.w 0
|
||||
.dc.w 768
|
||||
.globl _cnvdsk
|
||||
.data
|
||||
_cnvdsk:
|
||||
.dc.b 4
|
||||
.dc.b 5
|
||||
.dc.b 0
|
||||
.dc.b 1
|
||||
.globl _dskstate
|
||||
.data
|
||||
_dskstate:
|
||||
.dc.w 0
|
||||
.globl _portinit
|
||||
.text
|
||||
_portinit:
|
||||
~~portinit:
|
||||
~port=R13
|
||||
link R14,#0
|
||||
movem.l R7-R7/R13-R13,-(sp)
|
||||
move.l 8(R14),R13
|
||||
move.b #3,(R13)
|
||||
move.b #17,(R13)
|
||||
L2:tst.l (sp)+
|
||||
movem.l (sp)+,R13-R13
|
||||
unlk R14
|
||||
rts
|
||||
.globl _portstat
|
||||
.text
|
||||
_portstat:
|
||||
~~portstat:
|
||||
~port=R13
|
||||
link R14,#0
|
||||
movem.l R7-R7/R13-R13,-(sp)
|
||||
move.l 8(R14),R13
|
||||
btst #0,(R13)
|
||||
bne L10000
|
||||
clr R0
|
||||
bra L10001
|
||||
L10000:move #1,R0
|
||||
L10001:bra L3
|
||||
L3:tst.l (sp)+
|
||||
movem.l (sp)+,R13-R13
|
||||
unlk R14
|
||||
rts
|
||||
.globl _portin
|
||||
.text
|
||||
_portin:
|
||||
~~portin:
|
||||
~port=R13
|
||||
link R14,#0
|
||||
movem.l R7-R7/R13-R13,-(sp)
|
||||
move.l 8(R14),R13
|
||||
L6:
|
||||
move.l R13,(sp)
|
||||
jsr _portstat
|
||||
tst R0
|
||||
bne L5
|
||||
bra L6
|
||||
L5:
|
||||
move.b 2(R13),R0
|
||||
ext.w R0
|
||||
bra L4
|
||||
L4:tst.l (sp)+
|
||||
movem.l (sp)+,R13-R13
|
||||
unlk R14
|
||||
rts
|
||||
.globl _portout
|
||||
.text
|
||||
_portout:
|
||||
~~portout:
|
||||
~ch=R7
|
||||
~port=R13
|
||||
link R14,#0
|
||||
movem.l R6-R7/R13-R13,-(sp)
|
||||
move.l 8(R14),R13
|
||||
move.b 13(R14),R7
|
||||
L9:
|
||||
btst #1,(R13)
|
||||
bne L8
|
||||
bra L9
|
||||
L8:
|
||||
move.b R7,2(R13)
|
||||
L7:tst.l (sp)+
|
||||
movem.l (sp)+,R7-R7/R13-R13
|
||||
unlk R14
|
||||
rts
|
||||
.globl _bioserr
|
||||
.text
|
||||
_bioserr:
|
||||
~~bioserr:
|
||||
~errmsg=R13
|
||||
link R14,#0
|
||||
movem.l R7-R7/R13-R13,-(sp)
|
||||
move.l 8(R14),R13
|
||||
move.l #L11,(sp)
|
||||
jsr _printstr
|
||||
move.l R13,(sp)
|
||||
jsr _printstr
|
||||
move.l #L12,(sp)
|
||||
jsr _printstr
|
||||
L14:
|
||||
bra L14
|
||||
L13:L10:tst.l (sp)+
|
||||
movem.l (sp)+,R13-R13
|
||||
unlk R14
|
||||
rts
|
||||
.globl _printstr
|
||||
.text
|
||||
_printstr:
|
||||
~~printstr:
|
||||
~s=R13
|
||||
link R14,#0
|
||||
movem.l R7-R7/R13-R13,-(sp)
|
||||
move.l 8(R14),R13
|
||||
L17:
|
||||
tst.b (R13)
|
||||
beq L16
|
||||
move.b (R13),R0
|
||||
ext.w R0
|
||||
move R0,(sp)
|
||||
move.l #$ffee011,-(sp)
|
||||
jsr _portout
|
||||
add #4,sp
|
||||
add.l #1,R13
|
||||
bra L17
|
||||
L16:L15:tst.l (sp)+
|
||||
movem.l (sp)+,R13-R13
|
||||
unlk R14
|
||||
rts
|
||||
.globl _dskia
|
||||
.globl _setimask
|
||||
.globl _dskic
|
||||
.text
|
||||
_dskic:
|
||||
~~dskic:
|
||||
link R14,#-4
|
||||
move _dskstate,R0
|
||||
bra L20
|
||||
L21:L22:L23:
|
||||
cmp.b #6,$ff0183
|
||||
beq L10002
|
||||
cmp.b #21,$ff0183
|
||||
bne L24
|
||||
L10002:clr.b $ff0183
|
||||
L24:
|
||||
cmp.b #128,$ff0181
|
||||
bne L25
|
||||
move.b #6,$ff0103
|
||||
clr.b $ff0181
|
||||
clr.b $ff000d
|
||||
L25:bra L19
|
||||
L26:
|
||||
cmp.b #6,$ff0183
|
||||
bne L27
|
||||
clr.b $ff0183
|
||||
move #3,_dskstate
|
||||
bra L28
|
||||
L27:
|
||||
cmp.b #21,$ff0183
|
||||
bne L29
|
||||
clr.b $ff0183
|
||||
move #2,_dskstate
|
||||
bra L30
|
||||
L29:
|
||||
move.l #L31,(sp)
|
||||
jsr _bioserr
|
||||
L30:L28:
|
||||
cmp.b #128,$ff0181
|
||||
bne L32
|
||||
move #4,_dskstate
|
||||
L32:bra L19
|
||||
L33:
|
||||
cmp.b #128,$ff0181
|
||||
beq L34
|
||||
move.l #L35,(sp)
|
||||
jsr _bioserr
|
||||
L34:
|
||||
move #4,_dskstate
|
||||
clr.b $ff0181
|
||||
move.b #6,$ff0103
|
||||
clr.b $ff000d
|
||||
bra L19
|
||||
bra L19
|
||||
L20:cmp #4,R0
|
||||
bhi L19
|
||||
asl #2,R0
|
||||
move R0,R8
|
||||
add.l #L36,R8
|
||||
move.l (R8),R8
|
||||
jmp (R8)
|
||||
.data
|
||||
L36:.dc.l L21
|
||||
.dc.l L26
|
||||
.dc.l L23
|
||||
.dc.l L33
|
||||
.dc.l L22
|
||||
.text
|
||||
L19:L18:unlk R14
|
||||
rts
|
||||
.globl _sendpkt
|
||||
.text
|
||||
_sendpkt:
|
||||
~~sendpkt:
|
||||
~imsave=R6
|
||||
~pktadr=R13
|
||||
~iopackp=R12
|
||||
~pktsize=R7
|
||||
link R14,#0
|
||||
movem.l R5-R7/R12-R13,-(sp)
|
||||
move.l 8(R14),R13
|
||||
move 12(R14),R7
|
||||
L39:
|
||||
tst.b $ff0101
|
||||
beq L38
|
||||
bra L39
|
||||
L38:
|
||||
cmp.b #21,$ff0183
|
||||
bne L40
|
||||
move.l #L41,(sp)
|
||||
jsr _bioserr
|
||||
L40:
|
||||
clr.b $ff0183
|
||||
clr.b $ff0181
|
||||
move.l #$ff0105,R12
|
||||
L44:
|
||||
move.b (R13)+,(R12)
|
||||
add.l #2,R12
|
||||
sub #1,R7
|
||||
L43:
|
||||
tst R7
|
||||
bne L44
|
||||
L42:
|
||||
move.b #128,$ff0101
|
||||
move #7,(sp)
|
||||
jsr _setimask
|
||||
move R0,R6
|
||||
move #1,_dskstate
|
||||
clr.b $ff000d
|
||||
move R6,(sp)
|
||||
jsr _setimask
|
||||
L37:tst.l (sp)+
|
||||
movem.l (sp)+,R6-R7/R12-R13
|
||||
unlk R14
|
||||
rts
|
||||
.globl _dskxfer
|
||||
.text
|
||||
_dskxfer:
|
||||
~~dskxfer:
|
||||
~cmd=R5
|
||||
~dsk=R7
|
||||
~trk=R6
|
||||
~bufp=R13
|
||||
link R14,#0
|
||||
movem.l R4-R7/R13-R13,-(sp)
|
||||
move 8(R14),R7
|
||||
move 10(R14),R6
|
||||
move.l 12(R14),R13
|
||||
move 16(R14),R5
|
||||
move R7,R0
|
||||
ext.l R0
|
||||
add.l #_cnvdsk,R0
|
||||
move.l R0,R8
|
||||
move.b (R8),3+_rwpack
|
||||
move.l R13,10+_rwpack
|
||||
move R6,R0
|
||||
muls #13,R0
|
||||
move.l R0,16+_rwpack
|
||||
move.b R5,4+_rwpack
|
||||
move #21,(sp)
|
||||
move.l #_rwpack,-(sp)
|
||||
jsr _sendpkt
|
||||
add #4,sp
|
||||
L47:
|
||||
cmp #1,_dskstate
|
||||
bne L46
|
||||
bra L47
|
||||
L46:
|
||||
cmp #2,_dskstate
|
||||
bne L48
|
||||
move.l #L49,(sp)
|
||||
jsr _bioserr
|
||||
L48:L51:
|
||||
cmp #3,_dskstate
|
||||
bne L50
|
||||
bra L51
|
||||
L50:L45:tst.l (sp)+
|
||||
movem.l (sp)+,R5-R7/R13-R13
|
||||
unlk R14
|
||||
rts
|
||||
.globl _flush
|
||||
.text
|
||||
_flush:
|
||||
~~flush:
|
||||
link R14,#-4
|
||||
tst _tbvalid
|
||||
beq L53
|
||||
move #32,(sp)
|
||||
move.l #_trkbuf,-(sp)
|
||||
move _tbtrk,-(sp)
|
||||
move _tbdsk,-(sp)
|
||||
jsr _dskxfer
|
||||
add #8,sp
|
||||
L53:
|
||||
clr _tbdirty
|
||||
clr R0
|
||||
bra L52
|
||||
L52:unlk R14
|
||||
rts
|
||||
.globl _filltb
|
||||
.text
|
||||
_filltb:
|
||||
~~filltb:
|
||||
link R14,#-4
|
||||
tst _tbvalid
|
||||
beq L55
|
||||
tst _tbdirty
|
||||
beq L55
|
||||
jsr _flush
|
||||
L55:
|
||||
move #16,(sp)
|
||||
move.l #_trkbuf,-(sp)
|
||||
move _settrk,-(sp)
|
||||
move _setdsk,-(sp)
|
||||
jsr _dskxfer
|
||||
add #8,sp
|
||||
move #1,_tbvalid
|
||||
clr _tbdirty
|
||||
move _settrk,_tbtrk
|
||||
move _setdsk,_tbdsk
|
||||
L54:unlk R14
|
||||
rts
|
||||
.globl _read
|
||||
.text
|
||||
_read:
|
||||
~~read:
|
||||
~i=R7
|
||||
~p=R13
|
||||
~q=R12
|
||||
link R14,#0
|
||||
movem.l R6-R7/R12-R13,-(sp)
|
||||
tst _tbvalid
|
||||
beq L10003
|
||||
move _tbtrk,R0
|
||||
cmp _settrk,R0
|
||||
bne L10003
|
||||
move _tbdsk,R0
|
||||
cmp _setdsk,R0
|
||||
beq L57
|
||||
L10003:jsr _filltb
|
||||
L57:
|
||||
move _setsec,R0
|
||||
sub #1,R0
|
||||
asl #7,R0
|
||||
ext.l R0
|
||||
move.l R0,R13
|
||||
add.l #_trkbuf,R13
|
||||
move.l _setdma,R12
|
||||
move #128,R7
|
||||
L60:
|
||||
move.b (R13)+,(R12)+
|
||||
sub #1,R7
|
||||
L59:
|
||||
tst R7
|
||||
bne L60
|
||||
L58:
|
||||
clr R0
|
||||
bra L56
|
||||
L56:tst.l (sp)+
|
||||
movem.l (sp)+,R7-R7/R12-R13
|
||||
unlk R14
|
||||
rts
|
||||
.globl _write
|
||||
.text
|
||||
_write:
|
||||
~~write:
|
||||
~i=R7
|
||||
~p=R13
|
||||
~q=R12
|
||||
~mode=9
|
||||
link R14,#0
|
||||
movem.l R6-R7/R12-R13,-(sp)
|
||||
tst _tbvalid
|
||||
beq L10004
|
||||
move _tbtrk,R0
|
||||
cmp _settrk,R0
|
||||
bne L10004
|
||||
move _tbdsk,R0
|
||||
cmp _setdsk,R0
|
||||
beq L62
|
||||
L10004:jsr _filltb
|
||||
L62:
|
||||
move _setsec,R0
|
||||
sub #1,R0
|
||||
asl #7,R0
|
||||
ext.l R0
|
||||
move.l R0,R13
|
||||
add.l #_trkbuf,R13
|
||||
move.l _setdma,R12
|
||||
move #128,R7
|
||||
L65:
|
||||
move.b (R12)+,(R13)+
|
||||
sub #1,R7
|
||||
L64:
|
||||
tst R7
|
||||
bne L65
|
||||
L63:
|
||||
move #1,_tbdirty
|
||||
cmp.b #1,9(R14)
|
||||
bne L66
|
||||
jsr _flush
|
||||
L66:
|
||||
clr R0
|
||||
bra L61
|
||||
L61:tst.l (sp)+
|
||||
movem.l (sp)+,R7-R7/R12-R13
|
||||
unlk R14
|
||||
rts
|
||||
.globl _sectran
|
||||
.text
|
||||
_sectran:
|
||||
~~sectran:
|
||||
~s=8
|
||||
~xp=10
|
||||
link R14,#-4
|
||||
move 8(R14),R8
|
||||
move.l 10(R14),R9
|
||||
move.b 0(R8,R9.l),R0
|
||||
ext.w R0
|
||||
bra L67
|
||||
L67:unlk R14
|
||||
rts
|
||||
.globl _setxvect
|
||||
.text
|
||||
_setxvect:
|
||||
~~setxvect:
|
||||
~oldval=R7
|
||||
~vloc=R13
|
||||
~vval=10
|
||||
~vnum=8
|
||||
link R14,#0
|
||||
movem.l R6-R7/R13-R13,-(sp)
|
||||
move 8(R14),R0
|
||||
ext.l R0
|
||||
asl.l #2,R0
|
||||
move.l R0,R13
|
||||
move.l (R13),R7
|
||||
move.l 10(R14),(R13)
|
||||
move.l R7,R0
|
||||
bra L68
|
||||
L68:tst.l (sp)+
|
||||
movem.l (sp)+,R7-R7/R13-R13
|
||||
unlk R14
|
||||
rts
|
||||
.globl _seldsk
|
||||
.text
|
||||
_seldsk:
|
||||
~~seldsk:
|
||||
~logged=11
|
||||
~dsk=R7
|
||||
~dphp=R13
|
||||
~check=R6
|
||||
link R14,#0
|
||||
movem.l R5-R7/R13-R13,-(sp)
|
||||
move.b 9(R14),R7
|
||||
cmp.b #3,R7
|
||||
ble L70
|
||||
move.l #$0,R0
|
||||
bra L69
|
||||
L70:
|
||||
move.b R7,R0
|
||||
ext.w R0
|
||||
move R0,_setdsk
|
||||
move.b R7,R0
|
||||
ext.w R0
|
||||
muls #26,R0
|
||||
move.l R0,R13
|
||||
add.l #_dphtab,R13
|
||||
tst.b 11(R14)
|
||||
bne L71
|
||||
move.l #_cnvdsk,R0
|
||||
move _setdsk,R1
|
||||
ext.l R1
|
||||
add.l R1,R0
|
||||
move.l R0,R8
|
||||
move.b (R8),3+_hmpack
|
||||
move.b #48,4+_hmpack
|
||||
move.b #2,5+_hmpack
|
||||
move.b #6,$ff0183
|
||||
tst.b $ff0101
|
||||
beq L72
|
||||
move.l #L73,(sp)
|
||||
jsr _bioserr
|
||||
bra L74
|
||||
L72:
|
||||
move #7,(sp)
|
||||
move.l #_hmpack,-(sp)
|
||||
jsr _sendpkt
|
||||
add #4,sp
|
||||
L74:L76:
|
||||
cmp #1,_dskstate
|
||||
bne L75
|
||||
bra L76
|
||||
L75:
|
||||
cmp #2,_dskstate
|
||||
bne L77
|
||||
move.l #L78,(sp)
|
||||
jsr _bioserr
|
||||
L77:L80:
|
||||
cmp #3,_dskstate
|
||||
bne L79
|
||||
bra L80
|
||||
L79:
|
||||
move.b $ff019d,R6
|
||||
move.b R6,R0
|
||||
ext.w R0
|
||||
bra L82
|
||||
L83:
|
||||
move.l #_dpb0,14(R13)
|
||||
bra L81
|
||||
L84:
|
||||
move.l #_dpb1,14(R13)
|
||||
bra L81
|
||||
L85:
|
||||
move.l #L86,(sp)
|
||||
jsr _bioserr
|
||||
bra L81
|
||||
bra L81
|
||||
L82:cmp #3,R0
|
||||
beq L83
|
||||
cmp #7,R0
|
||||
beq L84
|
||||
bra L85
|
||||
L81:L71:
|
||||
move.l R13,R0
|
||||
bra L69
|
||||
L69:tst.l (sp)+
|
||||
movem.l (sp)+,R6-R7/R13-R13
|
||||
unlk R14
|
||||
rts
|
||||
.globl _biosinit
|
||||
.text
|
||||
_biosinit:
|
||||
~~biosinit:
|
||||
link R14,#-4
|
||||
move.l #$ffee011,(sp)
|
||||
jsr _portinit
|
||||
move.l #$ffee015,(sp)
|
||||
jsr _portinit
|
||||
L87:unlk R14
|
||||
rts
|
||||
.globl _bios
|
||||
.text
|
||||
_bios:
|
||||
~~bios:
|
||||
~d0=8
|
||||
~d1=10
|
||||
~d2=14
|
||||
link R14,#-4
|
||||
move 8(R14),R0
|
||||
bra L90
|
||||
L91:
|
||||
jsr _init
|
||||
bra L89
|
||||
L92:
|
||||
jsr _wboot
|
||||
bra L89
|
||||
L93:
|
||||
move.l #$ffee011,(sp)
|
||||
jsr _portstat
|
||||
ext.l R0
|
||||
bra L88
|
||||
bra L89
|
||||
L94:
|
||||
move.l #$ffee011,(sp)
|
||||
jsr _portin
|
||||
ext.l R0
|
||||
bra L88
|
||||
bra L89
|
||||
L95:
|
||||
move.l 10(R14),R0
|
||||
move R0,(sp)
|
||||
move.l #$ffee011,-(sp)
|
||||
jsr _portout
|
||||
add #4,sp
|
||||
bra L89
|
||||
L96:L97:
|
||||
move.l 10(R14),R0
|
||||
move R0,(sp)
|
||||
move.l #$ffee015,-(sp)
|
||||
jsr _portout
|
||||
add #4,sp
|
||||
bra L89
|
||||
L98:
|
||||
move.l #$ffee015,(sp)
|
||||
jsr _portin
|
||||
ext.l R0
|
||||
bra L88
|
||||
bra L89
|
||||
L99:
|
||||
clr _settrk
|
||||
bra L89
|
||||
L100:
|
||||
move.l 14(R14),R0
|
||||
move R0,(sp)
|
||||
move.l 10(R14),R0
|
||||
move R0,-(sp)
|
||||
jsr _seldsk
|
||||
add #2,sp
|
||||
bra L88
|
||||
bra L89
|
||||
L101:
|
||||
move.l 10(R14),R0
|
||||
move R0,_settrk
|
||||
bra L89
|
||||
L102:
|
||||
move.l 10(R14),R0
|
||||
move R0,_setsec
|
||||
bra L89
|
||||
L103:
|
||||
move.l 10(R14),_setdma
|
||||
bra L89
|
||||
L104:
|
||||
jsr _read
|
||||
ext.l R0
|
||||
bra L88
|
||||
bra L89
|
||||
L105:
|
||||
move.l 10(R14),R0
|
||||
move R0,(sp)
|
||||
jsr _write
|
||||
ext.l R0
|
||||
bra L88
|
||||
bra L89
|
||||
L106:
|
||||
move.l #$ffee015,(sp)
|
||||
jsr _portstat
|
||||
ext.l R0
|
||||
bra L88
|
||||
bra L89
|
||||
L107:
|
||||
move.l 14(R14),(sp)
|
||||
move.l 10(R14),R0
|
||||
move R0,-(sp)
|
||||
jsr _sectran
|
||||
add #2,sp
|
||||
ext.l R0
|
||||
bra L88
|
||||
bra L89
|
||||
L108:
|
||||
move.l #_memtab,R0
|
||||
bra L88
|
||||
bra L89
|
||||
L109:
|
||||
move _iobyte,R0
|
||||
ext.l R0
|
||||
bra L88
|
||||
bra L89
|
||||
L110:
|
||||
move.l 10(R14),R0
|
||||
move R0,_iobyte
|
||||
bra L89
|
||||
L111:
|
||||
jsr _flush
|
||||
ext.l R0
|
||||
bra L88
|
||||
bra L89
|
||||
L112:
|
||||
move.l 14(R14),(sp)
|
||||
move.l 10(R14),R0
|
||||
move R0,-(sp)
|
||||
jsr _setxvect
|
||||
add #2,sp
|
||||
bra L88
|
||||
bra L89
|
||||
bra L89
|
||||
L90:cmp #22,R0
|
||||
bhi L89
|
||||
asl #2,R0
|
||||
move R0,R8
|
||||
add.l #L113,R8
|
||||
move.l (R8),R8
|
||||
jmp (R8)
|
||||
.data
|
||||
L113:.dc.l L91
|
||||
.dc.l L92
|
||||
.dc.l L93
|
||||
.dc.l L94
|
||||
.dc.l L95
|
||||
.dc.l L96
|
||||
.dc.l L97
|
||||
.dc.l L98
|
||||
.dc.l L99
|
||||
.dc.l L100
|
||||
.dc.l L101
|
||||
.dc.l L102
|
||||
.dc.l L103
|
||||
.dc.l L104
|
||||
.dc.l L105
|
||||
.dc.l L106
|
||||
.dc.l L107
|
||||
.dc.l L89
|
||||
.dc.l L108
|
||||
.dc.l L109
|
||||
.dc.l L110
|
||||
.dc.l L111
|
||||
.dc.l L112
|
||||
.text
|
||||
L89:L88:unlk R14
|
||||
rts
|
||||
.data
|
||||
L11:.dc.b 10,13,66,73,79,83,32,69,82,82,79,82,32,45,45,32,0
|
||||
L12:.dc.b 46,10,13,0
|
||||
L31:.dc.b 69,120,112,101,99,116,101,100,32,65,67,75,32,111,114,32,78,65,75,0
|
||||
L35:.dc.b 69,120,112,101,99,116,101,100,32,115,116,97,116,117,115,32,112,97,99,107,101,116,32,102,114,111,109,32,73,80,67,0
|
||||
L41:.dc.b 78,65,75,32,102,114,111,109,32,73,80,67,0
|
||||
L49:.dc.b 78,65,75,32,102,114,111,109,32,73,80,67,0
|
||||
L73:.dc.b 69,82,82,32,54,0
|
||||
L78:.dc.b 78,65,75,32,102,114,111,109,32,73,80,67,0
|
||||
L86:.dc.b 69,82,82,32,55,0
|
@@ -0,0 +1,49 @@
|
||||
.text
|
||||
.globl _init
|
||||
.globl _wboot
|
||||
.globl _bios
|
||||
.globl _dskia
|
||||
.globl _dskic
|
||||
.globl _setimask
|
||||
*
|
||||
ccp = $18000 ccp entry point
|
||||
rtp = $1dc00 rtp entry point
|
||||
*
|
||||
_init: lea entry,a0
|
||||
move.l a0,$8C
|
||||
lea _dskia,a0
|
||||
move.l a0,$3fc
|
||||
clr.l d0
|
||||
move.l #rtp,$84 setup rtp trap
|
||||
move #$2000,sr
|
||||
jmp ccp
|
||||
*
|
||||
_wboot: clr.l d0
|
||||
jmp ccp
|
||||
*
|
||||
entry: move.l d2,-(a7)
|
||||
move.l d1,-(a7)
|
||||
move.w d0,-(a7)
|
||||
jsr _bios
|
||||
add #10,a7
|
||||
rte
|
||||
*
|
||||
_dskia: link a6,#0
|
||||
movem.l d0-d7/a0-a5,-(a7)
|
||||
jsr _dskic
|
||||
movem.l (a7)+,d0-d7/a0-a5
|
||||
unlk a6
|
||||
rte
|
||||
*
|
||||
_setimask: move sr,d0
|
||||
lsr #8,d0
|
||||
and.l #7,d0
|
||||
move sr,d1
|
||||
ror.w #8,d1
|
||||
and.w #$fff8,d1
|
||||
add.w 4(a7),d1
|
||||
ror.w #8,d1
|
||||
move d1,sr
|
||||
rts
|
||||
*
|
||||
.end
|
850
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/savebios.c
Normal file
850
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bios/savebios.c
Normal file
@@ -0,0 +1,850 @@
|
||||
/*=======================================================================*/
|
||||
/*/---------------------------------------------------------------------\*/
|
||||
/*| |*/
|
||||
/*| CP/M-68K(tm) BIOS for the EXORMACS |*/
|
||||
/*| |*/
|
||||
/*| Copyright 1982, Digital Research. |*/
|
||||
/*| |*/
|
||||
/*\---------------------------------------------------------------------/*/
|
||||
/*=======================================================================*/
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#define TRACEPORT 0xffee015
|
||||
|
||||
#include "[bill.cpm68k.csupport]stdtypes.h"
|
||||
|
||||
char copyright[] = "Copyright 1982, Digital Research";
|
||||
|
||||
struct memb { BYTE byte; };
|
||||
struct memw { WORD word; };
|
||||
struct meml { LONG lword;};
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* I/O Device Definitions */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Define the two ACIA ports on the DEBUG board */
|
||||
/************************************************************************/
|
||||
|
||||
#define PORT1 0xFFEE011
|
||||
#define PORT2 0xFFEE015
|
||||
|
||||
#define PORTCTRL 0
|
||||
#define PORTSTAT 0
|
||||
#define PORTRDR 2
|
||||
#define PORTTDR 2
|
||||
|
||||
#define PORTRSET 3
|
||||
#define PORTINIT 0x11
|
||||
|
||||
#define PORTRDRF 1
|
||||
#define PORTTDRE 2
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Define Disk I/O Addresses and Related Constants */
|
||||
/************************************************************************/
|
||||
|
||||
#define DSKIPC 0xFF0000 /* IPC Base Address */
|
||||
|
||||
#define DSKINTV 0x3FC /* Address of Disk Interrupt Vector */
|
||||
|
||||
#define INTTOIPC 0xD /* offsets */
|
||||
#define RSTTOIPC 0xF
|
||||
#define MSGTOIPC 0x101
|
||||
#define ACKTOIPC 0x103
|
||||
#define PKTTOIPC 0x105
|
||||
#define MSGFMIPC 0x181
|
||||
#define ACKFMIPC 0x183
|
||||
#define PKTFMIPC 0x185
|
||||
|
||||
#define DSKREAD 0x10
|
||||
#define DSKWRITE 0x20
|
||||
|
||||
#define STX 0x02
|
||||
#define ETX 0x03
|
||||
#define ACK 0x06
|
||||
#define NAK 0x15
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* BIOS Table Definitions */
|
||||
/************************************************************************/
|
||||
|
||||
struct dpb
|
||||
{
|
||||
WORD spt;
|
||||
BYTE bsh;
|
||||
BYTE blm;
|
||||
BYTE exm;
|
||||
BYTE dpbjunk;
|
||||
WORD dsm;
|
||||
WORD drm;
|
||||
BYTE al0;
|
||||
BYTE al1;
|
||||
WORD cks;
|
||||
WORD off;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct dph
|
||||
{
|
||||
BYTE *xltp;
|
||||
WORD dphscr[3];
|
||||
BYTE *dirbufp;
|
||||
struct dpb *dpbp;
|
||||
BYTE *csvp;
|
||||
BYTE *alvp;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Directory Buffer for use by the BDOS */
|
||||
/************************************************************************/
|
||||
|
||||
BYTE dirbuf[128];
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* CSV's */
|
||||
/************************************************************************/
|
||||
|
||||
BYTE csv0[16];
|
||||
BYTE csv1[16];
|
||||
BYTE csv2[16];
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* ALV's */
|
||||
/************************************************************************/
|
||||
|
||||
BYTE alv0[32]; /* (dsm0 / 8) + 1 */
|
||||
BYTE alv1[32]; /* (dsm1 / 8) + 1 */
|
||||
BYTE alv2[2002]; /* (dsm2 / 8) + 1 */
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Disk Parameter Blocks */
|
||||
/************************************************************************/
|
||||
|
||||
/* The following dpb definitions express the intent of the writer, */
|
||||
/* unfortunately, due to a compiler bug, these lines cannot be used. */
|
||||
/* Therefore, the obscure code following them has been inserted. */
|
||||
|
||||
/************* spt, bsh, blm, exm, jnk, dsm, drm, al0, al1, cks, off
|
||||
|
||||
struct dpb dpb0={ 26, 3, 7, 0, 0, 242, 63, 0xC0, 0, 16, 2};
|
||||
struct dpb dpb1={ 26, 4, 15, 0, 0, 242, 63, 0xC0, 0, 16, 2};
|
||||
struct dpb dpb2={ 26, 3, 7, 0, 0, 16008, 63, 0xC0, 0, 16, 2};
|
||||
|
||||
********** end of readable definitions *************/
|
||||
|
||||
/* The Alcyon C compiler assumes all structures are arrays of int, so */
|
||||
/* in the following definitions, adjacent pairs of chars have been */
|
||||
/* combined into int constants --- what a kludge! **********************/
|
||||
|
||||
struct dpb dpb0 = { 26, 775, 0, 242, 63, -16384, 16, 2 };
|
||||
struct dpb dpb1 = { 26, 1039, 0, 242, 63, -16384, 16, 2 };
|
||||
struct dpb dpb2 = { 26, 775, 0, 16008, 63, -16384, 16, 2 };
|
||||
|
||||
/*************** End of kludge *****************/
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Sector Translate Table */
|
||||
/************************************************************************/
|
||||
|
||||
BYTE xlt[26] = { 1, 7, 13, 19, 25, 5, 11, 17, 23, 3, 9, 15, 21,
|
||||
2, 8, 14, 20, 26, 6, 12, 18, 24, 4, 10, 16, 22 };
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Disk Parameter Headers */
|
||||
/* */
|
||||
/* Four disks are defined : dsk a: diskno=0, dev name=#fd04 */
|
||||
/* dsk b: diskno=1, dev name=#fd05 */
|
||||
/* dsk c: diskno=2, dev name=#hd00 */
|
||||
/* dsk d: diskno=3, dev name=#hd01 */
|
||||
/************************************************************************/
|
||||
|
||||
struct dph dphtab[4] =
|
||||
{ {&xlt, 0, 0, 0, &dirbuf, &dpb0, &csv0, &alv0}, /*dsk a*/
|
||||
{&xlt, 0, 0, 0, &dirbuf, &dpb0, &csv1, &alv1}, /*dsk b*/
|
||||
{ 0L, 0, 0, 0, &dirbuf, &dpb2, &csv2, &alv2}, /*dsk c*/
|
||||
{ 0L, 0, 0, 0, &dirbuf, &dpb2, &csv2, &alv2}, /*dsk d*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Memory Region Table */
|
||||
/************************************************************************/
|
||||
|
||||
struct mrt { WORD count;
|
||||
LONG tpalow;
|
||||
LONG tpalen;
|
||||
}
|
||||
memtab = { 1, 0x0002,0x0000, 0x0003,0xfff0 };/* kludge init by int */
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* IOBYTE */
|
||||
/************************************************************************/
|
||||
|
||||
WORD iobyte;
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Currently Selected Disk Stuff */
|
||||
/************************************************************************/
|
||||
|
||||
WORD settrk, setsec, setdsk;
|
||||
BYTE *setdma;
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Track Buffering Definitions and Variables */
|
||||
/************************************************************************/
|
||||
|
||||
#define NUMTB 10 /* must be at least 3 for some algorithms */
|
||||
|
||||
struct tbstr {
|
||||
struct tbstr *nextbuf;
|
||||
BYTE buf[26*128];
|
||||
WORD dsk;
|
||||
WORD trk;
|
||||
BYTE valid;
|
||||
BYTE dirty;
|
||||
};
|
||||
|
||||
struct tbstr *firstbuf;
|
||||
struct tbstr *lastbuf;
|
||||
|
||||
struct tbstr tbuf[NUMTB];
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Disk I/O Packets for the UDC and other Disk I/O Variables */
|
||||
/************************************************************************/
|
||||
|
||||
struct hmpkst {
|
||||
BYTE a1;
|
||||
BYTE a2;
|
||||
BYTE a3;
|
||||
BYTE dskno;
|
||||
BYTE com1;
|
||||
BYTE com2;
|
||||
BYTE a6;
|
||||
BYTE a7;
|
||||
}
|
||||
hmpack = { 512, 1792, 0, 768 }; /* kludge init by words */
|
||||
|
||||
|
||||
struct rwpkst {
|
||||
BYTE stxchr;
|
||||
BYTE pktid;
|
||||
BYTE pktsize;
|
||||
BYTE dskno;
|
||||
BYTE chcmd;
|
||||
BYTE devcmd;
|
||||
WORD numblks;
|
||||
WORD blksize;
|
||||
LONG iobf;
|
||||
WORD cksum;
|
||||
LONG lsect;
|
||||
BYTE etxchr;
|
||||
BYTE rwpad;
|
||||
};
|
||||
|
||||
struct rwpkst rwpack = { 512, 5376, 4097, 13, 256, 0, 0, 0, 0, 0, 768 };
|
||||
|
||||
|
||||
BYTE cnvdsk[4] = { 4, 5, 0, 1 }; /* convert from CP/M dsk # to Exormacs */
|
||||
|
||||
#define MAXDSK 3
|
||||
|
||||
|
||||
#define DSKIDLE 0
|
||||
#define MSGSENT 1
|
||||
#define NAKRCVD 2
|
||||
#define ACKRCVD 3
|
||||
#define IODONE 4
|
||||
#define DSKERROR 5
|
||||
|
||||
|
||||
WORD dskstate = DSKIDLE;
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Generic Serial Port I/O Procedures */
|
||||
/************************************************************************/
|
||||
|
||||
portinit(port)
|
||||
REG BYTE *port;
|
||||
{
|
||||
*(port + PORTCTRL) = PORTRSET;
|
||||
*(port + PORTCTRL) = PORTINIT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
portstat(port)
|
||||
REG BYTE *port;
|
||||
{
|
||||
return ( *(port + PORTSTAT) & PORTRDRF) == PORTRDRF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BYTE portin(port)
|
||||
REG BYTE *port;
|
||||
{
|
||||
while (portstat(port) == 0) ;
|
||||
return *(port + PORTRDR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
portout(port, ch)
|
||||
REG BYTE *port;
|
||||
REG BYTE ch;
|
||||
{
|
||||
while ( (*(port + PORTSTAT) & PORTTDRE) != PORTTDRE) ;
|
||||
*(port + PORTTDR) = ch;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Error procedure for BIOS */
|
||||
/************************************************************************/
|
||||
|
||||
bioserr(errmsg)
|
||||
REG BYTE *errmsg;
|
||||
{
|
||||
printstr("\n\rBIOS ERROR -- ");
|
||||
printstr(errmsg);
|
||||
printstr(".\n\r");
|
||||
}
|
||||
|
||||
printstr(s) /* used by bioserr */
|
||||
REG BYTE *s;
|
||||
{
|
||||
while (*s) {portout(PORT1,*s); s += 1; };
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
||||
printrace(s)
|
||||
REG BYTE *s;
|
||||
{
|
||||
while (*s) {portout(TRACEPORT, *s); s += 1;}
|
||||
}
|
||||
|
||||
printnum(n)
|
||||
REG LONG n;
|
||||
{
|
||||
REG WORD i;
|
||||
REG BYTE d;
|
||||
|
||||
i = 32;
|
||||
|
||||
while (i)
|
||||
{
|
||||
i -= 4;
|
||||
d = (n >> i) & 0x0fL;
|
||||
if ( d <= '9' ) d = d + '0';
|
||||
else d = d - 10 + 'a';
|
||||
portout(TRACEPORT, d);
|
||||
}
|
||||
portout(TRACEPORT, ' ');
|
||||
}
|
||||
|
||||
|
||||
printds(ds)
|
||||
WORD ds;
|
||||
{
|
||||
switch(ds){
|
||||
case DSKIDLE: printrace("DSKIDLE");
|
||||
break;
|
||||
case MSGSENT: printrace("MSGSENT");
|
||||
break;
|
||||
case NAKRCVD: printrace("NAKRCVD");
|
||||
break;
|
||||
case ACKRCVD: printrace("ACKRCVD");
|
||||
break;
|
||||
case IODONE: printrace("IODONE");
|
||||
break;
|
||||
case DSKERROR: printrace("DSKERROR");
|
||||
break;
|
||||
default: printrace("Invalid");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/************************************************************************/
|
||||
/* Disk I/O Procedures */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
EXTERN dskia();
|
||||
EXTERN setimask();
|
||||
|
||||
dskic()
|
||||
{
|
||||
/* Disk Interrupt Handler -- C Language Portion */
|
||||
|
||||
#if DEBUG
|
||||
|
||||
printrace("\n\rDisk Interrupt ");
|
||||
printds(dskstate);
|
||||
printrace("->");
|
||||
|
||||
#endif
|
||||
|
||||
switch ( dskstate )
|
||||
{
|
||||
case DSKIDLE: ;
|
||||
case IODONE: ;
|
||||
case DSKERROR:;
|
||||
case NAKRCVD: {
|
||||
if ( ((DSKIPC+ACKFMIPC)->byte == ACK) ||
|
||||
((DSKIPC+ACKFMIPC)->byte == NAK) )
|
||||
{
|
||||
(DSKIPC+ACKFMIPC)->byte = 0;
|
||||
}
|
||||
|
||||
if ( (DSKIPC+MSGFMIPC)->byte == 0x80 )
|
||||
{
|
||||
(DSKIPC+ACKTOIPC)->byte = ACK;
|
||||
(DSKIPC+MSGFMIPC)->byte = 0;
|
||||
(DSKIPC+INTTOIPC)->byte = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSGSENT: {
|
||||
if ( (DSKIPC+ACKFMIPC)->byte == ACK )
|
||||
{
|
||||
(DSKIPC+ACKFMIPC)->byte = 0;
|
||||
dskstate = ACKRCVD;
|
||||
}
|
||||
else if ( (DSKIPC+ACKFMIPC)->byte == NAK )
|
||||
{
|
||||
(DSKIPC+ACKFMIPC)->byte = 0;
|
||||
dskstate = NAKRCVD;
|
||||
}
|
||||
else
|
||||
{
|
||||
bioserr("Expected ACK or NAK");
|
||||
dskstate = DSKERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (DSKIPC+MSGFMIPC)->byte == 0x80 )
|
||||
{ dskstate = IODONE; }
|
||||
}
|
||||
break;
|
||||
|
||||
case ACKRCVD: {
|
||||
if ( (DSKIPC+MSGFMIPC)->byte != 0x80 )
|
||||
{ bioserr("Expected status packet from IPC");}
|
||||
else dskstate = IODONE;
|
||||
|
||||
(DSKIPC+MSGFMIPC)->byte = 0;
|
||||
(DSKIPC+ACKTOIPC)->byte = ACK;
|
||||
(DSKIPC+INTTOIPC)->byte = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
printds(dskstate);
|
||||
printrace("\n\r");
|
||||
#endif
|
||||
|
||||
} /* end of dskic */
|
||||
|
||||
|
||||
sendpkt(pktadr, pktsize)
|
||||
REG BYTE *pktadr;
|
||||
REG WORD pktsize;
|
||||
{
|
||||
REG BYTE *iopackp;
|
||||
REG WORD imsave;
|
||||
|
||||
while ( (DSKIPC+MSGTOIPC)->byte ); /* wait til ready */
|
||||
if ( (DSKIPC+ACKFMIPC)->byte == NAK ) bioserr("NAK from IPC");
|
||||
(DSKIPC+ACKFMIPC)->byte = 0;
|
||||
(DSKIPC+MSGFMIPC)->byte = 0;
|
||||
iopackp = (DSKIPC+PKTTOIPC);
|
||||
do {*iopackp = *pktadr++; iopackp += 2; pktsize -= 1;} while(pktsize);
|
||||
(DSKIPC+MSGTOIPC)->byte = 0x80;
|
||||
imsave = setimask(7);
|
||||
dskstate = MSGSENT;
|
||||
(DSKIPC+INTTOIPC)->byte = 0;
|
||||
setimask(imsave);
|
||||
}
|
||||
|
||||
|
||||
dskxfer(dsk, trk, bufp, cmd)
|
||||
REG WORD dsk, trk, cmd;
|
||||
REG BYTE *bufp;
|
||||
{
|
||||
/* build packet */
|
||||
rwpack.dskno = cnvdsk[dsk];
|
||||
rwpack.iobf = bufp;
|
||||
rwpack.lsect = trk * 13;
|
||||
rwpack.chcmd = cmd;
|
||||
sendpkt(&rwpack, 21);
|
||||
while (dskstate == MSGSENT); /* wait */
|
||||
if (dskstate == NAKRCVD) bioserr("NAK from IPC");
|
||||
while (dskstate == ACKRCVD); /* wait */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
flush1(tbp)
|
||||
REG struct tbstr *tbp;
|
||||
{
|
||||
if ( tbp->valid && tbp->dirty )
|
||||
dskxfer(tbp->dsk, tbp->trk, tbp->buf, DSKWRITE);
|
||||
|
||||
tbp->dirty = 0;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
flush()
|
||||
{
|
||||
REG struct tbstr *tbp;
|
||||
|
||||
tbp = firstbuf;
|
||||
while (tbp)
|
||||
{
|
||||
flush1(tbp);
|
||||
tbp = tbp->nextbuf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fill(tbp)
|
||||
REG struct tbstr *tbp;
|
||||
{
|
||||
|
||||
if ( tbp->valid && tbp->dirty ) flush1(tbp);
|
||||
|
||||
dskxfer(setdsk, settrk, tbp->buf, DSKREAD);
|
||||
|
||||
tbp->valid = 1;
|
||||
tbp->dirty = 0;
|
||||
tbp->trk = settrk;
|
||||
tbp->dsk = setdsk;
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct tbstr *gettrk()
|
||||
{
|
||||
REG struct tbstr *tbp;
|
||||
REG struct tbstr *ltbp;
|
||||
REG struct tbstr *mtbp;
|
||||
|
||||
tbp = firstbuf;
|
||||
ltbp = 0;
|
||||
mtbp = 0;
|
||||
|
||||
while (tbp)
|
||||
{
|
||||
if ( (tbp->valid) && (tbp->dsk == setdsk)
|
||||
&& (tbp->trk == settrk) )
|
||||
{
|
||||
if (ltbp)
|
||||
{
|
||||
ltbp->nextbuf = tbp->nextbuf;
|
||||
tbp->nextbuf = firstbuf;
|
||||
firstbuf = tbp;
|
||||
}
|
||||
return tbp;
|
||||
}
|
||||
else
|
||||
{
|
||||
mtbp = ltbp;
|
||||
ltbp = tbp;
|
||||
tbp = tbp->nextbuf;
|
||||
}
|
||||
}
|
||||
|
||||
if (mtbp) mtbp->nextbuf = 0; /* detach lru buffer */
|
||||
if ( (! firstbuf->valid) ||
|
||||
(firstbuf->trk > dphtab[firstbuf->dsk].dpbp->off) ) /* dir trk? */
|
||||
{
|
||||
ltbp->nextbuf = firstbuf;
|
||||
firstbuf = ltbp;
|
||||
}
|
||||
else
|
||||
{
|
||||
ltbp->nextbuf = firstbuf->nextbuf;
|
||||
firstbuf->nextbuf = ltbp;
|
||||
}
|
||||
flush1(ltbp);
|
||||
fill(ltbp);
|
||||
return ltbp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
read()
|
||||
{
|
||||
REG BYTE *p;
|
||||
REG BYTE *q;
|
||||
REG WORD i;
|
||||
REG struct tbstr *tbp;
|
||||
|
||||
tbp = gettrk();
|
||||
p = (tbp->buf) + ((setsec-1) << 7); /* multiply by shifting */
|
||||
q = setdma;
|
||||
i = 128;
|
||||
do {*q++ = *p++; i -= 1;} while (i);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
write(mode)
|
||||
BYTE mode;
|
||||
{
|
||||
REG BYTE *p;
|
||||
REG BYTE *q;
|
||||
REG WORD i;
|
||||
REG struct tbstr *tbp;
|
||||
|
||||
tbp = gettrk();
|
||||
p = (tbp->buf) + ((setsec-1) << 7); /* multiply by shifting */
|
||||
q = setdma;
|
||||
i = 128;
|
||||
if ( (mode != 1) || (tbp->dirty) ) /* normal case */
|
||||
{
|
||||
do {*p++ = *q++; i -= 1;} while (i);
|
||||
tbp->dirty = 1;
|
||||
}
|
||||
else /* for dir write, only mark dirty if changed. */
|
||||
{
|
||||
do
|
||||
{
|
||||
if (*p != *q) tbp->dirty=1;
|
||||
*p++ = *q++;
|
||||
i -= 1;
|
||||
}
|
||||
while (i);
|
||||
}
|
||||
if ( mode == 1 ) flush();
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
BYTE sectran(s, xp)
|
||||
WORD s;
|
||||
BYTE *xp;
|
||||
{
|
||||
return xp[s];
|
||||
}
|
||||
|
||||
|
||||
LONG setxvect(vnum, vval)
|
||||
WORD vnum;
|
||||
LONG vval;
|
||||
{
|
||||
REG LONG oldval;
|
||||
REG BYTE *vloc;
|
||||
|
||||
vloc = ( (long)vnum ) << 2;
|
||||
oldval = vloc->lword;
|
||||
vloc->lword = vval;
|
||||
|
||||
return(oldval);
|
||||
|
||||
}
|
||||
|
||||
|
||||
LONG seldsk(dsk, logged)
|
||||
REG BYTE dsk;
|
||||
BYTE logged;
|
||||
{
|
||||
REG struct dph *dphp;
|
||||
REG BYTE check;
|
||||
|
||||
if (dsk > MAXDSK) return(0L);
|
||||
setdsk = dsk;
|
||||
dphp = &dphtab[dsk];
|
||||
if ( ! logged )
|
||||
{
|
||||
|
||||
hmpack.dskno = cnvdsk[setdsk];
|
||||
hmpack.com1 = 0x30;
|
||||
hmpack.com2 = 0x02;
|
||||
(DSKIPC+ACKFMIPC)->byte = 6;
|
||||
if ( (DSKIPC+MSGTOIPC)->byte ) {bioserr("ERR 6"); return 0L;}
|
||||
else sendpkt(&hmpack, 7);
|
||||
while ( dskstate == MSGSENT ); /* wait */
|
||||
if (dskstate == NAKRCVD) {bioserr("NAK from IPC"); return 0L;}
|
||||
while ( dskstate == ACKRCVD ); /* wait */
|
||||
check = (DSKIPC+PKTFMIPC+0x18)->byte;
|
||||
switch ( check )
|
||||
{
|
||||
case 3: dphp->dpbp = &dpb0;
|
||||
break;
|
||||
|
||||
case 7: dphp->dpbp = &dpb1;
|
||||
break;
|
||||
|
||||
default: {bioserr("ERR 7"); return 0L;}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(dphp);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* BIOS PROPER */
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
biosinit()
|
||||
{
|
||||
REG WORD i;
|
||||
|
||||
portinit(PORT1);
|
||||
portinit(PORT2);
|
||||
for ( i = 0; i < NUMTB; ++i )
|
||||
{
|
||||
tbuf[i].valid = 0;
|
||||
tbuf[i].dirty = 0;
|
||||
if ( (i+1) < NUMTB ) tbuf[i].nextbuf = &tbuf[i+1];
|
||||
else tbuf[i].nextbuf = 0;
|
||||
}
|
||||
firstbuf = &tbuf[0];
|
||||
lastbuf = &tbuf[NUMTB-1];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
LONG bios(d0, d1, d2)
|
||||
WORD d0;
|
||||
LONG d1, d2;
|
||||
{
|
||||
|
||||
#if DEBUG
|
||||
|
||||
if ( d0 > 7) {
|
||||
printrace("\n\rBIOS( ");
|
||||
printnum((long)d0);
|
||||
printnum(d1);
|
||||
printnum(d2);
|
||||
printrace(")\n\r");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
switch(d0)
|
||||
{
|
||||
case 0: init(); /* INIT */
|
||||
break;
|
||||
|
||||
case 1: wboot(); /* WBOOT */
|
||||
break;
|
||||
|
||||
case 2: return(portstat(PORT1)); /* CONST */
|
||||
break;
|
||||
|
||||
case 3: return(portin(PORT1)); /* CONIN */
|
||||
break;
|
||||
|
||||
case 4: portout(PORT1, (char)d1); /* CONOUT */
|
||||
break;
|
||||
|
||||
case 5: ; /* LIST */
|
||||
case 6: portout(PORT2, (char)d1); /* PUNCH */
|
||||
break;
|
||||
|
||||
case 7: return(portin(PORT2)); /* READER */
|
||||
break;
|
||||
|
||||
case 8: settrk = 0; /* HOME */
|
||||
break;
|
||||
|
||||
case 9: return(seldsk((char)d1, (char)d2)); /* SELDSK */
|
||||
break;
|
||||
|
||||
case 10: settrk = (int)d1; /* SETTRK */
|
||||
break;
|
||||
|
||||
case 11: setsec = (int)d1; /* SETSEC */
|
||||
break;
|
||||
|
||||
case 12: setdma = d1; /* SETDMA */
|
||||
break;
|
||||
|
||||
case 13: return(read()); /* READ */
|
||||
break;
|
||||
|
||||
case 14: return(write((char)d1)); /* WRITE */
|
||||
break;
|
||||
|
||||
case 15: return(portstat(PORT2)); /* LISTST */
|
||||
break;
|
||||
|
||||
case 16: return(sectran((int)d1, d2)); /* SECTRAN */
|
||||
break;
|
||||
|
||||
case 18: return(&memtab); /* GMRTA */
|
||||
break;
|
||||
|
||||
case 19: return(iobyte); /* GETIOB */
|
||||
break;
|
||||
|
||||
case 20: iobyte = (int)d1; /* SETIOB */
|
||||
break;
|
||||
|
||||
case 21: return(flush()); /* FLUSH */
|
||||
break;
|
||||
|
||||
case 22: return(setxvect((int)d1,d2)); /* SETXVECT */
|
||||
break;
|
||||
|
||||
|
||||
|
||||
} /* end switch */
|
||||
|
||||
|
||||
} /* end bios procedure */
|
||||
|
||||
|
||||
|
||||
/* End of C Bios */
|
@@ -0,0 +1,23 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Definitions for use with C programs */
|
||||
/* according to CP/M-68K (tm) standard */
|
||||
/* coding practices */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
#define LONG long
|
||||
#define ULONG unsigned long
|
||||
#define WORD short int
|
||||
#define UWORD unsigned short
|
||||
#define BYTE char
|
||||
#define UBYTE unsigned char
|
||||
#define VOID
|
||||
|
||||
#define REG register
|
||||
#define LOCAL auto
|
||||
#define MLOCAL static
|
||||
#define GLOBAL extern
|
||||
#define EXTERN extern
|
||||
|
||||
/************************************************/
|
Reference in New Issue
Block a user