start.1 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. loc syslo
  2. nulls$==. ; MUST be at syslo !!!!
  3. tsrep
  4. 0
  5. skippy: twvec+skplen ; This causes GC to skip the next words
  6. ; global locations for routines to use
  7. gcon $tyo,tchan+ttyocn ; default tty output
  8. gcon $tyi,tchan+ttyicn ; default tty input
  9. gcon $work,trel+work$ ; a page to work with
  10. gcon $ents,tref+ents$
  11. define trent name,info,cause
  12. jsp r0,tracer
  13. 0
  14. jrst name+1
  15. info
  16. strlit cause
  17. termin
  18. tr.jsp==0
  19. tr.xct==1
  20. tr.fix==2
  21. tr.inf==3
  22. tr.str==4
  23. tr.nxt==5
  24. ; Here is the data used to initially clear some memory
  25. brinit: gclo,,gclo+1 ; when this is clear, all is clear
  26. memget: setz
  27. sixbit /corblk/
  28. movei %cbndw+%cbndr
  29. movei -1
  30. move n1
  31. setzi %jsnew
  32. trtab: 0 ; the global tracing flag & fixup table
  33. 0 ; the global trace routine to call
  34. ; must get fixed specially for GC
  35. trent set.t, 0,enter
  36. trent qset.t, 0,enter
  37. trent exiter, 0,exit
  38. trent mexit, 0,exit
  39. trent yield, 0,yield
  40. trent myield, 0,yield
  41. trent resume, 0,resume
  42. trent sigout, 0,signal
  43. 0 ? 0 ? 0 ? 0 ? 0
  44. skplen==.-skippy
  45. cluster %start,0,0
  46. proc .base,[]
  47. $go doit
  48. start: movei sp,stack+1
  49. move er,sp ; and the pseudo-frame at bottom
  50. setzm (er)
  51. movei mr,.base
  52. hrlzm mr,-1(er)
  53. move pr,en.lpr(mr)
  54. movs lr,pr
  55. .open ttyicn,1+[twvec+5 ? sixbit / tty/ ? sixbit /tty/ ? sixbit /in/ ? 0 ]
  56. setz
  57. .open ttyocn,1+[twvec+5 ? sixbit / 1tty/ ? sixbit /tty/ ? sixbit /out/ ? 0 ]
  58. setz
  59. $if skipn br,brinit ; ensure clear gc-mem
  60. $then movei n1,gclo/pgsize
  61. hrli n1,-memlen/pgsize
  62. .call memget ; ask system for initial memory
  63. croak Can't get initial memory!
  64. setzm gclo ; clear the first word
  65. blt br,gchi ; and all others
  66. setzm brinit ; DON'T do it again!
  67. $fi
  68. ; Here we setup the MPV handler.
  69. movei r0,int.tb
  70. hrli r0,-int.sz
  71. movem r0,42 ; set the interrupt vector
  72. hrrz r1,pr
  73. movei r0,mpv.su
  74. hrli r0,-mpv.sx
  75. .suset r0 ; set the options
  76. jrst ready ; make us ready to go
  77. mpv.in: hrrz r0,$memhi ; r0 is highest free addr + 1
  78. hrrz r1,$memlo ; r1 is lowest free addr
  79. camge r0,r1 ; if highest < lowest
  80. jrst mpv.i1 ; then more mem needed
  81. hrli sp,(tref)
  82. camge sp,$stkhi ; test for stack error
  83. pushj sp,mpvout ; not an alloc error or a stack error
  84. hrrz r0,$stkhi
  85. aos r0
  86. caile r0,-4*pgsize(r1); test for collision with free mem
  87. pushj sp,memout ; collision means death
  88. idivi r0,pgsize ; page to allocate
  89. hrro n1,r0 ; allocate one page (-1 in LH)
  90. .call memget ; call to allocate that page
  91. pushj sp,memout ; croak on no memory
  92. move r0,$stkhi
  93. aos r0
  94. setzm (r0) ; clear the first word
  95. movei br,1(r0)
  96. hrl br,r0
  97. blt br,pgsize-1(r0) ; clear the stack page
  98. movei n1,pgsize
  99. addm n1,$stkhi ; show the new limit
  100. jrst mpv.ex ; and go back to user
  101. ; We get here when we know that an alloc failed to get mem.
  102. ; New pages are required, otherwise we can't continue.
  103. mpv.i1: andi r0,-pgsize
  104. subi r0,4*pgsize ; alloc 4 more pages than we need
  105. caige r0,4*pgsize(sp)
  106. pushj sp,memout ; can't get more memory
  107. move g0,r0 ; g0 now has future $memlo
  108. sub r0,r1
  109. idivi r0,pgsize
  110. hrl n1,r0 ; length (in pages) to get
  111. hrrz r0,g0
  112. idivi r0,pgsize
  113. hrr n1,r0 ; start page to alloc
  114. .call memget ; get new pages
  115. pushj sp,memout
  116. hrrz r0,g0
  117. setzm (g0) ; clear out first word
  118. movei br,1(g0) ; we blt on top of ourselves
  119. hrl br,g0
  120. move r1,$memlo ; the top of the new area + 1
  121. blt br,-1(r1) ; clear the memory
  122. hrrm g0,$memlo ; and give the new limit
  123. mpv.ex: .call mpv.di ; dismiss the interrupt & retry the alloc
  124. pushj sp,memout
  125. pushj sp,memout
  126. mpv.di: setz
  127. sixbit /dismis/
  128. movsi 20
  129. setz mpv.sp
  130. mpv.su: .soption,,1+[twvec+2 ? (optopc+optint)] ; new style interrupts
  131. .smask,,int.tb+1 ; MPV stuff & pure writes only
  132. .spirq,,mpv.ze ; forget pending interrupts
  133. .sifpir,,mpv.ze ; in both words
  134. .sdf1,,mpv.ze ; clear the defer words
  135. .sdf2,,mpv.ze
  136. mpv.sx==.-mpv.su
  137. mpv.ze: 0
  138. int.tb: 20,,mpv.sp
  139. %piwro+%pimpv ; MPV & pure write enable only
  140. 0
  141. -1 ; defer everything
  142. -1
  143. mpv.in ; the handler
  144. int.sz==.-int.tb
  145. mpv.sp: -40,,.+1
  146. mpv.re: block 40
  147. mpvout: croak A real MPV! (regs at mpv.re)
  148. jrst start ; if continued, restart
  149. ready: croak What do you run on, Rocket Morton? (Say Beans)
  150. ; Next we go around and around the entry blocks in our
  151. ; initial system, entering the entry blocks into the
  152. ; module table (in $mtab). We only do this if there is
  153. ; no current module table.
  154. $if skipe $mtab
  155. $then mcall tb.cr,[]
  156. movem rr,$mtab
  157. $for all,rr,mcall loopv,[$ents]
  158. push sp,(rr)
  159. mcall pname,[(rr)]
  160. pop sp,r0
  161. hrli r0,(tref)
  162. mcall tb.en,[$mtab,rr,r0]
  163. $rof all
  164. slink lnk,clusys;dsk:clusys init
  165. call xload,1,[lnk(lr)]
  166. tcheck rr,(tnone)
  167. $fi
  168. $label doit
  169. $loop
  170. call listen,2,[$tyi,$tyo]
  171. $pool
  172. $rtnc $none
  173. corp %base%,[]
  174. iter loopy,[addr,incr]
  175. $loop
  176. move r0,addr(er)
  177. $if skipe (r0)
  178. $then $rtnc $none
  179. $fi
  180. move r1,r0
  181. hrrz n0,incr(er)
  182. add r1,n0
  183. movem r1,addr(er)
  184. $yield r0
  185. $pool
  186. reti loopy,[addr,incr]
  187. iter loopv,[ptr],[p,c],[trel,0]
  188. move r0,ptr(er)
  189. move n1,(r0)
  190. tcheck n1,(tvec)
  191. hrrm n1,c(er)
  192. hrroi r0,1(r0)
  193. $loop
  194. $if sosle c(er)
  195. $then $rtnc $none
  196. $fi
  197. movem r0,p(er)
  198. $yield r0
  199. aos r0,p(er)
  200. $pool
  201. reti loopv,[ptr],[p,c]
  202. proc tr.on,[p]
  203. move r1,p(er)
  204. move r0,$trtab
  205. movem r1,1(r0) ; set the trace routine regardless
  206. $if skipn (r0) ; if already tracing
  207. $then $rtnc $none ; then leave now
  208. $fi
  209. addi r0,2 ; point at first entry
  210. hrli r0,(jrst)
  211. $if skipn tr.xct(r0) ; if already fixed up
  212. $then aos -2(r0) ; then just bump the trace flag
  213. $rtnc $none ; and exit
  214. $fi
  215. $loop
  216. $if skipe r1,tr.fix(r0) ; test for end of table
  217. $then move r0,$trtab ; if the end, then
  218. aos (r0) ; turn the trace flag on
  219. $rtnc $none ; and exit
  220. $fi
  221. move n1,-1(r1) ; grab the normal contents
  222. movem n1,tr.xct(r0) ; save it to execute later
  223. movem r0,-1(r1) ; hit the instruction with a jump
  224. addi r0,tr.nxt ; move to next item
  225. $pool
  226. corp trace_on,[p]
  227. proc tr.of
  228. move r0,$trtab
  229. setzm (r0) ; turn trace flag off
  230. $rtnc $none
  231. corp trace_off
  232. proc tr.fl
  233. move r0,$trtab
  234. setzm (r0) ; turn the trace flag off
  235. setzm 1(r0) ; clear out the trace routine
  236. addi r0,2 ; move ptr to first entry
  237. $loop
  238. $if skipe r1,tr.fix(r0) ; test for end of table
  239. skipn n1,tr.xct(r0) ; or for no fix to make
  240. $then movem n1,-1(r1) ; and restore normal contents
  241. setzm tr.xct(r0) ; clear out the table
  242. addi r0,tr.nxt ; move to next item
  243. $else $for all,rr,call %table$values,1,[$mtab]
  244. setzm en.tr(rr) ; clear each proc's trace flags
  245. $rof all
  246. $rtnc $none
  247. $fi
  248. $pool
  249. corp trace_flush
  250. proc xfind,[s]
  251. mcall tb.va,[$mtab,s(er)]
  252. $rtn rr
  253. corp xfind,[s]
  254. proc pfind,[s]
  255. mcall tb.va,[$mtab,s(er)]
  256. $if came rr,$none
  257. $then $rtn rr
  258. $fi
  259. hrrz r0,en.lpr(rr) ; get the pure part
  260. $if skipe r0
  261. $then $rtnc $none
  262. $fi
  263. tcheck pr.cod(r0),tprep
  264. $rtn rr
  265. corp pfind,[s]
  266. proc plist,[]
  267. call crlf,1,[$tyo]
  268. $for all,rr,call %table$names,1,[$mtab]
  269. call chan$writes,2,[$tyo,rr]
  270. call crlf,1,[$tyo]
  271. $rof all
  272. $rtnc $none
  273. corp plist,[]
  274. proc xlist,[]
  275. mcall crlf,[$tyo]
  276. $for all,rr,mcall tb.in,[$mtab]
  277. mcall ch.ws,[$tyo,rr]
  278. mcall crlf,[$tyo]
  279. $rof all
  280. $rtnc $none
  281. corp xlist,[]
  282. ; all_procs is an iterator that yields all currently known
  283. ; procedures.
  284. proc allpr,[]
  285. $for all,rr,call %table$values,1,[$mtab]
  286. $yield rr
  287. $rof all
  288. $rtnc $none
  289. corp all_procs,[]
  290. proc crlf,[chan]
  291. link cr,tchar+12
  292. mcall ch.wc,[chan(er),cr(lr)]
  293. $rtnc $none
  294. corp crlf,[chan]
  295. proc siggy,[nargs,eblk],[name],[0]
  296. move r0,eblk(er)
  297. assn name(er),td.nam(r0)
  298. $loop
  299. mcall crlf,[$tyo]
  300. slink lnk,signal:
  301. mcall ch.ws,[$tyo,lnk(lr)]
  302. mcall ch.ws,[$tyo,name(er)]
  303. mcall crlf,[$tyo]
  304. croak signal not yet implemented.
  305. $pool
  306. $rtnc $none
  307. corp siggy,[nargs,eblk],[name]
  308. proc pname,[p]
  309. hrrz r1,p(er) ; grab the entry block
  310. $if cail r1,pgsize
  311. cail r1,gchi
  312. $then
  313. hrrz r0,en.lpr(r1) ; get the procedure in it
  314. $if skipe r0
  315. $then hlrz r0,en.lpr(r1) ; not a procedure, get the linkage sect
  316. move rr,1(r0) ; name is first string in linkage sect
  317. $else add r0,pr.nam(r0) ; point at the proc name
  318. move rr,(r0) ; get the name of the procedure
  319. $fi
  320. tcheck rr,tstr ; make sure that it is a string !
  321. $else
  322. slink lnk,?proc?
  323. move rr,lnk(lr)
  324. $fi
  325. $rtn rr ; return the name
  326. corp pname,[p]
  327. proc print,[chan,x]
  328. hlrz n1,x(er)
  329. $if caie n1,(tstr)
  330. $then link lnk,tstr+""
  331. mcall ch.ws,[chan(er),lnk(lr)]
  332. mcall ch.ws,[chan(er),x(er)]
  333. mcall ch.ws,[chan(er),lnk(lr)]
  334. $elf caie n1,(tnone)
  335. $then
  336. $elf caie n1,(tchar)
  337. $then slink lnk,'
  338. mcall ch.ws,[chan(er),lnk(lr)]
  339. mcall ch.wc,[chan(er),x(er)]
  340. mcall ch.ws,[chan(er),lnk(lr)]
  341. $elf caie n1,(tnull)
  342. $then slink lnk,null
  343. mcall ch.ws,[chan(er),lnk(lr)]
  344. $elf caie n1,(tint)
  345. $then call int$i2s,1,[x(er)]
  346. mcall ch.ws,[chan(er),rr]
  347. $elf caie n1,(tbool)
  348. $then hrrz n1,x(er)
  349. slink lnk,true
  350. move rr,lnk(lr)
  351. caie n1,true
  352. slink lnk,false
  353. move rr,lnk(lr)
  354. mcall ch.ws,[chan(er),rr]
  355. $elf caie n1,(tpcb)
  356. $then slink lnk,pcb#
  357. mcall ch.ws,[chan(er),lnk(lr)]
  358. mcall octal,[x(er)]
  359. mcall ch.ws,[chan(er),rr]
  360. slink lnk, :
  361. mcall ch.ws,[chan(er),lnk(lr)]
  362. move r0,x(er)
  363. mcall ch.ws,[chan(er),pc.str(r0)]
  364. slink lnk,,
  365. mcall ch.ws,[chan(er),lnk(lr)]
  366. move r0,x(er)
  367. move n1,pc.num(r0)
  368. hrli n1,(tint)
  369. mcall print,[chan(er),n1]
  370. $else $if movei rr,0
  371. cail n1,typlo
  372. caile n1,typhi
  373. $then move rr,(n1)
  374. $fi
  375. $if hlrz n2,rr
  376. caie n2,(tstr)
  377. $then
  378. mcall ch.ws,[chan(er),(n1)]
  379. $else
  380. mcall octal,[n1]
  381. mcall ch.ws,[chan(er),rr]
  382. $fi
  383. slink lnk,#
  384. mcall ch.ws,[chan(er),lnk(lr)]
  385. mcall octal,[x(er)]
  386. mcall ch.ws,[chan(er),rr]
  387. $fi
  388. $rtnc $none
  389. corp print,[chan,x]
  390. proc octal,[x]
  391. hrlz n3,x(er)
  392. movei n1,6
  393. hrro r1,sp
  394. .here octal1
  395. movei n2,0
  396. rotc n2,3
  397. addi n2,"0
  398. push sp,n2
  399. sojg n1,octal1(pr)
  400. movei n1,6
  401. movei n2,(wsize)
  402. mcall tp2s,[r1,n1,n2]
  403. $rtn rr
  404. corp octal,[x]
  405. proc restrt
  406. jrst start
  407. $rtnc $none
  408. corp restart
  409. proc dtyi
  410. $rtnc $tyi
  411. corp dtyi
  412. proc dtyo
  413. $rtnc $tyo
  414. corp dtyo
  415. ; the following routine displays a stack frame,
  416. ; giving name of procedure and arguments.
  417. proc framp,[tyo,frm],[p,n,lonam,loarg],[trel,0,trel,trel]
  418. tcheck frm(er),trel
  419. mcall crlf,[tyo(er)]
  420. move g0,frm(er) ; g0 points to frame
  421. hlrz r0,-1(g0)
  422. hrrm r0,p(er) ; r0 has ptr to procedure entry
  423. mcall pname,[p(er)] ; call to get proc name & check validity
  424. mcall ch.ws,[tyo(er),rr]
  425. slink lnk, has a frame at
  426. mcall ch.ws,[tyo(er),lnk(lr)]
  427. mcall octal,[frm(er)]
  428. mcall ch.ws,[tyo(er),rr] ; print frame address
  429. mcall crlf,[tyo(er)]
  430. move g0,p(er) ; entry block for procedure
  431. $if trnn g0,-pgsize
  432. $then
  433. hrrz r0,en.lpr(g0) ; pure part of procedure (the pr)
  434. hrre n0,pr.cut(r0) ; number of arguments in n0
  435. subi n0,2 ; must be adjusted by 2
  436. movem n0,n(er)
  437. add r0,pr.nam(r0) ; ptr to one less than argument names
  438. hrrm r0,lonam(er) ; gets saved
  439. hrrz r1,frm(er) ; get the frame back again
  440. subi r1,2 ; point at the arguments
  441. sub r1,n0 ; ptr to one less than lowest arg
  442. hrrm r1,loarg(er) ; & save that ptr
  443. $loop
  444. $if sosl n(er)
  445. $then $rtnc $none
  446. $fi
  447. link lnk,tchar+11
  448. mcall ch.wc,[tyo(er),lnk(lr)] ; print a tab
  449. aos r0,lonam(er) ; advance the name ptr
  450. mcall ch.ws,[tyo(er),(r0)] ; print a name
  451. slink lnk,:
  452. mcall ch.ws,[tyo(er),lnk(lr)] ; print ":\11"
  453. aos r0,loarg(er) ; advance the arg ptr
  454. mcall print,[tyo(er),(r0)] ; print the argument
  455. mcall crlf,[tyo(er)] ; end-of-the-line
  456. $pool
  457. $fi
  458. $rtnc $none
  459. corp framp,[tyo,frm],[p,n,lonam,loarg]
  460. proc frall,[tyo],[frm],[trel]
  461. hrrm er,frm(er)
  462. $loop
  463. hrrz r0,frm(er)
  464. hrrz r0,(r0)
  465. $if trne r0,-lolim
  466. $then $rtnc $none
  467. $fi
  468. hrrm r0,frm(er)
  469. mcall framp,[tyo(er),frm(er)]
  470. $pool
  471. corp frall,[tyo],[frm]
  472. ; This is a fake entry for the linker
  473. proc %linkf
  474. croak How the hell did you get to %linkf ?
  475. $rtnc $none
  476. corp %linker
  477. retsulc start