load.39 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. ;**** A BASIC CLUSYS FILE ****
  2. cluster %load,0,0,[],[]
  3. ; snap should be called with the address of a
  4. ; procedure call block (pcb) and the address of the
  5. ; entry block of the procedure executing when
  6. ; snapping. it will give a nasty error if the pc.lnk
  7. ; field of the pcb does not refer to a word which
  8. ; refers back to the pcb. it will give another nasty
  9. ; error if the pcb refers to a procedure that is not
  10. ; present in the procedure table. snap returns (if all
  11. ; is well) with the procedure object.
  12. proc snap,[plnk,ent]
  13. $label retry ; we will try forever if necessary
  14. move r0,plnk(er)
  15. tcheck r0,tpcb
  16. $if skipe pc.par(r0) ; if no parms to fool with
  17. $then mcall pfind,[pc.str(r0)] ; look in ptab
  18. $else call desc$pfind,1,[r0,ent(er)] ; look and perhaps build one
  19. $fi
  20. $if came rr,$none
  21. $then slink lnk,Snap can't find:
  22. move g0,lnk(lr)
  23. $go bitch
  24. $fi
  25. hrrz r1,en.lpr(rr) ; get the pr for the found procedure
  26. hrrz n1,pr.cut(r1) ; get number of args for that procedure
  27. hrrz r0,plnk(er)
  28. $if skipn n2,pc.num(r0) ; if #args < 0, then no test
  29. cain n2,-2(n1) ; adjust test for frame size
  30. $then slink lnk,Snap found a bad # of args for:
  31. move g0,lnk(lr)
  32. $go bitch
  33. $fi
  34. push sp,rr
  35. move r0,ent(er) ; try to fixup linkage
  36. hlro r0,en.lpr(r0)
  37. $ift mcall ld.sb,[r0,plnk(er),rr]
  38. $then $rtn (sp)
  39. $fi
  40. move rr,(sp)
  41. move r0,ent(er) ; try to fixup proc parms
  42. hlro r0,en.par(r0)
  43. $ift mcall ld.sb,[r0,plnk(er),rr]
  44. $then $rtn (sp)
  45. $fi
  46. move rr,(sp)
  47. move r0,ent(er) ; try to fixup cluster parms
  48. hrro r0,en.par(r0)
  49. $ift mcall ld.sb,[r0,plnk(er),rr]
  50. $then $rtn (sp)
  51. $fi
  52. move rr,(sp)
  53. $rtn rr ; and return the procedure object
  54. $label bitch ; come here to bitch about something
  55. mcall dtyo
  56. push sp,rr
  57. mcall crlf,[rr] ; get new line
  58. move rr,(sp)
  59. mcall ch.ws,[rr,g0] ; write the bitch
  60. move rr,(sp)
  61. move r0,plnk(er)
  62. mcall ch.ws,[rr,pc.str(r0)] ; write the name of the offender
  63. mcall crlf
  64. croak $p gets you a listen loop (maybe).
  65. mcall dtyi
  66. args [rr]
  67. mcall dtyo
  68. call listen,2,[rr] ; call to listen again
  69. $go retry ; try again if we return
  70. corp snap,[plnk,ent]
  71. ; Load$replace(vec,item,repl) tries to replace all occurences
  72. ; of item in vec by repl. If there was a replacement, it returns
  73. ; true, otherwise false.
  74. proc ld.sb,[vec,item,repl],[flag],[tbool+false]
  75. move r0,vec(er)
  76. $if trne r0,-pgsize
  77. $then $rtnc $false
  78. $fi
  79. $for all,rr,mcall loopv,[r0]
  80. move r0,item(er)
  81. $if came r0,(rr)
  82. $then move r1,repl(er)
  83. movem r1,(rr)
  84. move rr,$true
  85. movem rr,flag(er)
  86. $fi
  87. $rof all
  88. $rtn flag(er)
  89. corp load$replace,[vec,item,replace],[flag]
  90. ; xload takes a string and tries to open the named channel.
  91. ; it then reads lines and treats them as file names to be fload'd
  92. ; into the current environment.
  93. proc xload,[str],[chan],[0]
  94. tcheck str(er),tstr
  95. slink lnk,dsk:clusys;
  96. call %str$concat,2,[lnk(lr),str(er)]
  97. assn str(er),rr
  98. slink lnk,read
  99. call chan$open,2,[lnk(lr),str(er)]
  100. assn chan(er),rr
  101. $if hlrz n0,rr
  102. cain n0,(tchan)
  103. $then $rtn rr
  104. $fi
  105. $loop
  106. link lnk,tchar+12
  107. call chan$reads,2,[chan(er),lnk(lr)]
  108. assn str(er),rr
  109. call %str$size,1,[rr]
  110. $if camg rr,$two
  111. $then call fload,1,[str(er)]
  112. $else call chan$close,1,[chan(er)]
  113. $rtnc $none
  114. $fi
  115. $pool
  116. corp xload,[str],[chan]
  117. ; Load$page(chan,addr) attempts to load in a page from
  118. ; a load file by mapping it in. If successful, it
  119. ; makes the page read-only to prevent funny things
  120. ; from happening.
  121. proc ld.np,[chan,addr]
  122. movei n0,0
  123. hrrz n1,chan(er)
  124. hrrz n2,addr(er)
  125. idivi n2,pgsize
  126. $if .call ld.np1(pr) ; did we map it in?
  127. $then
  128. $elf .call ld.np2(pr) ; try to get new page for reading
  129. $then movei n1,pgsize ; could not map it in, so try to read it
  130. hrli n1,(tint)
  131. call chan$readvec,3,[chan(er),addr(er),n1]
  132. $else croak Can't get the page to load!
  133. $fi
  134. $rtnc $none
  135. ld.np1==.-proc$
  136. setz
  137. sixbit /corblk/
  138. 5000,,%cbndr+%cbcpy ; copy, read
  139. n0 ; arg1 = 0 (no mod to ctrl bits)
  140. 1000,,%jself ; job = self
  141. n2 ; page number
  142. setz n1 ; channel #
  143. ld.np2==.-proc$
  144. setz
  145. sixbit /corblk/
  146. 5000,,%cbndr+%cbndw ; read & write the page
  147. n0 ; arg1 = 0 (no mod to ctrl bits)
  148. 1000,,%jself ; job = self
  149. n2 ; page number
  150. setzi %jsnew ; try for new page
  151. corp load$page,[chan,addr]
  152. ; Fload takes a string for a file name, then attempts
  153. ; to open a load file by that name. If successful it
  154. ; calls Load on the resulting channel.
  155. proc ld.fl,[name],[chan],[0]
  156. slink def, bin
  157. call %str$concat,2,[name(er),def(lr)]
  158. slink lnk,readb
  159. call chan$open,2,[lnk(lr),rr]
  160. movem rr,chan(er)
  161. $if hlrz n1,rr
  162. cain n1,(tchan)
  163. $then slink lnk,Fload could not open a channel for
  164. call %str$concat,2,[lnk(lr),name(er)]
  165. $rtn rr
  166. $fi
  167. call load,1,[chan(er)] ; load the file
  168. movem rr,name(er)
  169. call chan$close,1,[chan(er)] ; close the channel
  170. $rtn name(er)
  171. corp fload,[name],[chan],[0]
  172. ; Load takes an open channel, then reads in what had
  173. ; better be a load file. To wit, there should be a
  174. ; JRST 1 in the first page of the file, followed by
  175. ; blocks with the format:
  176. ; 0: -N,,addr
  177. ; 1-N: data
  178. ; N: checksum
  179. ; This loading process runs out when a block is found
  180. ; with N = 0. The first block to be loaded must be in
  181. ; the "load block" format given here:
  182. ld.cod== 0 ; tvec+5
  183. ld.siz== 1 ; size of load file
  184. ld.low== 2 ; virtual low bound
  185. ld.ent== 3 ; ref to entry block vector
  186. ld.ver== 4 ; CLU version number
  187. ld.ref== 5 ; ptr to ref area
  188. ; Load then calls Load$fix to fix up the loaded stuff,
  189. ; then runs around making the entry blocks happy and
  190. ; entering them into the module table.
  191. proc ld.ld,[chan],[lolim,size,reloc,source,srclen],[0,0,0,0,0]
  192. call load$page,2,[chan(er),$work]
  193. movei n1,1
  194. hrli n1,(jrst)
  195. move r0,$work
  196. hrli r0,-pgsize
  197. .here ld.ld1 ; Scan for a JRST 1 to start the file.
  198. camn n1,(r0)
  199. jrst ld.ld2(pr)
  200. aobjn r0,ld.ld1(pr)
  201. jrst ld.lde(pr) ; there had better be one!
  202. .here ld.ld2 ; Get the descriptor block & check it
  203. movei n1,6
  204. hrli n1,(tvec)
  205. came n1,ld.cod+2(r0) ; the first word must be tvec+6
  206. jrst ld.lde(pr)
  207. hrrz n1,1(r0) ; get the low addr from load format
  208. hrrz n2,2+ld.low(r0) ; and from the load block itself
  209. came n1,n2
  210. jrst ld.lde(pr) ; they had better match!
  211. movem n2,lolim(er) ; save the low limit
  212. hlrz n3,2+ld.ver(r0) ; get the version number
  213. caie n3,ones&(myvers); compare against format part
  214. jrst ld.lde(pr) ; otherwise we goof off
  215. hrrz n1,2+ld.siz(r0)
  216. movem n1,size(er) ; and the size of the memory
  217. hrli n1,(twvec)
  218. alloc (n1),n1 ; grab enough memory to load into
  219. gclock ; stop any GC's
  220. hrroi r1,0(rr) ; point at the memory
  221. movem r1,reloc(er) ; save that address
  222. movei n3,0 ; clear to force new virtual ptr
  223. .here ld.ld3
  224. jumpl r0,ld.ld4(pr) ; if work ptr is valid, then use it
  225. hrrm n3,source(er) ; save the virtual ptr
  226. hlrm n3,srclen(er)
  227. call load$page,2,[chan(er),$work] ; grab the page
  228. move r0,$work
  229. hrli r0,-pgsize ; get ptr to the work area
  230. move n3,source(er) ; get virtual ptr
  231. hrl n3,srclen(er) ; and the length
  232. .here ld.ld4
  233. jumpl n3,ld.ld6(pr) ; if we can load another word, do so
  234. aobjn r0,ld.ld5(pr) ; skip checksum & check for new page needed
  235. call load$page,2,[chan(er),$work] ; grab the page
  236. move r0,$work
  237. hrli r0,-pgsize ; get ptr to the work area
  238. .here ld.ld5
  239. $if skipge n3,(r0) ; get new virtual ptr & check for loading done
  240. $then call load$fix,5,[reloc(er),size(er),lolim(er),size(er),reloc(er)]
  241. move r0,reloc(er) ; get the first word address
  242. $if skipn r1,ld.ref(r0) ; if there are strings to fix up
  243. $then add r0,ld.siz(r0)
  244. hrli r0,(trel)
  245. move g1,r0
  246. $loop ; then start to fix them
  247. hrli r1,(trel)
  248. $if camge r1,g1 ; test for end of area
  249. $then $go sfixed
  250. $fi
  251. hlrz n2,(r1)
  252. $if caie n2,(tsrep) ; fix the string
  253. $then hrli r1,(trel)
  254. push sp,g1
  255. call load$string_fix,1,[r1]
  256. pop sp,g1
  257. move r1,rr
  258. $elf caie n2,(tarep) ; skip the array block
  259. $then addi r1,3
  260. $elf cail n2,typrep
  261. cail n2,typrsb
  262. $then hrrz n1,(r1)
  263. addi r1,(n1) ; skip the block
  264. $else aos r1 ; skip any other word
  265. $fi
  266. $pool
  267. $label sfixed
  268. $fi
  269. move r0,reloc(er) ; get the first word address
  270. $for all,rr,call loopv,1,[ld.ent(r0)] ; for all entry blocks, do
  271. push sp,(rr) ; save the entry block
  272. call pname,1,[(rr)] ; get the name it wants
  273. push sp,rr ; save that, too
  274. $if camn rr,$nulls
  275. $then call %table$value,2,[$mtab,rr] ; get old entry
  276. pop sp,g0 ; restore the name
  277. pop sp,g1 ; restore the entry
  278. push sp,rr ; save the old guy
  279. hrrz r0,rr
  280. $if cail r0,stack
  281. $then croak Attempt to redefine an initial module !
  282. $fi
  283. call %table$enter,3,[$mtab,g0,g1]
  284. pop sp,rr ; restore the old guy
  285. $if camn rr,$none
  286. $then movei n1,relink ; change setup call
  287. hrrm n1,en.set(rr) ; to relink
  288. $fi
  289. $fi
  290. $rof all
  291. move rr,chan(er)
  292. jrst ld.ldx(pr)
  293. $fi
  294. aobjp r0,ld.ld3(pr) ; skip over block ptr word & get new page if needed
  295. .here ld.ld6 ; come here to move a bunch of words
  296. ; n3 is aobjn to virtual area
  297. ; r0 is aobjn to work area
  298. hlre n2,n3
  299. movn n2,n2 ; get length of virtual ptr
  300. hlre n1,r0
  301. movn n1,n1 ; and length of work ptr
  302. camle n1,n2
  303. exch n1,n2 ; n1 now has min length to blt
  304. hrrz n0,n3
  305. sub n0,lolim(er)
  306. jumpl n0,ld.lde(pr) ; if low limit too low, error
  307. hrrz br,reloc(er)
  308. add br,n0 ; save for destination address
  309. add n0,n1 ; add in blt length
  310. camle n0,size(er)
  311. jrst ld.lde(pr) ; if too long to blt, then error
  312. hrrz r1,br ; get dest address
  313. addi r1,-1(n1) ; find last word address
  314. hrl br,r0 ; get work area address as source
  315. blt br,(r1) ; move all possible words
  316. hrl n1,n1 ; duplicate the size moved
  317. add n3,n1 ; update the aobjn ptrs
  318. add r0,n1
  319. jrst ld.ld3(pr) ; and go test for source acceptability
  320. .here ld.lde
  321. croak Bad load file!!!!
  322. slink lnk,Load failed.
  323. move rr,lnk(lr)
  324. .here ld.ldx
  325. gcsafe
  326. $rtn rr
  327. corp load,[chan],[lolim,size,reloc,source,srclen]
  328. ; Load$fix(src,srclen,reflow,reflen,reloc) scans the
  329. ; area from src for srclen, looking for references to
  330. ; the area from reflow to reflen, and relocates such
  331. ; references to point at the area starting at reloc.
  332. ; macro to perform one case
  333. define .case x
  334. jrst lf.nxt(pr)
  335. $elf caie n2,(t!x)
  336. $then .case.==0
  337. termin
  338. ; macro to skip a word of rsb's
  339. define .skip pos
  340. ifsn pos,,[
  341. kvetch pos-.case.,n,Bad position in .skip pos !
  342. .case.==.case.+1
  343. ]
  344. aobjp r0,lf.ex(pr)
  345. move n1,(r0)
  346. termin
  347. ; macro to relocate the right half of current word
  348. define .rel pos
  349. ifsn pos,,[
  350. kvetch pos-.case.,n,Bad position in .rel pos !
  351. .case.==.case.+1
  352. ]
  353. jsp r1,lf.rel(pr)
  354. termin
  355. ; macro to relocate both halves of current word
  356. define .pair pos
  357. ifsn pos,,[
  358. kvetch pos-.case.,n,Bad position in .pair pos !
  359. .case.==.case.+1
  360. ]
  361. jsp r1,lf.par(pr)
  362. termin
  363. ; macro to snap setup words
  364. define .set pos
  365. ifsn pos,,[
  366. kvetch pos-.case.,n,Bad position in .set pos !
  367. .case.==.case.+1
  368. ]
  369. jsp r1,lf.set(pr)
  370. termin
  371. proc ld.fx,[src,srclen,reflow,reflen,reloc]
  372. move r0,src(er)
  373. movn n1,srclen(er)
  374. hrl r0,n1 ; r1 is aobjn to source for fix
  375. hrrz g0,reflow(er) ; g0 points to ref bottom
  376. hrrz n3,reflen(er) ; n3 is size of ref area
  377. move g1,reloc(er) ; g1 points to start of reloc area
  378. .here lf.get
  379. $crtnc r0,ge,$none
  380. move n1,(r0)
  381. .here lf.nxt
  382. .case.==0
  383. hlrz n2,n1
  384. $if skipl n1
  385. $then .rel
  386. $elf cail n2,typlo
  387. $then .skip
  388. $elf cail n2,typrep
  389. $then .rel
  390. $elf caige n2,(tbad)
  391. $then .skip
  392. $elf caige n2,typrsb
  393. $then $if cail n2,typref
  394. $then .skip
  395. $elf cail n2,typusr
  396. $then .rel
  397. $else croak User relocation not yet implemented!
  398. .skip
  399. $fi
  400. .case arep ; arrays
  401. .skip ar.cod
  402. .rel ar.vec
  403. .rel ar.rel
  404. .case crep ; call blocks
  405. .skip pc.cod
  406. .set pc.set
  407. .skip pc.num
  408. .case drep ; descriptors
  409. .skip td.cod
  410. .rel td.fix
  411. .skip td.opt
  412. .case erep ; entry blocks
  413. .skip en.cod
  414. .set en.set
  415. .pair en.lpr
  416. movs n1,n1 ; en.vi is (ref+1,,rsb)
  417. sos n1
  418. movem n1,(r0)
  419. .rel en.vi
  420. move n1,-1(r0)
  421. aos n1
  422. movsm n1,-1(r0)
  423. .pair en.par
  424. .rel en.tr
  425. .case orep ; oneofs
  426. .skip on.cod
  427. .case prep ; pure parts
  428. .skip pr.cod
  429. sos n1 ; adjust because r0 is one farther
  430. hrl n1,n1
  431. add r0,n1
  432. jrst lf.get(pr)
  433. .case srep ; strings
  434. movei n1,bpword+bpword-1(n1)
  435. idivi n1,bpword ; get # of words to skip
  436. hrl n1,n1 ; duplicate the number
  437. add r0,n1 ; point at next stuff to fix
  438. jrst lf.get(pr)
  439. .case vec ; vectors
  440. .skip
  441. .case wvec ; word vectors
  442. hrl n1,n1
  443. add r0,n1
  444. jrst lf.get(pr)
  445. .case xrep ; ref vector
  446. hrrz n1,n1
  447. push sp,n1
  448. .skip
  449. $loop
  450. $if sosg (sp)
  451. $then .rel
  452. $else jrst lf.nxt(pr)
  453. $fi
  454. $pool
  455. $fi
  456. jrst lf.nxt(pr)
  457. .here lf.par ; reloc a pair of refs (ref,,ref)
  458. hlrz n2,n1
  459. sub n2,g0
  460. jumpl n2,lf.skp(pr)
  461. caml n2,n3
  462. jrst lf.rel(pr)
  463. add n2,g1 ; add in relocation
  464. hrlm n2,(r0) ; insert the left half back into mem
  465. .here lf.rel
  466. hrrz n1,n1
  467. sub n1,g0 ; check for validity of ref at bottom
  468. jumpl n1,lf.skp(pr)
  469. caml n1,n3 ; must be under (or at) the top, too
  470. jrst lf.skp(pr)
  471. add n1,g1 ; add in relocation
  472. hrrm n1,(r0) ; relocate the right half
  473. .here lf.skp
  474. .skip
  475. jrst (r1) ; and return to caller
  476. .here lf.set
  477. trne n1,-typlo ; check for n1 being in the common area
  478. jrst lf.skp(pr)
  479. trnn n1,-comadr
  480. jrst lf.skp(pr) ; skip if it is not
  481. hlrz n2,(n1)
  482. caie n2,(jrst) ; is it a link to a jrst ?
  483. jrst lf.skp(pr)
  484. hrr n1,(n1) ; yes, so change it
  485. movem n1,(r0)
  486. jrst lf.skp(pr) ; and go skip the word
  487. .here lf.ex ; to exit, come here
  488. $rtnc $none
  489. corp load$fix,[src,srclen,reflow,reflen,reloc]
  490. proc ld.sf,[rel]
  491. move r0,rel(er)
  492. tcheck r0,trel
  493. move rr,r0 ; save the start in rr
  494. hrli r0,(bsize)
  495. move r1,r0
  496. hrro g1,r1 ; save the start
  497. hrre n3,(r0) ; grab the size in bytes
  498. $loop
  499. $if sosl n3
  500. $then $go done
  501. $fi
  502. ildb n1,r1 ; grab byte from source
  503. $label again
  504. $if caie n1,"\
  505. $then movei n2,3
  506. movei n1,0
  507. $loop
  508. $if sosl n2
  509. $then $go next
  510. $fi
  511. $if sosl n3
  512. $then idpb n1,r0
  513. $go done
  514. $fi
  515. ildb n0,r1
  516. $if cail n0,"0
  517. caile n0,"7
  518. $then rot n1,3
  519. andi n0,7
  520. add n1,n0
  521. sos (rr) ; keep track of chars missed
  522. $else idpb n1,r0
  523. move n1,n0
  524. $go again
  525. $fi
  526. $pool
  527. $fi
  528. $label next
  529. idpb n1,r0 ; deposit byte to dest
  530. $pool
  531. $label done
  532. movei n1,0
  533. $loop
  534. $if came r0,r1
  535. $then hrrz n1,(rr) ; and the number of bytes
  536. addi n1,bpword+bpword-1 ; adjust to get # of words
  537. idivi n1,bpword
  538. add rr,n1 ; skip them
  539. $rtn rr ; and return the ptr
  540. $fi
  541. idpb n1,r0 ; clear out remainder of string
  542. $pool
  543. corp load$string_fix,[rel]
  544. retsulc %load