mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 17:34:06 +00:00
Upload
Digital Research
This commit is contained in:
452
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/doc/rsx.doc
Normal file
452
CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/doc/rsx.doc
Normal file
@@ -0,0 +1,452 @@
|
||||
CP/M-68K RSX IMPLEMENTATION ON CP/M-68K V1.0
|
||||
==============================
|
||||
|
||||
|
||||
A resident system extension under CP/M-68K consists of a block
|
||||
|
||||
of memory permanently set aside to hold a program and an executable,
|
||||
|
||||
relocatable program which can be accessed via a trap call. The RSX may reside
|
||||
|
||||
anywhere outside the TPA(transient program area) and CP/M itself. This
|
||||
|
||||
block of memory is created by use of the BDOS call: Get/Set TPA limits.
|
||||
|
||||
The current boundries of the TPA are re-defined to leave a section of
|
||||
|
||||
memory available to permanently hold the RSX. Here is a typical memory
|
||||
|
||||
model with an existing RSX.
|
||||
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
| |
|
||||
| BIOS |
|
||||
| |
|
||||
-------------------------------------------------
|
||||
| |
|
||||
| BDOS |
|
||||
| |
|
||||
-------------------------------------------------
|
||||
| |
|
||||
| CCP |
|
||||
| |
|
||||
Old Top of -------------------------------------------------
|
||||
TPA | |
|
||||
| RSX |
|
||||
| |
|
||||
New Top of -------------------------------------------------
|
||||
TPA | |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| TPA |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
Base of TPA -------------------------------------------------
|
||||
| |
|
||||
| Reserved for CP/M-68K |
|
||||
| |
|
||||
-------------------------------------------------
|
||||
|
||||
|
||||
CP/M-68K RSX IMPLEMENTATION ON CP/M-68K V1.0
|
||||
==============================
|
||||
|
||||
|
||||
The bdos program load function is used to load the RSX program into
|
||||
|
||||
memory. The set exception vector function should then be used to reset a
|
||||
|
||||
trap vector address to the beginning of the RSX. All access to the RSX
|
||||
|
||||
should be done via a trap call. This type of access will allow the RSX to
|
||||
|
||||
operate in supervisor mode. Return from the RSX is then accomplished by
|
||||
|
||||
using the RTE instruction. To eliminate the RSX,use the Get/Set TPA limits
|
||||
|
||||
function to re-define the TPA to its original configuration. Reset the trap
|
||||
|
||||
vector address to its orginal value. The following is an example of a
|
||||
|
||||
transient program that loads other transient programs as RSX's,reconfigures
|
||||
|
||||
the TPA,and passes control to the new RSX for initialization. The RSX
|
||||
|
||||
initialization should set an exception vector address to the beginning of
|
||||
|
||||
the desired code segment in the RSX,and pass control back to the rsx loader
|
||||
|
||||
via an RTS(return from subroutine) instruction. The RSX is now accessable via
|
||||
|
||||
a trap call. The rsx loader can load other RSX's right below the existing RSX.
|
||||
|
||||
The command:
|
||||
|
||||
A>rsx $
|
||||
|
||||
will cause the rsx loader to reset the TPA boundries to their coldboot values
|
||||
|
||||
as specified in the BIOS. The RSX should also have a mechanism for reseting
|
||||
|
||||
the modified trap vector to its coldboot value.
|
||||
|
||||
|
||||
*************************************************************************
|
||||
* rsx.s Link to LOADRSX.C v1.0 *
|
||||
* ================= *
|
||||
* *
|
||||
* Assembly Language Module Needed to *
|
||||
* Assist 'C' code to Load a Program as an RSX *
|
||||
* *
|
||||
*************************************************************************
|
||||
|
||||
|
||||
*
|
||||
* Make All these labels GLOBAL
|
||||
*
|
||||
.globl _bdos
|
||||
.globl _push
|
||||
.globl _main
|
||||
.globl _reset
|
||||
.globl _openfile
|
||||
.globl _prt_tpa
|
||||
.globl stack
|
||||
*
|
||||
* Load Parameter Block Labels
|
||||
* ---------------------------
|
||||
.globl _LPB
|
||||
.globl _lowadr
|
||||
.globl _hiadr
|
||||
.globl _baspag
|
||||
.globl _usrstk
|
||||
.globl _flags
|
||||
*
|
||||
* TPA Parameter Block Labels
|
||||
* --------------------------
|
||||
.globl _TPAB
|
||||
.globl _low
|
||||
.globl _high
|
||||
|
||||
prtstr = 9
|
||||
getmemtb = 18
|
||||
settpa = 63
|
||||
|
||||
*
|
||||
* Try to open 1st parsed FCB
|
||||
* --------------------------
|
||||
start: link a6,#0 *link and allocate
|
||||
move.l 8(a6),a0 *get basepage address
|
||||
move.l #stack,a7 *set up my own stack
|
||||
move.l a7,a6 *set up a6
|
||||
lea $5c(a0),a1 *get 1st parsed fcb address
|
||||
move.l a1,-(sp) *push fcb address
|
||||
jsr _openfile *jump to open file routine
|
||||
add.l #4,sp *clean off the stack
|
||||
jsr _main *go to main routine
|
||||
clr.l d0 *prepare to exit program
|
||||
trap #2 *warmboot and return to CCP
|
||||
*
|
||||
*
|
||||
* Push the needed addresses on to the stack
|
||||
* -----------------------------------------
|
||||
*
|
||||
_push:
|
||||
movea.l _usrstk,a7 *set up the user stack pointer
|
||||
move.l _baspag,a1 *get address of user basepage
|
||||
move.l a1,-(sp) *push basepage address
|
||||
move.l #wboot,-(sp) *push return address
|
||||
move.l 8(a1),-(sp) *push address to jump to
|
||||
rts *jump to new program
|
||||
|
||||
*
|
||||
* Call the BDOS
|
||||
* -------------
|
||||
_bdos:
|
||||
move.w 4(sp),d0 *get the BDOS function number
|
||||
move.l 6(sp),d1 *get the BDOS parameter
|
||||
trap #2 *call the BDOS
|
||||
rts *return to calling code
|
||||
*
|
||||
* Reset CP/M-68K TPA limits to original values
|
||||
* --------------------------------------------
|
||||
_reset:
|
||||
move.l #getmemtb,d0 *bios get memory region table
|
||||
trap #3 *call the bios
|
||||
add.l #$2,d0 *skip the count
|
||||
move.l d0,a0 *a0 now points to tpa low address
|
||||
move.l (a0)+,_low *put that address in TPAB
|
||||
move.l (a0),d2 *get length of tpa
|
||||
add.l _low,d2 *calculate top of tpa
|
||||
move.l d2,_high *put that address in TPAB
|
||||
move.w #$FF,_TPAB *make this permanent
|
||||
move.w #settpa,d0 *bdos function # for set tpa limits
|
||||
move.l #_TPAB,d1 *d1 gets address of TPAB
|
||||
trap #2 *call the bdos
|
||||
move.w #prtstr,d0 *bdos function # to print a string
|
||||
move.l #mesg,d1 *get address of string into d1
|
||||
trap #2 *print message by calling bdos
|
||||
move.l #0,-(sp) *push a FALSE value
|
||||
jsr _prt_tpa *print TPA boundries
|
||||
wboot:
|
||||
clr.l d0 *prepare to warmboot
|
||||
trap #2 *call the bdos
|
||||
|
||||
*
|
||||
* DATA
|
||||
*
|
||||
.data
|
||||
.even
|
||||
*
|
||||
* Load Parameter Block
|
||||
*
|
||||
_LPB: .ds.l 1
|
||||
_lowadr: .ds.l 1
|
||||
_hiadr: .ds.l 1
|
||||
_baspag: .ds.l 1
|
||||
_usrstk: .ds.l 1
|
||||
_flags: .dc.w 0
|
||||
*
|
||||
* TPA Parameter Block
|
||||
*
|
||||
.even
|
||||
|
||||
_TPAB: .dc.w 0
|
||||
_low: .ds.l 1
|
||||
_high: .ds.l 1
|
||||
.even
|
||||
mesg: .dc.b 13,10,'TPA limits reset to COLDBOOT values:$'
|
||||
.bss
|
||||
.even
|
||||
.ds.l 200
|
||||
stack: .ds.w 1
|
||||
*
|
||||
* END of Assembly Language Code
|
||||
*
|
||||
.end
|
||||
|
||||
/*----------------------------------------------------------------------*\
|
||||
| loadrsx.c LOAD A RESIDENT SYSTEM EXTENSION v1.0 |
|
||||
| ================================ |
|
||||
| |
|
||||
| Description: |
|
||||
| ----------- This program loads a CP/M-68K executable |
|
||||
| program into high memory and reconfigures |
|
||||
| the TPA. The loaded program is now a |
|
||||
| Resident System Extension. Control is |
|
||||
| passed to the RSX so it can do its |
|
||||
| own initialization. |
|
||||
| |
|
||||
| Created by: Tom Saulpaugh |
|
||||
| ---------- |
|
||||
| Date: 11/29/82 |
|
||||
| ---- |
|
||||
| Last Modified: 12/01/82 |
|
||||
| ------------- |
|
||||
| |
|
||||
| Include Files: <Stdio.h> <Portab.h> |
|
||||
| ------------- |
|
||||
| Link to: rsx.s |
|
||||
| ------- |
|
||||
| |
|
||||
\*----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/************************************************************************\
|
||||
* Here are the Include Files *
|
||||
\************************************************************************/
|
||||
/********************************/
|
||||
#include "stdio.h" /* Standard I/O library */
|
||||
/********************************/
|
||||
/************************************************************************\
|
||||
* DEFINES for Loadrsx.c *
|
||||
\************************************************************************/
|
||||
/********************************/
|
||||
#define CON_OUT 2 /* Bdos console output func # */
|
||||
#define PRINT_STRING 9 /* Bdos print string func # */
|
||||
#define OPENFILE 15 /* Bdos open file function # */
|
||||
#define CLOSE_FILE 16 /* Bdos close file funciton # */
|
||||
#define READSEQ 20 /* Bdos read seq function # */
|
||||
#define SETDMA 26 /* Bdos set dma address func # */
|
||||
#define LOAD_PROG 59 /* Bdos load program func # */
|
||||
#define SET_TPA 63 /* Bdos set tpa limits func # */
|
||||
#define GET_TPA 63 /* Bdos get tap limits func # */
|
||||
#define CR (long)13/* Carriage Return */
|
||||
#define LF (long)10/* Linefeed character */
|
||||
#define DMA_OFFSET (long)0x80/* Default dma buffer offset */
|
||||
#define NULLB '\0' /* Null Byte */
|
||||
/********************************/
|
||||
#define isupper(c) ('A' <= (c) && (c) <= 'Z')/*upper case */
|
||||
#define islower(c) ('a' <= (c) && (c) <= 'z')/*lower case */
|
||||
#define tolower(c) (isupper(c) ? ((c)+040):(c))/*ltrans */
|
||||
#define toupper(c) (islower(c) ? ((c)-040):(c))/*utrans */
|
||||
/********************************/
|
||||
/************************************************************************\
|
||||
* GLOBAL Variables *
|
||||
\************************************************************************/
|
||||
/********************************/
|
||||
BYTE open = FALSE; /* Rsx file open flag */
|
||||
BYTE rsxfcb[36]; /* Fcb for rsx */
|
||||
BYTE buf[128]; /* buffer to hold rsx header */
|
||||
BYTE *msg1 = "RSXloader Ver 1.1$"; /* Version Number message */
|
||||
BYTE *msg2 = "Unable to open file$"; /* Could not open rsx on disk */
|
||||
BYTE *msg3 = "Size of RSX computed$"; /* Status message to user */
|
||||
BYTE *msg4 = "Unable to Load RSX$"; /* Program load error message */
|
||||
BYTE *msg5 = "Current TPA Boundries:$"; /* Status of Current TPA size */
|
||||
BYTE *msg6 = "New TPA Boundries:$"; /* Status after loading of RSX */
|
||||
BYTE *msg7 = "Starting Address----> $"; /* Start of TPA message */
|
||||
BYTE *msg8 = " Ending Address+1----> $";/* End of TPA message */
|
||||
EXTERN LONG LPB,lowadr,hiadr,baspag, /* Load Parameter block */
|
||||
usrstk; /* -------------------- */
|
||||
EXTERN UWORD flags; /* -------------------- */
|
||||
EXTERN UWORD TPAB; /* TPA Parameter Block */
|
||||
EXTERN LONG low,high; /* ------------------- */
|
||||
/********************************/
|
||||
/************************************************************************\
|
||||
* External Procedures *
|
||||
\************************************************************************/
|
||||
/********************************/
|
||||
EXTERN UWORD bdos(); /* Calls the bdos */
|
||||
/********************************/
|
||||
/************************************************************************/
|
||||
|
||||
|
||||
cr_lf()
|
||||
{
|
||||
bdos(CON_OUT,CR);
|
||||
bdos(CON_OUT,LF);
|
||||
}
|
||||
|
||||
illegal(fcb)
|
||||
BYTE *fcb;
|
||||
{
|
||||
REG UWORD i;
|
||||
|
||||
if(*++fcb == '$')
|
||||
reset();
|
||||
i = 1;
|
||||
while(i++ <= 11)
|
||||
if(*fcb++ == '?')
|
||||
return(TRUE);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
|
||||
openfile(fcb)
|
||||
BYTE *fcb;
|
||||
{
|
||||
REG BYTE *ptr;
|
||||
REG UWORD i;
|
||||
|
||||
if(!(illegal(fcb)))
|
||||
{
|
||||
if(bdos(OPENFILE,fcb) <= 3)
|
||||
open = TRUE;
|
||||
else
|
||||
{
|
||||
ptr = (long)0;
|
||||
ptr = (long)(0x9 + fcb);
|
||||
if(*ptr == ' ')
|
||||
{
|
||||
*ptr++ = '6';
|
||||
*ptr++ = '8';
|
||||
*ptr = 'K';
|
||||
}
|
||||
if(bdos(OPENFILE,fcb) <= 3)
|
||||
open = TRUE;
|
||||
}
|
||||
if(open)
|
||||
{
|
||||
ptr = rsxfcb;
|
||||
for(i = 0;i < 36;i++)
|
||||
*ptr++ = *fcb++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prtnum(num)
|
||||
LONG num;
|
||||
{
|
||||
if(num)
|
||||
{
|
||||
prtnum(num/10);
|
||||
bdos(CON_OUT,('0' + (num%10)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
prt_tpa(new)
|
||||
BYTE new;
|
||||
{
|
||||
BYTE *p;
|
||||
if(!(new))
|
||||
p = msg5;
|
||||
else
|
||||
p = msg6;
|
||||
cr_lf();
|
||||
bdos(PRINT_STRING,p);
|
||||
cr_lf();
|
||||
cr_lf();
|
||||
bdos(PRINT_STRING,msg7);
|
||||
if(low == 0)
|
||||
bdos(CON_OUT,'0');
|
||||
else
|
||||
prtnum(low);
|
||||
bdos(PRINT_STRING,msg8);
|
||||
if(high == 0)
|
||||
bdos(CON_OUT,'0');
|
||||
else
|
||||
prtnum(high);
|
||||
cr_lf();
|
||||
}
|
||||
|
||||
|
||||
|
||||
main()
|
||||
{
|
||||
REG LONG *p1,size;
|
||||
REG UWORD i;
|
||||
|
||||
bdos(PRINT_STRING,msg1);
|
||||
cr_lf();
|
||||
if(open)
|
||||
{
|
||||
bdos(SETDMA,buf);
|
||||
bdos(READSEQ,rsxfcb);
|
||||
size = 0;
|
||||
p1 = &buf[2];
|
||||
for(i = 0;i <= 3;i++)
|
||||
size += *p1++;
|
||||
size += 2048;
|
||||
bdos(GET_TPA,&TPAB);
|
||||
prt_tpa(FALSE);
|
||||
bdos(CLOSE_FILE,rsxfcb);
|
||||
for(i = 12;i < 36;i++)
|
||||
rsxfcb[i] = NULLB;
|
||||
bdos(OPENFILE,rsxfcb);
|
||||
LPB = rsxfcb;
|
||||
lowadr = high - size;
|
||||
hiadr = high;
|
||||
if(bdos(LOAD_PROG,&LPB) == 0)
|
||||
{
|
||||
high = high - size;
|
||||
TPAB = 0xFF;
|
||||
bdos(SET_TPA,&TPAB);
|
||||
prt_tpa(TRUE);
|
||||
bdos(SETDMA,(baspag + DMA_OFFSET));
|
||||
push();
|
||||
}
|
||||
else
|
||||
bdos(PRINT_STRING,msg4);
|
||||
}
|
||||
else
|
||||
bdos(PRINT_STRING,msg2);
|
||||
}
|
||||
Reference in New Issue
Block a user