|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 19200 (0x4b00) Types: TextFile Names: »tautoboot «
└─⟦9ccaf6601⟧ Bits:30008165 Bånd med SW8000 kildetekst/release værktøjer └─⟦2ba378e4a⟧ └─⟦this⟧ »tautoboot «
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◀