DataMuseum.dk

Presents historical artifacts from the history of:

RC4000/8000/9000

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RC4000/8000/9000

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦0c677d116⟧ TextFile

    Length: 19200 (0x4b00)
    Types: TextFile
    Names: »tautoboot   «

Derivation

└─⟦9ccaf6601⟧ Bits:30008165 Bånd med SW8000 kildetekst/release værktøjer
    └─⟦2ba378e4a⟧ 
        └─⟦this⟧ »tautoboot   « 

TextFile

autoboot=slang list.no xref.no
b.

m. autoboot 88.02.22 15.20.00
m. version 6  

; bootloader, rc8000.

; autoload program for load from rc82xx disc, ida801 or fpa.
; the autoload from disc is performed in the following way:
;  -  the autoload bottom is pressed and released.
;       the rc8000 cpu executes a general clear, inserts two channelcommands
;       in the core store (an initialize and an input command), initializes
;       the basis address of the controller (word 8) and starts the 
;       channelprogram on the device with io-device number 4 (the disc).
;  -  first command initiates the disc controller, positions to cylinder zero,
;       head zero and sector zero.
;  -  second command inputs one segment (the bootloader) to first free core
;       after the input command.
;  -  the segment now loaded must start with a continuation of the initial
;       channelprogram, which normally consists of a stop command only.
;
;  -  in case the device 4 does not respond the start channelprogram command,
;       the mikroprogram in the cpu now tries to autoload from device number 
;       1, which is an IDA801 with a tapestation, but without discs. 
;     If no responce the mikroprogram tries to autoload from device number 2 
;       which is the fpa.
;     This requires only reinitialisation of the basis address of the con-
;       troller table. the channelprogram inserted in core is now started
;       on the fpa.
;       If device number 4 is a IDA801 controller and the load is from disc,
;       the controller saves a coredump on disc 00( disc controller 0 , plug 0).
;       Segment 0 on the disc holds information about the location af the 
;       monitor, the coredump area e.t.c. The dump is terminated by either
;          - top of dumparea reached
;          - top of core is reached
;          - parity error .
;        Following this the bootloader is loaded as specified by the address
;        and the bytecount of the input command. The IDA801 controller is 
;        only able to respond on input commands ( 1<8 ); all other commands
;        will cause the controller to halt.
;
;        version 5:  error causing break if memory = 12Mb has been corrected.
;        version 5.1: KMD-ÅLB. load only 500 segments (p5); 
;                     Problems with dcm801 and huge memory size.
;        version 6:  error in version 5. If core size = 12Mb the size would
;                    be set 192Kb too low.
;
; 89 01 16 7.45 kak max core address reduced to 8.37777772

b.a20,p10 

; the channelprogram placed in core after activation of the autoload buttom
; has the format shown below. Part of this channelprogram area does also serve
; as device controller description and as standard status area. the format is:
;
;   address    contents   channelprogram    controller desc   status area
;
;    8         12-iodev<3
;   10         6<8        initialize
;   12         10         dummy             start of chpg
;   14         20         dummy             start of st.area
;   16         1<8(256)   input             interrupt addr
;   18         22         first addr        interrupt number
;   20         768        blocklength                         chpg addr
;   22         word0      ...                                 rem. char. count
;   24         word1      ...                                 curr. status
;   26         word2      ...                                 event status
;   28         word3      ...
;   30         ...        ...

; word0,1,2 are the beginning of the first segment loaded. they do at load time
; contain the channelcommand:
;   word0      15<8       stop
;   word1      ..         dummy
;   word2      ..         dummy
;   word3      ..         ....

a1 =8.60<1             ; display register
a2 =8.17<1             ; coresize register
a3 =8.57<1             ; interrupt register
a4 =4                  ; device number of disc
a5 =2                  ; device number of fpa
a6 =8                  ; basis of controller table
a7 =12                 ; start of controller description
a8 =10                 ; start of channelprogram
a9 =20                 ; start of standard status area
a10=22                 ; first free address after autoload channel program
a11=256                ; interrupt address (contents of word(16))
a12=22                 ; interrupt number (contents of word(18))

