Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

100 lines
3.1 KiB
C

/*=======================================================================*/
/*+---------------------------------------------------------------------+*/
/*| |*/
/*| P-CP/M(tm) Block Move for the KONTRON BOARD (Z8002) |*/
/*| |*/
/*| Copyright 1982, Zilog Incorporated. |*/
/*| |*/
/*+---------------------------------------------------------------------+*/
/*=======================================================================*/
char copyright[] = "Copyright 1982, Zilog Incorporated";
/* HISTORY
**
** 830111 F. Zlotnick (Zilog)
** 830121 D. Heintz (Me) Fixed bug in s/d window computation
*/
mem_bcp( sseg, source, dseg, dest, length)/* sseg and dseg are pseudo-segment */
unsigned short sseg, source, dseg, dest;/* numbers from mem_copy. */
unsigned short length; /* source and dest are offsets in */
/* the pseudo-segments. length is */
/* the number of bytes to be copied*/
{
register unsigned length1, length2;
register unsigned middle;
short swindow, dwindow;
unsigned short blength;
static char locbuf[256]; /* intermediate buffer */
/* deal recursively with the possibility of crossing the half-segment line */
middle = 0x8000;
if(source < middle && source + length > middle) {
length1 = middle - source; /* first half */
length2 = length - length1; /* second half */
mem_bcp(sseg,source,dseg,dest,length1); /* recurse */
mem_bcp(sseg,middle,dseg,dest+length1,length2);/* recurse */
return;
}
if(dest < middle && dest + length > middle) {
length1 = middle - dest; /* first half */
length2 = length - length1; /* second half */
mem_bcp(sseg,source,dseg,dest,length1); /* recurse */
mem_bcp(sseg,source+length1,dseg,middle,length2);/* recurse */
return;
}
/*
* This part is non-recursive. If you get this far, you're guaranteed
* not to cross a mid-segment boundary on either the source or dest
* blocks.
*/
swindow = ((sseg >> 8) << 1) | ( (source >= middle) ? 1 : 0);
dwindow = ((dseg >> 8) << 1) | ( (dest >= middle) ? 1 : 0);
if ( swindow == dwindow ) { /* Both in same window */
map_wdw(swindow);
if(swindow != 0) { /* If really mapped, then */
source |= 0x8000; /* must be in upper half */
dest |= 0x8000; /* of system address space */
}
blkmov(source,dest,length);
}
else if(swindow != 0 && dwindow != 0) {
source |= 0x8000;
dest |= 0x8000;
while(length > 0) {
blength = (length > 256)? 256: length ;
map_wdw(swindow);
blkmov(source,locbuf,blength); /* Assumes pointers*/
map_wdw(dwindow); /* are short! */
blkmov(locbuf,dest,blength); /* Ditto */
source += blength;
dest += blength;
length -= blength;
}
}
else {
if ( swindow == 0 ) { /* System lower half: no window */
map_wdw(dwindow); /* Put dest block in upper */
dest |= 0x8000; /* half of system space */
}
else if ( dwindow == 0 ) {
map_wdw(swindow); /* Put source block in upper */
source |= 0x8000; /* half of system space */
}
while ( length > 0 ) {
blength = (length > 256)? 256: length ;
blkmov(source,dest,blength);
source += blength;
dest += blength;
length -= blength;
}
}
}