Files
Digital-Research-Source-Code/MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/10/OUTP.PLM
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

227 lines
5.8 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

$title ('HEX OUTPUT MODULE')
hexout:
do;
/*
modified 3/28/81 R. Silberstein
modified 3/30/81 R. Silberstein
modified 4/9/81 R. Silberstein
*/
/*
This is the module to produce the (hex-)output
from the assembler. The interface to other modules
goes through the subroutine
EMITCODEBYTE (outputbyte,segmenttype).
This routine outputs one byte of generated code of
a specified segment type (code,data,stack,extra).
The subroutine also updates the value of the current
instruction pointer of the current segment (CIP),
and prints the output code on the print line.
*/
$include (:f1:macro.lit)
$include (:f1:struc.lit)
$include (:f1:outp.lit)
$include (:f1:subr2.ext)
$include (:f1:files.ext)
$include (:f1:global.ext)
dcl
empty lit '0ffh', /* buffer empty value */
recordlimit lit '30', /* max no of bytes pr record */
loccip addr, /* local copy of instruction pointer */
startfound byte, /* true if start record sent */
gtyp byte, /* incomming byte type */
gbyt byte, /* incomming byte */
curtyp byte, /* current byte type */
sum byte, /* used to compute check sum */
buffer (35) byte, /* record buffer (RECORDLIMIT+5) */
recordlg byte at (.buffer(0)),
recordtype byte at (.buffer(3)),
offsetaddr addr at (.buffer(1)),
bufpt byte, /* buffer index */
/* Record type conversion table */
/* ( to be changed later ??? ) */
rectyp$I$tab(12) byte data
(0ffh,eoftype,0ffh,starttype,INTELdata,INTELdata,
INTELdata,INTELdata,INTELsegment,INTELsegment,INTELsegment,
INTELsegment),
rectyp$D$tab(12) byte data
(0ffh,eoftype,0ffh,starttype,DRcodedata,DRdatadata,
DRstackdata,DRextradata,DRcodesegm,DRdatasegm,DRstacksegm,
DRextrasegm);
/*********** subroutines **********/
rectyptab: procedure(n) byte;
declare n byte;
if intel$hex$on then$do
return rectyp$I$tab(n);
else$do
return rectyp$D$tab(n);
end$if;
end rectyptab;
switch$high$low: procedure(p);
declare p address, ch based p byte, (s1,s2) byte;
s1=ch;
p=p+1;
s2=ch;
ch=s1;
p=p-1;
ch=s2;
end switch$high$low;
writebyt: proc (ch);
dcl ch byte;
call outhexbyte(ch);
end writebyt;
writerecord: proc; /* write current recor to file */
call switch$high$low(.offsetaddr);
recordlg=bufpt-4;
sum=0; /* compute check sum */
i=0ffh;
do while (i:=i+1) < bufpt;
sum=sum+buffer(i);
end$while;
buffer(bufpt)=-sum; /* check sum */
call writebyt(':');
do i=0 to bufpt; /* print hexbytes to file */
call hex1out(buffer(i),.help(0));
call writebyt(help(0));
call writebyt(help(1));
end$do;
call writebyt(cr);
call writebyt(lf);
end writerecord;
enternewbyt: proc(b); /* enter a new byte into buffer */
dcl b byte;
if bufpt > recordlimit then$do /* test if record full */
call writerecord;
offsetaddr=cip;
bufpt=4;
end$if;
buffer(bufpt)=b;
bufpt=bufpt+1;
end enternewbyt;
enterinput: proc;
call enternewbyt(gbyt);
end enterinput;
eofrecord: proc; /* write end-of-file record to file */
if curtyp<>empty then call writerecord;
recordtype=rectyptab(eoftype);
offsetaddr=0;
bufpt=4;
call writerecord;
end eofrecord;
startrecord: proc; /* write a start record to file */
dcl seglow byte at (.csegvalue),seghigh byte at (.csegvalue+1),
offslow byte at (.cip),offshigh byte at (.cip+1);
if pass=2 then$do
startfound=true;
if curtyp <> empty then call writerecord;
bufpt=4;
offsetaddr=0;
recordtype=rectyptab(starttype);
if csegspec then$do
call enternewbyt(seghigh);
call enternewbyt(seglow);
else$do
call enternewbyt(0);
call enternewbyt(0);
end$if;
call enternewbyt(offshigh);
call enternewbyt(offslow);
call writerecord;
curtyp=empty;
end$if;
end startrecord;
segmbyte: proc; /* write a segment value byte to file */
if pass = 2 then$do
if curtyp <> gtyp then$do
if curtyp <> empty then call writerecord;
curtyp=gtyp;
recordtype=rectyptab(gtyp);
offsetaddr=0;
bufpt=4;
call enterinput;
else$do
call enterinput;
call writerecord;
curtyp=empty;
end$if;
end$if;
end segmbyte;
databyte: proc; /* write a data byte to file */
if pass=2 then$do
if (curtyp <> gtyp) or (loccip <> cip) then$do
if curtyp<>empty then call writerecord;
curtyp=gtyp;
recordtype=rectyptab(gtyp);
offsetaddr=cip;
bufpt=4;
end$if;
call enterinput;
call hex1out(gbyt,.prefix(prefixptr)); /* output to listing */
prefixptr=prefixptr+2;
end$if;
cip=cip+1; /* update instruction pointer */
loccip=cip;
end databyte;
emitinit: proc public;
startfound=false;
curtyp=empty;
end emitinit;
emitterminate: proc public;
call eofrecord; /* write EOF record */
end emitterminate;
emitcodebyte: proc (b,typ) public;
dcl (b,typ) byte;
gbyt=b; /* move to global variables */
gtyp=typ;
do case typ-CSdata;
do; /* CS data */
if not startfound then$do
call startrecord;
end$if;
call databyte;
end;
call databyte; /* DS data */
call databyte; /* SS data */
call databyte; /* ES data */
call segmbyte; /* CS value */
call segmbyte; /* DS value */
call segmbyte; /* SS value */
call segmbyte; /* ES value */
end$case;
end emitcodebyte;
end$module hexout;