; user defined parameters:

p0 =+8                 ; first sector of monitor area
p1 =+840               ; first sector of coredump area, if p1<0 then no coredump
p2 =21                 ; number of sectors per track (head)
p3 =168                ; max size, dumping the core (in segments)
                       ;   = max size, loading the monitor + p4 (in segments)
p4 =1024               ; load address of monitor
p5= 500                ; max size loading the monitor (5.1 testversion)

; when loading from fixed media disc with fixed head part, then use
;  p0=4+1008, p1=840+1008
; else use
;  p0=4     , p1=840

\f



s.b50,m6,n6 w.

k=a10

; channelcommands continuing the init autoload channelprogram:
b0:  15<8              ; stop
     0                 ; dummy
     0                 ; dummy

; the following four words are intended for automatic startup area name
; default is: manual startup!
;
; these four words are known(!) by absolute core-address in moncatinit
; they are also known by the 'install'-program!
     0, r.4            ; startup name

; device address:
b3:  1<23+a4<3         ; device address of loaddevice        

b5: 01                 ; +1: load flag: IDA801load: 2, discload: 1, fpaload: 0
                       ; +0: coredump flag: <> 0 parity error, no coredump
b6: 8.77777000         ; 
\f



; channelprogram for fpaload of monitor.

b10: 3<8               ; output
     b15               ;  addr of status byte
     1                 ;  size:=1 char
b11: 1<8+1<7           ; input and continue
     b16               ;  addr of start byte
     1                 ;  size:=1 char
b12: 1<8               ; input
b13: p4                ;  start addr (init: load addr(monitor))
     768               ;  size:=1 segment
b14: 15<8              ; stop
                       ;  dummy
                       ;  dummy

b15: 0<16              ; status byte<16:=transfer next block
b16: 0                 ; start byte<16
b17: p4                ; top of last loaded segment
b18: 255<16            ; status byte<16:=stop transfer

\f



; channelprogram for discload of monitor:
b20: 2<8               ; seek
     b30               ;  addr of seek information
     6                 ;  number of chars
b21: 1<8+1             ; input address mark
     b35               ;  addr mark area
     12                ;  read one addr mark
b22: 15<8              ; stop
                       ;  dummy
                       ;  dummy

; position area.
b30: 0<8+0             ;   cylinder0, head0
     (:p2-1:)<16+0     ;   last sector, empty flag

; input area for addr marks.
b35=b10                ; b10:   0,0 ; addr mark area(curr)
b36=b35+4              ; b10+4: 0,0 ; addr mark area(next)

; format of disc.
b31: 0                 ;   segments per cylinder 
b32: p2                ;   segments per track
b33: 0                 ;   screw

b38: p3*768            ;   max transfer size 
b41: p5*512            ;   max load size
  
; channelprogram used to initialize the
; first 4 words of core
 
b39: 0<8               ; sense
     0                 ; addr:= core(0);
     12                ; number of chars
b40: 15<8              ; stop
                       ; dummy
                       ; dummy

\f


; discload.
b.i4,j6 w.

m2:  al  w0  b20       ; discload from RC82XX:
     rs  w0  a7+0      ;   start(chpg):=start(discloadpg);
j0:  al  w2  b22+6     ; next head:
     jl  w3  n0        ;   execute chpg(top(discchpg));
     jl      -16       ;    error: sysfault(16);
     al  w0  1         ;    ok:
     ba  w0  b30+1     ;
     hs  w0  b30+1     ;   head:=head+1;
     rl  w3  b36+0     ;
     sh  w3  1<8-1     ;   if cylinder(next)>0 then
     jl      j0        ;     goto next head;
     wm  w0  b32       ;
     rs  w0  b31       ;   segments per cylinder:=head*segments per track;
     bz  w0  b36+2     ;
     ls  w0  -4        ;
     rs  w0  b33       ;   screw:=sector(next);
                       ;
