mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 00:14:25 +00:00
100 lines
3.1 KiB
C
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;
|
|
}
|
|
}
|
|
}
|