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