c.p1
     zl  w0  b5        ;      if no parity error then dump core
     se  w0  0         ;
     jl      j1        ;
     rl  w1  b38       ;      load length:=max load length;
     al  w0  3<8       ;          
     rs  w0  b21+0     ;   command:=write;
     al  w0  0         ;   first:=0 (=first byte of core);
     ds  w1  b21+4     ;   size:=load length;
     rl  w2  i0        ;
     jl  w3  n1        ;   set position(first sector coredump area);
     al  w2  b22+6     ;
     jl  w3  n0        ;   execute chpg(top(discpg));
     am      0         ;    ignore the answer
z.                     ;
m3:
j1:  al  w0  1<8       ; load monitor:
     rs  w0  b21+0     ;   command:=read;
     al  w0  p4        ;   first:=load addr(monitor);
     gg  w1  a2        ; load size:
     sl  w1  (b41)     ;   min(loadsize, coresize)
     rl  w1  b41       ;
     la  w1  b6        ;  only transfer full segments
     al  w2  x1        ;
     ls  w2  -1        ;
     wa  w1   4        ;
     ds  w1  b21+4     ;
     rl  w2  i1        ;
     jl  w3  n1        ;   set position(first sector of monitor area);
     al  w2  b22+6     ;
     jl  w3  n0        ;   execute chpg(top(chpg));
     jl      -64       ;    error: sysfault(64);
                       ;    ok:
     jl      m5        ;   goto finis;
i0:  p1                ;
i1:  p0                ;
e.                     ; end of discload;
\f


; fpaload.
b.i10,j10 w.
m4:                    ; fpaload
     al  w0  b10       ;   start(chpg):=start(fpaloadpg);
     rs  w0  a7+0      ;
     al  w0  0         ;
     hs  w0  b5+1      ;   load flag:=load from fpa;
j0:  al  w2  b14+6     ; next:
     jl  w3  n0        ;   execute chpg(top(chpg));
     jl      -4        ;    error: sysfault(4);
                       ;    ok:
     al  w1  512       ;
     wa  w1  b13       ;
     rs  w1  b13       ;   first addr:=first addr+512;
     rl  w2  b17       ;
