/* This loads a sequence of absolute hunks produced by SYSLINK,
     then outputs a 'core-image'.
  */
needs "USINGCMS"

get "NLIBHDR"

GET "USINGCMS"

manifest $( t.end=1002; t.abshunk=1003 $)
static $( cvec=0 $)

let start() be $( USINGCMS("HUNK") $(
  let vvvv = vec (64*1024/bytesperword)
  LET max = ?
  cvec := vvvv
  for i = 0 to 64*1024/bytesperword do cvec!i := 0

   $( LET fd = findinput("SYSLINK")
      LET fc = findinput("SYSCODE")
      LET so = findoutput("SYSPRINT")

      IF so=0 stop(85)
      selectoutput(so)

      IF fd=0 DO
      $( writes("*NNo data segment input*N")
         stop(10)
      $)

      IF fc=0 DO
      $( writes("*NNo code segment input*N")
         stop(10)
      $)

      selectinput(fd)

      max := readhunks()
      writef("*Nmax = %X5*N", max)

      IF max=0 DO
      $( writes("*NError reading data hunks*N")
         stop(85)
      $)

      // interrupt vectors loaded from 0 to hex 400
      // data is loaded from hex 500 to hex 600
      // plus the top 3K bytes.
      selectoutput(findoutput("TRIPOS DATA"))
      writes("LOC0000")
      outlims(0, #X400-1)
      outlims(#X500, #X660-1)
      outlims(max-#XC00, max)
      writes("*NSTOR"); endwrite()

      selectinput(fc)
      FOR i = 0 to 64*1024/bytesperword-1 DO cvec!i := 0
      max := readhunks()
      selectoutput(so)
      writef("*Nmax = %X5*N", max)
      IF max=0 DO
      $( selectoutput(so)
         writes("*NError reading code hunks*N")
         stop(85)
      $)

      selectoutput(findoutput("TRIPOS CODE"))
      writes("LOC0000")
      // code is loaded from 8 to 11 plus the top #X9C40 bytes
      outlims(8, 11)
      outlims(max-#X9C3F, max)
      writes("*NSTOR")
      endwrite()
      selectoutput(so)
      writes("*NTripos image files created OK*N")
      stop(0)
   $)
$)
$)


AND readhunks() = VALOF
$( LET m = 0
  $( let b1 = rd16()
     if b1=t.end do b1 := rd16()
     unless b1=t.abshunk break

     $( let base = rd16()*2
        let size = rd16()*2

        for i = 0 to size-1 do
        $( let x = rd8()
           IF x=-1 DO RESULTIS 0
           cvec%(base+i) := x
           IF base+i-m>0 DO m := base+i // max
        $)
     $)
  $) repeat

   RESULTIS m
$)


AND RD8() = VALOF
$( LET VAL = READX()
   IF VAL=-1 RESULTIS -1
   $( LET VAL2 = READX()
      IF VAL2=-1 RESULTIS -1
      RESULTIS VAL*16 + VAL2
   $)
$)

AND READX() = VALOF
$( LET C = ?
   C := RDCH() REPEATWHILE C='*S' | C='*N'
   IF C=ENDSTREAMCH RESULTIS -1
   RESULTIS '0'<=C<='9' -> C-'0', C-'A'+10
$)

AND RD16() = VALOF
$( LET VAL1 = RD8()
  IF VAL1=-1 RESULTIS -1
  $( LET VAL2 = RD8()
     IF VAL2=-1 RESULTIS -1
     RESULTIS (VAL2<<8) | VAL1
  $)
$)


AND outlims(a, b) BE
$( // output bytes from limits a to b
   FOR i = a TO b DO
   $( IF i REM (32) = 0 | i=a DO writef("*NOG%X4", i)
      writehex(cvec%i, 2)
   $)
$)