j2:  sl  w2  x1        ; check next:
     jl      j0        ;   if block top>=top transferred then
     rl  w3  x2        ;     goto next;
     wa  w2  x2        ;   size:=word(block top);
     rs  w2  b17       ;   block top:=block top+size;
     se  w3  0         ;   if size<>0 then
     jl      j2        ;     goto check next;
     rl  w0  b18       ; end:
     rs  w0  b15       ;   status byte:=stop transfer;
     rl  w0  b14       ;
     rs  w0  b11       ;   insert stopcommand in second command;
     al  w2  b11+6     ;
     jl  w3  n0        ;   execute chpg(top(chpg);
     jl      -8        ;   error: sysfault(8);
                       ;    ok:
     jl      m5        ;   goto finis;
e.
 \f


0, r.(:a11-k:)/2+1     ; fill up
0                      ; a11: interrupt word

m1:                    ; load from ida801:
     al  w0  b21       ; start(chpg) = start(input command)
     rs  w0  a7+0      ; goto load monitor
     jl      m3        ;




; start load.
; this block is entered right after load of bootloader.
b.i4,j10 w.
m0:  rl  w0  a11       ; start load:
     se  w0  a12       ;   wait interrupt;
     jl      m0        ;
     dl  w1  a9+2      ; check status:
     dl  w3  a9+6      ;
     se  w0  768       ;   if status area(0) = channelpgm(5) then
     jl      j8        ;       begin
     al  w0  2         ;                        
     hs  w0  b5+1      ;       load type = IDA801
     jl      j9        ;       end
                       ;   else
j8:  sn  w0  b0+6      ;   if next chpg command<>top(init chpg)
     sl  w1  1  ;sew1 0;   or rem char count<>0
     jl      -2        ;   or curr status(bit0)<>0
     sl  w2  0         ;   or event status<>0 then
     sz  w3 (i0);sew3 0;     sysfault(2);
     jl      -2        ;
j9:  al  w1  0         ;                   
     rl  w0  b7        ;
                       ;   find core size: do until timeout
j0:  wa  w1  i1        ;   addr = addr +I1
     sz  w1  (i3)      ;   if upper limit core then
     jl      j1        ;      max adress to max core register
     di  w3  x1        ;   w3 = (addr)
     sx      2.010     ;   end
     jl      j2        ;
     sx      2.101     ;  if memory parity error (NACK (23))
     hs  w0  b5        ;     or bus parity error (PARITY (21)) 
     jl      j0        ;     then clear coredump flag

j1:  rl  w1  i2        ;  core size := max
j2:  al  w1  x1-2      ;
     do  w0  x1+2      ;  for addr = addr step -2 until found do
     di  w3  x1+2      ;  (addr+2) = pattern
     sx      2.111     ;   w3 = (addr-2)
     jl      j2        ;   if w3 = pattern and no exception then
     se  w3  (0)       ;      found = true
     jl      j2        ;    end
     gp  w1  a2        ;     coresize = max address
     zl  w0  b5        ;   if not coredump flag then
     al  w2  b1        ;      clear all core
     sn  w0  0         ;   else
     rl  w2  b41       ;      clear top of core 
     jl  w3  n2        ;
     al  w0  a7        ;    loaddevice = a7 -(contr. base)
     ws  w0  a6        ;     
     hs  w0  b3+1      ;
     zl  w0  b5+1      ;   if load type = IDA801 then goto idaload
     sn  w0  2         ;
     jl      m1        ;
     al  w0  b39       ; start channelprogram used to initialize the
     rs  w0  a7+0      ; first four words of core memory
     al  w2  b40+6     ;
     jl  w3  n0        ;
     am      0         ; ignore the answer
     rl  w0  a6        ; if device number = 4 then
     sn  w0  a7-a4<3   ;
     jl      m2        ;    goto discload
     jl      m4        ;    else goto fpaload;
 
i0:  -1-1<23>4         ; status bit4 (blocklength error)
i1:  64<10             ; core module:=64 k words
i2:  8.37777772        ; max core address         
i3:  1<23              ; address bit
e.

\f


; finis.
b.j1 w.
m5:                    ; finis:
     al  w1  7         ;
j0:  al  w1  x1-1      ;   clear interrupts(0:6);
     gp  w1  a3        ;
     se  w1  0         ;
     jl      j0        ;
     zl  w0  b5+1      ; enter monitor:
     rs  w0  p4+2      ;   insert loadflag in monitor;
     jl      p4+6      ;   enter monitor in +6;
e.
\f


; execute chpg.
; the procedure starts the channelprogram on the device defined in b3,
; awaits an interrupt for a certain time given by the 'max delay'. 
; If not load from IDA801, the procedure
; checks the status delivered in the std status area,
; and returns.
; the procedure return to
;   link+0    in case of errors (w0 = error cause)
;   link+2    in case of normal termination.
; error cause
;      1     exception when starting the channelprogram
;      2     timeout in waiting for the interrupt
;      3     statuserror, which means
;                 top(chpg)<>awaited value
;                 remaining character count<>0
;                 current status(bit0)<>0
;                 event status<>0
;
;        call          return
; w0     -             destroyed or error cause
; w1     -             destroyed
; w2     top(chpg)     destroyed
; w3     link          unchanged
b.i4,j4 w.
n0:  rs  w2  i1        ; execute chpg: save chpg top;
     al  w1  -1        ;
     al  w2  -1        ;
     rs  w2  a11       ;   interrupt word:=-1;
     ds  w2  a9+2      ;
     ds  w2  a9+6      ;   std status area:=-1,-1,-1,-1;
     al  w0  1         ;   1 == start command for ifp
     do     (b3)       ;   start chpg;
     sx      2.111     ;   if ex<>2.000 then
     jl      j1        ;     goto error1;
     al  w1  0         ;   unit:=time of loop (appr. 12.5 microsec);
j0:  al  w1  x1+1      ;   for time:=unit step unit until max delay do
     sn  w1 (i0)       ;     if interrupt then
     jl      j2        ;     goto after interrupt;
     sn  w2 (a11)      ; time expired:
     jl      j0        ;   return to error2;
     zl  w0  b5+1      ; after interrupt:
     sn  w0  2         ; if load from IDA801 then
     jl      x3+2      ; return ok else
     dl  w1  a9+2      ; RC82XX:
     sn  w0 (i1)       ;   if next chpg command<>top(chpg)
     se  w1  0         ;   or rem char count<>0
     jl      j3        ;   or curr status(bit0)<>0
     dl  w1  a9+6      ;   or event status<>0 then
     sl  w0  0         ;     goto error3;
     se  w1  0         ;
     jl      j3        ;
     jl      x3+2      ; ok: return to link+2;

j1:  am      1-2       ; error1: errorcause:=1;
j2:  am      2-3       ; error2: errorcause:=2;
j3:  al  w0  3         ; error3: errorcause:=3;
     jl      x3+0      ;   return to link;
i0:  80000000          ; delay: apr. 400 sek                                   
i1:  0                 ; top(chpg)
e.


; procedure set position.
; this procedure computes the cylinder, head and sector number from
; the logical segment number.
; the parameters 'segments per cylinder' , 'segments per track'
; and 'screw' is used.
;        call:         return:
; w0                   destroyed
; w1                   destroyed
; w2     segmentno     destroyed
; w3     link          destroyed
b.w.
n1:  ld  w1  -100      ; set position:
     wd  w2  b31       ;   w2:=cylinder;
     wd  w1  b32       ;   w1:=head;
     sz  w2  2.1       ;   w0:=sector;
     wa  w0  b33       ;   if cylinder odd then
     sl  w0 (b32)      ;     sector:=(sector+screw) mod sectors per track;
     ws  w0  b32       ;
     ls  w2  8         ;
     lo  w1  4         ;   position1:=cylinder<8+head;
     ls  w0  16        ;   position2:=sector<16+0;
     rs  w1  b30+0     ;
     rs  w0  b30+2     ;   position:=position0, position1;
     jl      x3        ; exit: return;
e.
; procedure reset core.
; clear possible parity errors in core.
;  note: the last word may not be written
;        call:         return
; w0                   unchanged
; w1     top addr      unchanged
; w2     start addr    destroyed
; w3     link          unchanged
b.w.
n2:  ds  w0  x2       ; (addr) := w0 ; (addr-2) := w3
     al  w2  x2+4     ; 
     sh  w2  x1       ;
     jl      n2       ;
     jl      x3       ;
e.
b7: 8.52525252        ; check pattern


\f



0, r.(:a10+512-k:)/2-11+1 ; fill up

b.i0 w.

; interrupt stack:
     0                 ; monitor element: (end status)
     i0                ;                  reg dump
     0                 ;                  exception
     0                 ;                  escape
     m0                ;                  monitor call
     0                 ;                  external interrupt

     1<23              ; user element:    monitor status
     i0                ;                  reg dump
     0                 ;                  exception
     0                 ;                  escape

i0:  jd      -1<11+0   ; last word in first segment: change to monitor mode and goto start load;
b1=k/4*4               ; top(loader)
e.

e.                     ; end of load segment;

e.

e.
end
▶EOF◀