home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume7 / basic / part05 < prev    next >
Encoding:
Internet Message Format  |  1986-12-03  |  57.5 KB

  1. Subject:  v07i077:  A BASIC Interpreter, Part05/06
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: phil@Cs.Ucl.AC.UK
  6. Mod.sources: Volume 7, Issue 77
  7. Archive-name: basic/Part05
  8.  
  9. # Shar file shar05 (of 6)
  10. #
  11. # This is a shell archive containing the following files :-
  12. #    pdp11/assist.s
  13. #    pdp11/conf.h
  14. #    pdp11/fpassist.s
  15. #    pdp11/lfunc.s
  16. #    pdp11/nfp.s
  17. #    pdp11/term.c
  18. #    pyramid/Makefile
  19. # ------------------------------
  20. # This is a shell archive, shar, format file.
  21. # To unarchive, feed this text into /bin/sh in the directory
  22. # you wish the files to be in.
  23.  
  24. echo x - pdp11/assist.s 1>&2
  25. sed 's/^X//' > pdp11/assist.s << 'End of pdp11/assist.s'
  26. X/       (c) P. (Rabbit) Cockcroft 1982
  27. X/   This file contains machine code routines that either can't
  28. X/   be implemented or are very slow in C.
  29. X/
  30. X
  31. X/   When the 'shell' command was first added it was noticed that
  32. X/   it would bus-error about five times ( an old form of memory
  33. X/   allocation was being used at the time ) before it started to
  34. X/   do the wait. The reason for this is rather awful. In the call
  35. X/   it uses _nargs to find how many arguments it has got. This is
  36. X/   a routine that will not work in split i and d space, since it tries
  37. X/   to access the text segment.
  38. X/       The routine was thus taken from the C library and has been changed
  39. X/   to need no parameters. It just returns -1 on error or the waited for's
  40. X/   process id.
  41. X/
  42. X/ pid == -1 if error
  43. X
  44. X.globl  _wait, cerror
  45. X
  46. Xwait = 7.
  47. X
  48. X_wait:
  49. X    mov     r5,-(sp)
  50. X    mov     sp,r5
  51. X    sys     wait
  52. X    bec     1f
  53. X    jmp     cerror
  54. X1:
  55. X    tst     4(r5)
  56. X    beq     1f
  57. X    mov     r1,*4(r5)
  58. X1:
  59. X    mov     (sp)+,r5
  60. X    rts     pc
  61. X
  62. X/   getch() is used all over the place to get the next character on the line.
  63. X/   It uses 'point' ( _point ) as the pointer to the next character.
  64. X/   It skips over all leading spaces.
  65. X/       It was put into machine code for speed since it does not have to
  66. X/   call csv and cret ( the C subroutine call and return routines ).
  67. X/   this saves a lot of time. It can also be written more efficiently
  68. X/   in machine code.
  69. X/
  70. X
  71. X.text
  72. X.globl  _point , _getch
  73. X
  74. X_getch:
  75. X    mov     _point,r1
  76. X1:      cmpb    $40,(r1)+       / ignore spaces
  77. X    beq     1b
  78. X    mov     r1,_point
  79. X    clr     r0
  80. X    bisb    -(r1),r0
  81. X    rts     pc
  82. X
  83. X/   check() is used by many routines that want to know if there is any
  84. X/   garbage characters after its arguments. e.g. in 'goto' there
  85. X/   should be nothing after the line number. It gives a SYNTAX
  86. X/   error if the next character is not a terminator.
  87. X/   check() was also taken out of C for speed reasons.
  88. X
  89. X.globl  _point  , _check   , _elsecount  , _error
  90. X
  91. XELSE=   0351
  92. X
  93. X_check:
  94. X    mov     _point,r0
  95. X1:      cmpb    $40,(r0)+
  96. X    beq     1b
  97. X    movb    -(r0),r1
  98. X    beq     1f
  99. X    cmpb    r1,$':
  100. X    beq     1f
  101. X    cmpb    r1,$ELSE
  102. X    bne     2f
  103. X    tstb    _elsecount
  104. X    beq     2f
  105. X1:      mov     r0,_point
  106. X    rts     pc
  107. X2:      mov     $1,-(sp)        / syntax error
  108. X    jsr     pc,_error
  109. X
  110. X/   startfp() this is called in main to intialise the floating point
  111. X/   hardware if it is used. it is only called once to set up fpfunc()
  112. X/   this routine does nothing in non-floating point hardware machines
  113. X/
  114. X.globl  _startfp  ,  _fpfunc
  115. X
  116. X_startfp:
  117. X    clr     _fpfunc
  118. X    rts     pc
  119. X
  120. X.bss
  121. X_fpfunc: .=.+2
  122. X.text
  123. X
  124. X/   getop() will convert a number into in ascii form to a binary number
  125. X/   it returns non-zero if the number is ok, with the number in
  126. X/   the union 'res'. It uses the floating point routines (nfp.s) and
  127. X/   some of its storage locations ( areg ) to do the hard work.
  128. X/   If the number will fit into an integer, then the value returned is an
  129. X/   integer, with 'vartype' set accordingly. This convertion to integers
  130. X/   is only operative if the convertion needed is an easy one.
  131. X/   Zero is always returned as an integer.
  132. X/       This routine was written in assembler since it is impossible
  133. X/   to write in C.
  134. X
  135. X.globl  _getop
  136. X_getop:
  137. X    jsr     r5,csv
  138. X    mov     $areg,r0
  139. X    clr     (r0)+
  140. X    clr     (r0)+
  141. X    clr     (r0)+
  142. X    clr     (r0)+
  143. X    clr     aexp
  144. X    clr     dpoint
  145. X    clr     dflag
  146. X    mov     $1,asign
  147. X    clrb    _vartype
  148. X    clr     count           / number of actual digits
  149. X1:      movb    *_point,r4
  150. X    inc     _point
  151. X    cmp     r4,$'.
  152. X    bne     4f
  153. X    tst     dflag           / decimal point
  154. X    bne     out1            / already had one so get out of loop
  155. X    inc     dflag           / set the decimal point flag.
  156. X    br      1b
  157. X4:
  158. X    cmp     r4,$'0
  159. X    blt     out1
  160. X    cmp     r4,$'9
  161. X    bgt     out1
  162. X    inc     count               / we have a digit
  163. X    bit     $!07,areg           / enough space for another digit
  164. X    bne     2f                  / no
  165. X    sub     $'0,r4              / multiply number by ten
  166. X    mov     r4,r2               / and add the new digit.
  167. X    jsr     pc,tenmul
  168. X    tst     dflag               / if we have not had a decimal point
  169. X    beq     1b                  / don't decrement the significance
  170. X    dec     dpoint              / counter.
  171. X    br      1b
  172. X2:                                  / get here if all digits are filled
  173. X    tst     dflag               / if decimal point , forget it
  174. X    bne     1b
  175. X    inc     dpoint              / increment the significance counter
  176. X    br      1b                  / get some more.
  177. Xout1:
  178. X    tst     count               / check to see that we have had a digit
  179. X    bne     9f                  / yes then continue.
  180. X    jmp     bad                 / no goto bad.
  181. X9:      cmp     r4,$'e              / do we have an exponent.
  182. X    bne     out2                / no.
  183. X    clr     count               / count number of exponent digits
  184. X    clr     r3                  / clear exponent value
  185. X    clr     r2                  / clear exponent sign
  186. X    movb    *_point,r4
  187. X    inc     _point
  188. X    cmp     r4,$'-              / exponents sign
  189. X    bne     1f
  190. X    inc     r2                  / set the flag
  191. X    br      2f
  192. X1:      cmp     r4,$'+
  193. X    bne     3f
  194. X2:      movb    *_point,r4
  195. X    inc     _point
  196. X3:
  197. X    cmp     r4,$'0              / get the exponent digits
  198. X    blt     1f
  199. X    cmp     r4,$'9
  200. X    bgt     1f
  201. X    inc     count               / we have a digit.
  202. X    sub     $'0,r4
  203. X    cmp     r3,$1000.           / if the digit would make the exponent
  204. X    blt     7f                  / greater than ten thousand
  205. X3:                                  / for get the following digits
  206. X    movb    *_point,r4          / ( we are heading for an overflow )
  207. X    inc     _point
  208. X    cmp     r4,$'0
  209. X    blt     1f
  210. X    cmp     r4,$'9
  211. X    ble     3b
  212. X    br      1f
  213. X7:
  214. X    mul     $12,r3              / multiply the exponent by ten and
  215. X    add     r4,r3               / add the new digit.
  216. X    br      2b                  / get some more
  217. X1:
  218. X    tst     r2                  / check sign of exponent
  219. X    beq     1f
  220. X    neg     r3
  221. X1:      add     r3,dpoint           / add the exponent to the decimal
  222. X    tst     count               / point counter
  223. X    beq     bad                 / check to see if we had any digits
  224. Xout2:
  225. X    dec     _point              / adjust the character pointer
  226. X    tst     dpoint              / check to see if number can be
  227. X    ble     1f                  / multiplied by ten if need be.
  228. X2:      bit     $!07,areg
  229. X    bne     1f                  /  no
  230. X    clr     r2
  231. X    jsr     pc,tenmul           / multiply by ten
  232. X    dec     dpoint
  233. X    bne     2b
  234. X1:
  235. X    tst     areg                / check to see if we have an integer
  236. X    bne     1f
  237. X    tst     areg+2
  238. X    bne     1f
  239. X    tst     areg+4
  240. X    bne     1f
  241. X    tst     dpoint
  242. X    bne     2f
  243. X    bit     $100000,areg+6
  244. X    beq     3f
  245. X2:      tst     areg+6              / test for zero
  246. X    bne     1f
  247. X3:      mov     areg+6,_res         / yes we have an integer put the
  248. X    movb    $1,_vartype         / value in 'res' and set 'vartype'
  249. X    inc     r0                  / stop bad number error, since at this
  250. X    jmp     cret                / point r0 is zero.
  251. X1:
  252. X    mov     $56.,aexp           / convert to floating point format
  253. X    jsr     pc,norm
  254. X    tst     dpoint              / number wants to be multiplied
  255. X    ble     2f                  / by ten
  256. X    cmp     dpoint,$1000.
  257. X    bgt     bad
  258. X1:      clr     r2
  259. X    jsr     pc,tenmul           /  do it
  260. X3:      bit     $!377,areg          / normalise the number
  261. X    bne     1f
  262. X    dec     dpoint              / decrement the counter
  263. X    bne     1b
  264. X    br      2f
  265. X1:      mov     $areg,r0            / shift right to normalise
  266. X    asr     (r0)+
  267. X    ror     (r0)+
  268. X    ror     (r0)+
  269. X    ror     (r0)+
  270. X    inc     aexp
  271. X    cmp     aexp,$177
  272. X    bgt     bad
  273. X    br      3b
  274. X2:
  275. X    tst     dpoint              / wants to be divided by ten
  276. X    bge     2f
  277. X3:      mov     $3,r1
  278. X1:      mov     $areg+8,r0          / shift left to save significant
  279. X    asl     -(r0)               / digits
  280. X    rol     -(r0)
  281. X    rol     -(r0)
  282. X    rol     -(r0)
  283. X    dec     aexp
  284. X    sob     r1,1b
  285. X    jsr     pc,tendiv           / divide number by ten
  286. X1:      bit     $200,areg           / normalise number
  287. X    bne     1f
  288. X    mov     $areg+8,r0          / shift left
  289. X    asl     -(r0)
  290. X    rol     -(r0)
  291. X    rol     -(r0)
  292. X    rol     -(r0)
  293. X    dec     aexp
  294. X    br      1b
  295. X1:      inc     dpoint
  296. X    bne     3b
  297. X2:
  298. X    cmp     aexp,$177       / check for overflow
  299. X    bgt     bad
  300. X    mov     $_res,r2        / return value to 'res' via the floating
  301. X    jmp     retng           / point return routine, r0 is non-zero
  302. Xbad:    clr     r0              / bad number , clear r0
  303. X    jmp     cret            / return
  304. X
  305. X.bss
  306. Xdflag:  .=.+2                   / temporary space for decimal point counter
  307. X
  308. X.text
  309. X
  310. X/   cmp() is used to compare two numbers , it uses 'vartype' to decide
  311. X/   which kind of variable to test.
  312. X/   The result is -1,0 or 1 , depending on the result of the comparison
  313. X/
  314. X
  315. X.globl  _cmp   , _vartype
  316. X
  317. X_cmp:   mov     2(sp),r0
  318. X    mov     4(sp),r1
  319. X    tstb    _vartype
  320. X    beq     6f
  321. X    cmp     (r0)+,(r1)+
  322. X    blt     4f
  323. X    bgt     3f
  324. X5:      clr     r0
  325. X    rts     pc
  326. X3:      mov     $1,r0
  327. X    rts     pc
  328. X4:      mov     $-1,r0
  329. X    rts     pc
  330. X                / floating point comparisons
  331. X6:      tst     (r0)            / straight out of the floating
  332. X    bge     1f              / point trap routines
  333. X    tst     (r1)
  334. X    bge     1f
  335. X    cmp     (r0),(r1)
  336. X    bgt     4b
  337. X    blt     3b
  338. X1:
  339. X    cmp     (r0)+,(r1)+
  340. X    bgt     3b
  341. X    blt     4b
  342. X    cmp     (r0)+,(r1)+
  343. X    bne     1f
  344. X    cmp     (r0)+,(r1)+
  345. X    bne     1f
  346. X    cmp     (r0)+,(r1)+
  347. X    beq     5b
  348. X1:
  349. X    bhi     3b
  350. X    br      4b
  351. X
  352. X/   routine to multiply two numbers together. returns zero on overflow
  353. X/   used in dimensio() only.
  354. X
  355. X.globl  _dimmul
  356. X
  357. X_dimmul:
  358. X    mov     2(sp),r1
  359. X    mul     4(sp),r1
  360. X    bcc     1f
  361. X    clr     r1
  362. X1:      mov     r1,r0
  363. X    rts     pc
  364. X
  365. X/   The calling routines for the maths functions ( from bas3.c).
  366. X/   The arguments passed to the routines are as follows.
  367. X/       at  6(sp)   The operator funtion required.
  368. X/       at  4(sp)   The pointer to second parameter and
  369. X/                   the location where the result is to be put.
  370. X/       at  2(sp)   The pointer to the first parameter.
  371. X
  372. X/   The jump table is called by the following sequence:-
  373. X/       (*mbin[priority*2+vartype])(&j->r1,&res,j->operator)
  374. X/
  375. X/   So the values in this table are such that integer and real
  376. X/   types are dealt with separately, and the different types of operators
  377. X/   are also dealt with seperately.
  378. X/       e.g. *, /, mod for reals are dealt with by 'fmdm'
  379. X/            and , or , xor for integers are dealt with by 'andor'
  380. X/
  381. X
  382. X.globl  _mbin   , csv , cret , _error  , _fmul , _fdiv , _fadd , _fsub
  383. X
  384. X/   jump table for the maths functions
  385. X/   straight from the eval() routine in bas3.c
  386. X
  387. X.data
  388. X_mbin:  0
  389. X    0
  390. X    fandor
  391. X    andor
  392. X    comop
  393. X    comop
  394. X    fads
  395. X    ads
  396. X    fmdm
  397. X    mdm
  398. X    fex
  399. X    ex
  400. X.text
  401. X
  402. X/   locations from the jump table
  403. X/   integer exponentiation , convert to reals then call the floating
  404. X/   point convertion routines.
  405. X/
  406. X
  407. Xex:     mov     2(sp),-(sp)
  408. X    jsr     pc,_cvt
  409. X    mov     6(sp),(sp)
  410. X    jsr     pc,_cvt
  411. X    tst     (sp)+
  412. X    clrb    _vartype
  413. Xfex:    jmp     _fexp
  414. X
  415. X
  416. Xfmdm:
  417. X    cmp     $'*,6(sp)       / times
  418. X    bne     1f
  419. X    jmp     _fmul
  420. X1:
  421. X    cmp     $'/,6(sp)       / div
  422. X    bne     1f
  423. X    jmp     _fdiv
  424. X1:
  425. X    jmp     _fmod           / mod
  426. X
  427. X
  428. Xmdm:    cmp     $'*,6(sp)       / integer multiply
  429. X    bne     1f
  430. X    mov     *2(sp),r0
  431. X    mul     *4(sp),r0
  432. X    bcs     over            / overflow
  433. X    br      2f
  434. X1:      mov     *2(sp),r1       / divide or mod
  435. X    sxt     r0
  436. X    div     *4(sp),r0
  437. X    bvs     1f
  438. X    cmp     $'/,6(sp)       / div
  439. X    bne     2f              / no , must be mod.
  440. X    tst     r1
  441. X    bne     3f
  442. X    mov     r0,*4(sp)
  443. X    rts     pc
  444. X2:      mov     r1,*4(sp)
  445. X    rts     pc
  446. X1:      mov     $25.,-(sp)      / zero divisor error
  447. X    jsr     pc,_error
  448. X                / code to do integer divisions.. etc.
  449. X3:      mov     2(sp),-(sp)     / if the result of the integer division
  450. X    jsr     pc,_cvt         / is not an integer then convert to
  451. X    mov     6(sp),(sp)      / float and call the floationg point
  452. X    jsr     pc,_cvt         / routine
  453. X    clrb    _vartype
  454. X    tst     (sp)+
  455. X    jmp     _fdiv
  456. X
  457. Xfads:                           / floating add and subtract
  458. X    cmp     $'+,6(sp)
  459. X    bne     1f
  460. X    jmp     _fadd
  461. X1:
  462. X    jmp     _fsub
  463. X
  464. X
  465. Xads:    mov     *2(sp),r1
  466. X    cmp     $'+,6(sp)           / add or subtract
  467. X    bne     1f
  468. X    add     *4(sp),r1           / add
  469. X    br      2f
  470. X1:      sub     *4(sp),r1           / subtract
  471. X2:      bvs     over1               / branch on overflow
  472. X    mov     r1,*4(sp)
  473. X    rts     pc
  474. X
  475. Xover1:  tst     *2(sp)              / move value to 'overfl'
  476. X    sxt     r0
  477. Xover:   mov     r0,_overfl
  478. X    mov     r1,_overfl+2
  479. X    jmp     _over               /  return via call to 'over'
  480. X
  481. X/   comparison operators ( float and integer )
  482. X/   cmp() expects to have only two parameters . So save return address
  483. X/   and so simulate environment.
  484. X
  485. Xcomop:  mov     (sp)+,comsav        / save return address
  486. X    jsr     pc,_cmp             / call comparison routine
  487. X    mov     r0,-(sp)
  488. X    mov     6(sp),-(sp)         / call routine to convert
  489. X    jsr     pc,_compare         / this result into logical result
  490. X    tst     (sp)+
  491. X    mov     comsav,(sp)         / restore return address
  492. X    rts     pc                  / return
  493. X.bss
  494. Xcomsav: .=.+2
  495. X.text
  496. X
  497. X/   floating logical operators
  498. X/   convert floating types into integers. If the value is non zero
  499. X/   then value has a true (-1) value.
  500. X/
  501. X
  502. Xfandor:
  503. X    mov     *2(sp),r0
  504. X    beq     2f
  505. X    mov     $-1,r0
  506. X2:      mov     *4(sp),r1
  507. X    beq     2f
  508. X    mov     $-1,r1
  509. X2:      movb    $1,_vartype
  510. X    br      2f
  511. X
  512. X/   integer logical operators
  513. X/   does a bitwise operaotion on the two numbers ( in r0 , r1 ).
  514. X/
  515. X
  516. Xandor:
  517. X    mov     *2(sp),r0
  518. X    mov     *4(sp),r1
  519. X2:      cmpb    $356,6(sp)
  520. X    bne     2f
  521. X    com     r1
  522. X    bic     r1,r0
  523. X    br      1f
  524. X2:      cmp     $357,6(sp)
  525. X    bne     2f
  526. X    bis     r1,r0
  527. X    br      1f
  528. X2:      xor     r1,r0
  529. X1:      mov     r0,*4(sp)
  530. X    rts     pc
  531. X
  532. X/   This routine converts a floationg point number into an integers
  533. X/   if the result would overflow then return non zero.
  534. X/
  535. X
  536. X.globl  _conv
  537. X
  538. X_conv:
  539. X    mov     2(sp),r1
  540. X    mov     (r1)+,r0
  541. X    beq     3f
  542. X    mov     (r1),r1
  543. X    asl     r0
  544. X    clrb    r0
  545. X    swab    r0
  546. X    sub     $200,r0
  547. X    cmp     r0,$20
  548. X    bge     1f                  / overflow or underflow
  549. X    sub     $8,r0
  550. X    mov     r0,-(sp)            / counter
  551. X    mov     *4(sp),r0
  552. X    bic     $!0177,r0
  553. X    bis     $200,r0
  554. X    ashc    (sp)+,r0
  555. X    tst     *2(sp)
  556. X    bpl     3f
  557. X    neg     r0
  558. X3:
  559. X    mov     r0,*2(sp)
  560. X    clr     r0
  561. X    rts     pc
  562. X
  563. X1:      bne     1f
  564. X    cmp     *2(sp),$144000  / check for -32768
  565. X    bne     1f
  566. X    bit     r1,$177400
  567. X    bne     1f
  568. X    mov     $-32768.,r0
  569. X    br      3b
  570. X1:      rts     pc
  571. X
  572. X
  573. X/   convert from integer to floating point , this will never fail.
  574. X/
  575. X
  576. X.globl  _cvt
  577. X_cvt:   mov     r2,-(sp)
  578. X    clr     r0
  579. X    mov     *4(sp),r1
  580. X    beq     4f
  581. X    bpl     1f
  582. X    neg     r1
  583. X1:      mov     $220,r2                 /counter
  584. X    ashc    $8,r0
  585. X1:      bit     $200,r0
  586. X    bne     1f
  587. X    ashc    $1,r0
  588. X    dec     r2
  589. X    br      1b
  590. X1:      swab    r2
  591. X    ror     r2
  592. X    tst     *4(sp)
  593. X    bpl     1f
  594. X    bis     $100000,r2
  595. X1:      bic     $!177,r0
  596. X    bis     r2,r0
  597. X4:      mov     4(sp),r2
  598. X    mov     r0,(r2)+
  599. X    mov     r1,(r2)+
  600. X    clr     (r2)+
  601. X    clr     (r2)+
  602. X    mov     (sp)+,r2
  603. X    rts     pc
  604. X
  605. X/   add two numbers used in the 'next' routine
  606. X/   depends on the type of the number. calls error on overflow.
  607. X/
  608. X
  609. X.globl  _foreadd
  610. X_foreadd:
  611. X    add     2(sp),*4(sp)
  612. X    bvs     1f
  613. X    rts     pc
  614. X1:      mov     $35.,-(sp)      / integer overflow
  615. X    jsr     pc,_error
  616. X
  617. X/   This routine converts a floating point number into decimal
  618. X/   It uses the following algorithm:-
  619. X/   forever{
  620. X/       If X > 1 then {
  621. X/               X = X / 10
  622. X/               decpoint++
  623. X/               continue
  624. X/               }
  625. X/       If X < 0.1 then {
  626. X/               X = X * 10
  627. X/               decpoint--
  628. X/               continue
  629. X/               }
  630. X/           }
  631. X/       for i = 1 to 10 do {
  632. X/               digit[i] = int ( X * 10)
  633. X/               X = frac ( X * 10 )
  634. X/               }
  635. X/   This routine is not very complicated but very fiddly so was one
  636. X/   of the last ones written.
  637. X/
  638. X
  639. X
  640. X.globl  _necvt  , tendiv , tenmul
  641. X
  642. X_necvt: jsr     r5,csv          / needs to look like ecvt to
  643. X    clr     dpoint          / the outside world
  644. X    clr     *10.(r5)
  645. X    mov     $buf,r3
  646. X    mov     6(r5),r2
  647. X    mov     r2,mdigit
  648. X    inc     r2
  649. X    mov     r2,count
  650. X    tst     *4(r5)
  651. X    beq     zer
  652. X    bpl     1f
  653. X    inc     *10.(r5)        / sign part of ecvt
  654. X1:      mov     4(r5),r2
  655. X    mov     $asign,r0
  656. X    jsr     pc,seta         / set up number in areg
  657. X1:      tst     aexp
  658. X    ble     1f
  659. X    mov     $3,r1           / number is greater than one
  660. X2:      mov     $areg+8,r0
  661. X    asl     -(r0)           / save significant digits
  662. X    rol     -(r0)
  663. X    rol     -(r0)
  664. X    rol     -(r0)
  665. X    dec     aexp
  666. X    sob     r1,2b
  667. X    jsr     pc,tendiv
  668. X    inc     dpoint          / increment decimal point
  669. X2:      bit     $200,areg
  670. X    bne     1b
  671. X    mov     $areg+8,r0      / normalise after the division
  672. X    asl     -(r0)
  673. X    rol     -(r0)
  674. X    rol     -(r0)
  675. X    rol     -(r0)
  676. X    dec     aexp
  677. X    br      2b
  678. X1:
  679. X    cmp     aexp,$-3            / number greate than 0.1
  680. X    bgt     5f
  681. X    blt     2f
  682. X    cmp     areg,$314
  683. X    bgt     5f
  684. X    blt     2f
  685. X    mov     $3,r1
  686. X    mov     $areg+2,r0
  687. X3:      cmp     (r0)+,$146314
  688. X    bhi     5f
  689. X    blo     2f
  690. X    sob     r1,3b
  691. X2:                                  / no
  692. X    clr     r2
  693. X    jsr     pc,tenmul           / multiply by ten
  694. X3:      tstb    areg+1
  695. X    bne     4f
  696. X    dec     dpoint
  697. X    br      1b
  698. X4:
  699. X    mov     $areg,r0            / normalise
  700. X    asr     (r0)+
  701. X    ror     (r0)+
  702. X    ror     (r0)+
  703. X    ror     (r0)+
  704. X    inc     aexp
  705. X    br      3b
  706. X5:
  707. X    tst     aexp                / get decimal point in correct place
  708. X    beq     9f
  709. X1:      mov     $areg,r0
  710. X    asr     (r0)+
  711. X    ror     (r0)+
  712. X    ror     (r0)+
  713. X    ror     (r0)+
  714. X    inc     aexp
  715. X    bne     1b
  716. X9:
  717. X    clr     r2                  / get  the digits
  718. X    jsr     pc,tenmul
  719. X    bic     $!377,areg
  720. X    clrb    r1                  / top word in r1
  721. X    swab    r1
  722. X    add     $'0,r1
  723. X    movb    r1,(r3)+
  724. X    dec     count               / got all digits
  725. X    bne     9b
  726. X    br      out
  727. X
  728. Xzer:    inc     dpoint              / deal with zero
  729. X1:      movb    $'0,(r3)+
  730. X    sob     r2,1b
  731. Xout:                                / correct the last digit
  732. X    mov     $buf,r0
  733. X    add     mdigit,r0
  734. X    movb    (r0),r2
  735. X    add     $5,r2
  736. X    movb    r2,(r0)
  737. X1:
  738. X    cmpb    (r0),$'9
  739. X    ble     1f                  / don't correct it
  740. X    movb    $'0,(r0)
  741. X    cmp     r0,$buf
  742. X    blos    2f
  743. X    incb    -(r0)
  744. X    br      1b
  745. X2:
  746. X    inc     dpoint
  747. X    movb    $'1,(r0)            / correction has made number a one
  748. X1:
  749. X    mov     mdigit,r0           / pass values back
  750. X    clrb    buf(r0)
  751. X    mov     $buf,r0
  752. X    mov     dpoint,*8(r5)
  753. X    jmp     cret
  754. X
  755. Xtenmul:                             / multiply value in areg by 10
  756. X    mov     $areg+8.,r4
  757. X1:      mov     -(r4),r0
  758. X    mul     $12,r0
  759. X    bpl     2f
  760. X    add     $12,r0
  761. X2:      add     r2,r1
  762. X    adc     r0
  763. X    mov     r1,(r4)
  764. X    mov     r0,r2
  765. X    cmp     r4,$areg
  766. X    bne     1b
  767. X    rts     pc
  768. X
  769. Xtendiv:                             / divide value in areg by 10
  770. X    mov     $areg,r4
  771. X    clr     r0
  772. X1:      mov     (r4),r1             / has to divide by 20 to stop
  773. X    div     $24,r0              / multiply thinking there is an
  774. X    asl     r0                  / overflow
  775. X    cmp     r1,$9
  776. X    ble     2f
  777. X    inc     r0
  778. X    sub     $12,r1
  779. X2:      mov     r0,(r4)+
  780. X    mov     r1,r0
  781. X    cmp     r4,$areg+8
  782. X    bne     1b
  783. X    rts     pc
  784. X
  785. X    .bss
  786. Xmdigit: .=.+2
  787. Xcount:  .=.+2
  788. Xbuf:    .=.+20.
  789. Xdpoint: .=.+2
  790. X    .text
  791. X
  792. X/   convert a long in 'overfl' to a real. uses the floating point
  793. X/   routines. returns via these routines.
  794. X
  795. X.globl  _over
  796. X_over:
  797. X    jsr     r5,csv
  798. X    clrb    _vartype
  799. X    mov     _overfl,areg
  800. X    mov     _overfl+2,areg+2
  801. X    clr     areg+4
  802. X    clr     areg+6
  803. X    mov     $1,asign
  804. X    mov     $32.-8,aexp
  805. X    jmp     saret
  806. X
  807. X/
  808. X/   put a value into a variable , does the convertions from integer
  809. X/   to real and back as needed.
  810. X/
  811. X
  812. X.globl  _putin
  813. X_putin: cmpb    4(sp),_vartype
  814. X    beq     3f
  815. X    mov     $_res,-(sp)
  816. X    tstb    6(sp)
  817. X    beq     2f
  818. X    jsr     pc,_conv
  819. X    tst     r0
  820. X    beq     1f
  821. X    mov     $35.,(sp)
  822. X    jsr     pc,_error       / no return
  823. X2:      jsr     pc,_cvt
  824. X1:      tst     (sp)+
  825. X3:      mov     $_res,r0
  826. X    mov     2(sp),r1
  827. X    mov     (r0)+,(r1)+
  828. X    tstb    4(sp)           / type of variable that is to be assigned
  829. X    bne     1f              / to
  830. X    mov     (r0)+,(r1)+
  831. X    mov     (r0)+,(r1)+
  832. X    mov     (r0)+,(r1)+
  833. X1:      rts     pc
  834. X
  835. X/   high speed move of variables
  836. X/   can't use floating point moves because of '-0'.
  837. X
  838. X.globl  _movein
  839. X_movein: mov     2(sp),r0
  840. X    mov     4(sp),r1
  841. X    mov     (r0)+,(r1)+
  842. X    mov     (r0)+,(r1)+
  843. X    mov     (r0)+,(r1)+
  844. X    mov     (r0)+,(r1)+
  845. X    rts     pc
  846. X
  847. X/   puts the value from a variable into 'res'. It might be thought
  848. X/   that 'movein' could be used but it can't for the reason given in
  849. X/   the report.
  850. X/
  851. X
  852. X.globl  _getv
  853. X_getv:  mov     2(sp),r0
  854. X    mov     $_res,r1
  855. X    mov     (r0)+,(r1)+
  856. X    tstb    _vartype
  857. X    bne     1f
  858. X    mov     (r0)+,(r1)+
  859. X    mov     (r0)+,(r1)+
  860. X    mov     (r0)+,(r1)+
  861. X1:      rts     pc
  862. X
  863. X/   move the value in res onto the maths 'stack'. A simple floating
  864. X/   move cannot be used due to the possibility of "minus zero" or
  865. X/   -32768 being in 'res'. This could check 'vartype' but for speed just
  866. X/   does the move.
  867. X
  868. X.globl  _push
  869. X_push:  mov     2(sp),r1
  870. X    mov     $_res,r0
  871. X    mov     (r0)+,(r1)+
  872. X    mov     (r0)+,(r1)+
  873. X    mov     (r0)+,(r1)+
  874. X    mov     (r0)+,(r1)+
  875. X    rts     pc
  876. X
  877. X/   negate a number , checks for overflow and for type of number.
  878. X/
  879. X
  880. X.globl  _negate
  881. X_negate:
  882. X    tstb    _vartype
  883. X    beq     1f
  884. X    neg     _res
  885. X    bvs     2f                      / negating -32768
  886. X    rts     pc
  887. X1:      tst     _res                    / stop -0
  888. X    beq     1f
  889. X    add     $100000,_res
  890. X1:      rts     pc
  891. X2:
  892. X    mov     $044000,_res            / 32768 in floating form
  893. X    clr     _res+2
  894. X    clr     _res+4
  895. X    clr     _res+6
  896. X    clrb    _vartype
  897. X    rts     pc
  898. X
  899. X/ unary negation
  900. X
  901. X.globl  _notit
  902. X
  903. X_notit: tstb    _vartype
  904. X    beq     1f
  905. X    com     _res
  906. X    rts     pc
  907. X1:      movb    $1,_vartype
  908. X    tst     _res
  909. X    bne     1f
  910. X    com     _res
  911. X    rts     pc
  912. X1:      clr     _res
  913. X    rts     pc
  914. X
  915. X/ routine to dynamically check the stack
  916. X.globl  _checksp
  917. X
  918. X_checksp:
  919. X    cmp     sp,$160000+1024.
  920. X    blos    1f
  921. X    rts     pc
  922. X1:      mov     $44.,(sp)
  923. X    jsr     pc,_error       / no return
  924. End of pdp11/assist.s
  925. chmod u=rw-,g=r,o=r pdp11/assist.s
  926. echo x - pdp11/conf.h 1>&2
  927. sed 's/^X//' > pdp11/conf.h << 'End of pdp11/conf.h'
  928. X/*
  929. X * BASIC by Phil Cockcroft
  930. X */
  931. X/*
  932. X * Configuration file for a pdp11
  933. X */
  934. X/*
  935. X * hardware specific. Can't change MAXMEM upwards
  936. X */
  937. X
  938. X#define MAXMEM          (memp)0160000   /* max data address on a pdp11 */
  939. X#define MEMINC          1023            /* size of memory increments - 1 */
  940. X
  941. X/*
  942. X * various options.
  943. X */
  944. X
  945. X#define V7
  946. X#define UCB_NTTY
  947. X#define LKEYWORDS
  948. X#define LNAMES
  949. X#define RENUMB
  950. X#define SCOMMS
  951. X#define BERK
  952. X
  953. X#ifdef  BERK
  954. X#define BLOCKSIZ        1024
  955. X#else
  956. X#define BLOCKSIZ        512
  957. X#endif
  958. X
  959. X/*
  960. X * terminal specific options
  961. X */
  962. X#define DEFPAGE         80      /* default page width */
  963. X#define DEFLENGTH       24      /* default page length */
  964. X#define CTRLINT         03      /* ctrl -c - sig int */
  965. X#define CTRLQUIT        034     /* ctrl - \ FS sig quit */
  966. X
  967. X/* #define V7     */    /* define for v7 */
  968. X/* #define SOFTFP */    /* define if not got fp hardware */
  969. X/* #define V6C    */    /* if got V6 compiler (no structure assignments ) */
  970. X/* #define BERK   */    /* define if got Berkley tty driver ( not v6 ) */
  971. X/* #define UCB_NTTY */  /* if got the new driver ..... */
  972. X
  973. X/* #define NOEDIT    /* define if don't want editing ever ! */
  974. X             /* NB basic -e will still turn on editing */
  975. X             /* basic -x will still turn off editing */
  976. X
  977. X/* #define LKEYWORDS /* define this if you want to have variable names which*/
  978. X             /* contain commands this is like the later versions of */
  979. X             /* microsoft but not like the orignal version */
  980. X             /* it wastes more space since you have to have some */
  981. X             /* spaces in to distinguish keywords */
  982. X
  983. X/* #define RENUMB    /* define if you want to put the code for renumbering */
  984. X             /* in. It works but is very wasteful of space. If you */
  985. X             /* are short of space then don't use it. */
  986. X
  987. X/* #define LNAMES    /* define if you want long variables names. This only */
  988. X             /* slows it down by a small fraction */
  989. X
  990. X/* #define _BLOCKED  /* This is a switch to allow block mode files */
  991. X             /* don't define it here look below for where it is done*/
  992. X             /* in the file handling bits */
  993. X/* #define SCOMMS    /* to allow shortened command names e.g. l. -> list */
  994. X             /* this might cause some problems with overwriting of */
  995. X             /* core but I think they have all been solved */
  996. End of pdp11/conf.h
  997. chmod u=rw-,g=r,o=r pdp11/conf.h
  998. echo x - pdp11/fpassist.s 1>&2
  999. sed 's/^X//' > pdp11/fpassist.s << 'End of pdp11/fpassist.s'
  1000. X/       (c) P. (Rabbit) Cockcroft 1982
  1001. X
  1002. X.globl  _wait, cerror
  1003. X
  1004. Xwait = 7.
  1005. X
  1006. X_wait:
  1007. X    mov     r5,-(sp)
  1008. X    mov     sp,r5
  1009. X    sys     wait
  1010. X    bec     1f
  1011. X    jmp     cerror
  1012. X1:    
  1013. X    tst    4(r5)
  1014. X    beq    1f
  1015. X    mov    r1,*4(5)
  1016. X1:
  1017. X    mov     (sp)+,r5
  1018. X    rts     pc
  1019. X
  1020. X/   getch() is used all over the place to get the next character on the line.
  1021. X/   It uses 'point' ( _point ) as the pointer to the next character.
  1022. X/   It skips over all leading spaces.
  1023. X/       It was put into machine code for speed since it does not have to
  1024. X/   call csv and cret ( the C subroutine call and return routines ).
  1025. X/   this saves a lot of time. It can also be written more efficiently
  1026. X/   in machine code.
  1027. X/
  1028. X
  1029. X.text
  1030. X.globl  _point , _getch
  1031. X
  1032. X_getch:
  1033. X    mov     _point,r1
  1034. X1:      cmpb    $40,(r1)+       / ignore spaces
  1035. X    beq     1b
  1036. X    mov     r1,_point
  1037. X    clr     r0
  1038. X    bisb    -(r1),r0
  1039. X    rts     pc
  1040. X
  1041. X/   check() is used by many routines that want to know if there is any
  1042. X/   garbage characters after its arguments. e.g. in 'goto' there
  1043. X/   should be nothing after the line number. It gives a SYNTAX
  1044. X/   error if the next character is not a terminator.
  1045. X/   check() was also taken out of C for speed reasons.
  1046. X
  1047. X.globl  _point  , _check   , _elsecount  , _error
  1048. X
  1049. XELSE=   0351
  1050. X
  1051. X_check:
  1052. X    mov     _point,r0
  1053. X1:      cmpb    $40,(r0)+
  1054. X    beq     1b
  1055. X    movb    -(r0),r1
  1056. X    beq     1f
  1057. X    cmpb    r1,$':
  1058. X    beq     1f
  1059. X    cmpb    r1,$ELSE
  1060. X    bne     2f
  1061. X    tstb    _elsecount
  1062. X    beq     2f
  1063. X1:      mov     r0,_point
  1064. X    rts     pc
  1065. X2:      mov     $1,-(sp)        / syntax error
  1066. X    jsr     pc,_error
  1067. X
  1068. X/   startfp() this is called in main to intialise the floating point
  1069. X/   hardware if it is used. it is only called once to set up fpfunc()
  1070. X/   this routine does nothing in non-floating point hardware machines.
  1071. X/
  1072. X
  1073. X .globl _startfp , _fpfunc
  1074. X
  1075. Xldfps = 0170100 ^ tst
  1076. X
  1077. X_startfp:
  1078. X    mov     $fpcrash,_fpfunc
  1079. X    ldfps   $1200
  1080. X    rts     pc
  1081. X.bss
  1082. X_fpfunc: .=.+2
  1083. X.text
  1084. X
  1085. Xfpcrash:
  1086. X    mov     $34.,-(sp)
  1087. X    jsr     pc,_error       / no return
  1088. X
  1089. X/   cmp() is used to compare two numbers , it uses 'vartype' to decide
  1090. X/   which kind of variable to test.
  1091. X/   The result is -1,0 or 1 , depending on the result of the comparison
  1092. X/
  1093. X
  1094. X.globl  _cmp   , _vartype
  1095. X
  1096. X_cmp:
  1097. X    tstb    _vartype
  1098. X    beq     6f
  1099. X    cmp     *2(sp),*4(sp)
  1100. X1:
  1101. X    blt     4f
  1102. X    bgt     3f
  1103. X5:      clr     r0
  1104. X    rts     pc
  1105. X3:      mov     $1,r0
  1106. X    rts     pc
  1107. X4:      mov     $-1,r0
  1108. X    rts     pc
  1109. X                / floating point comparisons
  1110. X6:      movf    *4(sp),fr0
  1111. X    cmpf    *2(sp),fr0
  1112. X    cfcc
  1113. X    br      1b
  1114. X
  1115. X
  1116. X/   routine to multiply two numbers together. returns zero on overflow
  1117. X/   used in dimensio() only.
  1118. X
  1119. X.globl  _dimmul
  1120. X
  1121. X_dimmul:
  1122. X    mov     2(sp),r1
  1123. X    mul     4(sp),r1
  1124. X    bcc     1f
  1125. X    clr     r1
  1126. X1:      mov     r1,r0
  1127. X    rts     pc
  1128. X
  1129. X.globl  _mbin
  1130. X
  1131. X/   jump table for the maths functions
  1132. X/   straight from the eval() routine in bas3.c
  1133. X
  1134. X.data
  1135. X_mbin:  0
  1136. X    0
  1137. X    fandor
  1138. X    andor
  1139. X    comop
  1140. X    comop
  1141. X    fads
  1142. X    ads
  1143. X    fmdm
  1144. X    mdm
  1145. X    fex
  1146. X    ex
  1147. X.text
  1148. X
  1149. X/   locations from the jump table
  1150. X/   integer exponentiation , convert to reals then call the floating
  1151. X/   point convertion routines.
  1152. X/
  1153. X.globl  _exp , _log
  1154. X
  1155. Xexp:    movf    fr0,-(sp)
  1156. X    jsr     pc,_exp
  1157. X    tstf    (sp)+
  1158. X    rts     pc
  1159. X
  1160. Xlog:    movf    fr0,-(sp)
  1161. X    jsr     pc,_log
  1162. X    tstf    (sp)+
  1163. X    rts     pc
  1164. X
  1165. X
  1166. Xex:     movif   *2(sp),fr0
  1167. X    movif   *4(sp),fr1
  1168. X    movf    fr1,*4(sp)
  1169. X    clrb    _vartype
  1170. X    br      1f
  1171. Xfex:
  1172. X    movf    *2(sp),fr0
  1173. X1:
  1174. X    tstf    fr0
  1175. X    cfcc
  1176. X    beq     1f
  1177. X    bmi     2f
  1178. X    jsr     pc,log              / call log
  1179. X    mulf    *4(sp),fr0
  1180. X1:
  1181. X    jsr     pc,exp              / exponentiate
  1182. X    bes     1f
  1183. X    movf    fr0,*4(sp)
  1184. X    rts     pc
  1185. X1:      mov     $40.,-(sp)          / overflow in ^
  1186. X    jsr     pc,_error
  1187. X2:      mov     $41.,-(sp)          / negative value to ^
  1188. X    jsr     pc,_error
  1189. X
  1190. Xfmdm:
  1191. X    movf    *2(sp),fr0
  1192. X    cmp     $52,6(sp)       / times
  1193. X    bne     1f
  1194. X    mulf    *4(sp),fr0
  1195. X    movf    fr0,*4(sp)
  1196. X    rts     pc
  1197. X1:
  1198. X    movf    *4(sp),fr2
  1199. X    cfcc
  1200. X    beq     zerodiv
  1201. X    divf    fr2,fr0
  1202. X    cmp     $'/,6(sp)       / div
  1203. X    beq     1f
  1204. X    modf    $040200,fr0     / mod
  1205. X    mulf    fr2,fr0
  1206. X1:
  1207. X    movf    fr0,*4(sp)
  1208. X    rts     pc
  1209. X
  1210. X
  1211. Xmdm:    cmp     $52,6(sp)       / integer multiply
  1212. X    bne     1f
  1213. X    mov     *2(sp),r0
  1214. X    mul     *4(sp),r0
  1215. X    bcs     over            / overflow
  1216. X    br      2f
  1217. X1:      mov     *2(sp),r1       / divide or mod
  1218. X    sxt     r0
  1219. X    div     *4(sp),r0
  1220. X    bvs     1f
  1221. X    cmp     $57,6(sp)       / div
  1222. X    bne     2f              / no , must be mod.
  1223. X    tst     r1
  1224. X    bne     3f
  1225. X    mov     r0,r1
  1226. X2:      mov     r1,*4(sp)
  1227. X    rts     pc
  1228. X1:
  1229. Xzerodiv:
  1230. X    mov     $25.,-(sp)      / zero divisor error
  1231. X    jsr     pc,_error
  1232. X                / code to do integer divisions.. etc.
  1233. X3:      movif   *2(sp),fr0
  1234. X    movif   *4(sp),fr1
  1235. X    divf    fr1,fr0
  1236. X    movf    fr0,*4(sp)
  1237. X    clrb    _vartype
  1238. X    rts     pc
  1239. X
  1240. Xfads:                           / floating add and subtract
  1241. X    movf    *2(sp),fr0
  1242. X    cmp     $53,6(sp)
  1243. X    bne     1f
  1244. X
  1245. X    addf    *4(sp),fr0
  1246. X    movf    fr0,*4(sp)
  1247. X    rts     pc
  1248. X1:
  1249. X    subf    *4(sp),fr0
  1250. X    movf    fr0,*4(sp)
  1251. X    rts     pc
  1252. X
  1253. X
  1254. Xads:    mov     *2(sp),r1
  1255. X    cmp     $53,6(sp)           / add or subtract
  1256. X    bne     1f
  1257. X    add     *4(sp),r1           / add
  1258. X    br      2f
  1259. X1:      sub     *4(sp),r1           / subtract
  1260. X2:      bvs     over1               / branch on overflow
  1261. X    mov     r1,*4(sp)
  1262. X    rts     pc
  1263. X
  1264. Xover1:  tst     *2(sp)              / move value to 'overfl'
  1265. X    sxt     r0
  1266. Xover:   mov     r0,_overfl
  1267. X    mov     r1,_overfl+2
  1268. X    jmp     _over               /  return via call to 'over'
  1269. X
  1270. X/   comparison operators ( float and integer )
  1271. X/   cmp() expects to have only two parameters . So save return address
  1272. X/   and so simulate environment.
  1273. X
  1274. Xcomop:  mov     (sp)+,comsav        / save return address
  1275. X    jsr     pc,_cmp             / call comparison routine
  1276. X    mov     r0,-(sp)
  1277. X    mov     6(sp),-(sp)         / call routine to convert
  1278. X    jsr     pc,_compare         / this result into logical result
  1279. X    tst     (sp)+
  1280. X    mov     comsav,(sp)         / restore return address
  1281. X    rts     pc                  / return
  1282. X.bss
  1283. Xcomsav: .=.+2
  1284. X.text
  1285. X
  1286. X/   floating logical operators
  1287. X/   convert floating types into integers. If the value is non zero
  1288. X/   then value has a true (-1) value.
  1289. X/
  1290. X
  1291. Xfandor:
  1292. X    mov     *2(sp),r0
  1293. X    beq     2f
  1294. X    mov     $-1,r0
  1295. X2:      mov     *4(sp),r1
  1296. X    beq     2f
  1297. X    mov     $-1,r1
  1298. X2:      movb    $1,_vartype
  1299. X    br      2f
  1300. X
  1301. X/   integer logical operators
  1302. X/   does a bitwise operaotion on the two numbers ( in r0 , r1 ).
  1303. X/
  1304. X
  1305. Xandor:
  1306. X    mov     *2(sp),r0
  1307. X    mov     *4(sp),r1
  1308. X2:      cmpb    $356,6(sp)
  1309. X    bne     2f
  1310. X    com     r1
  1311. X    bic     r1,r0
  1312. X    br      1f
  1313. X2:      cmp     $357,6(sp)
  1314. X    bne     2f
  1315. X    bis     r1,r0
  1316. X    br      1f
  1317. X2:      xor     r1,r0
  1318. X1:      mov     r0,*4(sp)
  1319. X    rts     pc
  1320. X
  1321. X/   This routine converts a floationg point number into an integers
  1322. X/   if the result would overflow then return non zero.
  1323. X/
  1324. X
  1325. X.globl  _conv
  1326. X
  1327. X_conv:
  1328. X    movf    *2(sp),fr0
  1329. X    movfi   fr0,r0
  1330. X    cfcc
  1331. X    bcs     1f
  1332. X    mov     r0,*2(sp)
  1333. X    clr     r0
  1334. X    rts     pc
  1335. X1:
  1336. X    mov     $1,r0
  1337. X    rts     pc
  1338. X
  1339. X
  1340. X/   add two numbers used in the 'next' routine
  1341. X/   depends on the type of the number. calls error on overflow.
  1342. X/
  1343. X
  1344. X.globl  _foreadd
  1345. X_foreadd:
  1346. X    add     2(sp),*4(sp)
  1347. X    bvs     1f
  1348. X    rts     pc
  1349. X1:      mov     $35.,-(sp)      / integer overflow
  1350. X    jsr     pc,_error
  1351. X
  1352. X/   convert a long in 'overfl' to a real. uses the floating point
  1353. X/   routines. returns via these routines.
  1354. X
  1355. X.globl  _over
  1356. X_over:
  1357. X    setl
  1358. X    movif   _overfl,fr0
  1359. X    clrb    _vartype
  1360. X    movf    fr0,*4(sp)
  1361. X    seti
  1362. X    rts     pc
  1363. X/
  1364. X/   put a value into a variable , does the convertions from integer
  1365. X/   to real and back as needed.
  1366. X/
  1367. X
  1368. X.globl  _putin
  1369. X_putin: cmpb    4(sp),_vartype
  1370. X    beq     1f
  1371. X    tstb    4(sp)
  1372. X    beq     2f
  1373. X    movf    _res,fr0
  1374. X    movfi   fr0,r0
  1375. X    cfcc
  1376. X    bes     3f
  1377. X    mov     r0,*2(sp)
  1378. X    rts     pc
  1379. X3:
  1380. X    mov     $35.,-(sp)
  1381. X    jsr     pc,*$_error     / no return
  1382. X2:
  1383. X    movif   _res,fr0
  1384. X    movf    fr0,*2(sp)
  1385. X    rts     pc
  1386. X1:
  1387. X    tstb    4(sp)
  1388. X    bne     1f
  1389. X    movf    _res,fr0
  1390. X    movf    fr0,*2(sp)
  1391. X    rts     pc
  1392. X1:
  1393. X    mov     _res,*2(sp)
  1394. X    rts     pc
  1395. X
  1396. X/   high speed move of variables
  1397. X/   can't use floating point moves because of '-0'.
  1398. X
  1399. X.globl  _movein
  1400. X_movein: mov     2(sp),r0
  1401. X    mov     4(sp),r1
  1402. X    mov     (r0)+,(r1)+
  1403. X    mov     (r0)+,(r1)+
  1404. X    mov     (r0)+,(r1)+
  1405. X    mov     (r0)+,(r1)+
  1406. X    rts     pc
  1407. X
  1408. X/   puts the value from a variable into 'res'. It might be thought
  1409. X/   that 'movein' could be used but it can't for the reason given in
  1410. X/   the report.
  1411. X/
  1412. X
  1413. X.globl  _getv
  1414. X_getv:  mov     2(sp),r0
  1415. X    mov     $_res,r1
  1416. X    mov     (r0)+,(r1)+
  1417. X    tstb    _vartype
  1418. X    bne     1f
  1419. X    mov     (r0)+,(r1)+
  1420. X    mov     (r0)+,(r1)+
  1421. X    mov     (r0)+,(r1)+
  1422. X1:      rts     pc
  1423. X
  1424. X/   move the value in res onto the maths 'stack'. A simple floating
  1425. X/   move cannot be used due to the possibility of "minus zero" or
  1426. X/   -32768 being in 'res'. This could check 'vartype' but for speed just
  1427. X/   does the move.
  1428. X
  1429. X.globl  _push
  1430. X_push:  mov     2(sp),r1
  1431. X    mov     $_res,r0
  1432. X    mov     (r0)+,(r1)+
  1433. X    mov     (r0)+,(r1)+
  1434. X    mov     (r0)+,(r1)+
  1435. X    mov     (r0)+,(r1)+
  1436. X    rts     pc
  1437. X
  1438. X/   negate a number , checks for overflow and for type of number.
  1439. X/
  1440. X
  1441. X.globl  _negate
  1442. X_negate:
  1443. X    tstb    _vartype
  1444. X    beq     1f
  1445. X    neg     _res
  1446. X    bvs     2f                      / negating -32768
  1447. X    rts     pc
  1448. X1:      tst     _res                    / stop -0
  1449. X    beq     1f
  1450. X    add     $100000,_res
  1451. X1:
  1452. X    rts     pc
  1453. X2:
  1454. X    mov     $044000,_res            / 32768 in floating form
  1455. X    clr     _res+2
  1456. X    clr     _res+4
  1457. X    clr     _res+6
  1458. X    clrb    _vartype
  1459. X    rts     pc
  1460. X
  1461. X/ unary negation
  1462. X
  1463. X.globl  _notit
  1464. X
  1465. X_notit: tstb    _vartype
  1466. X    beq     1f
  1467. X    com     _res
  1468. X    rts     pc
  1469. X1:      movb    $1,_vartype
  1470. X    tst     _res
  1471. X    bne     1f
  1472. X    com     _res
  1473. X    rts     pc
  1474. X1:      clr     _res
  1475. X    rts     pc
  1476. X
  1477. X/ routine to dynamically check the stack
  1478. X
  1479. X.globl  _checksp
  1480. X
  1481. X_checksp:
  1482. X    cmp     sp,$160000+1024.
  1483. X    blos    1f
  1484. X    rts     pc
  1485. X1:      mov     $44.,(sp)       / expression too complex
  1486. X    jsr     pc,_error       / no return
  1487. End of pdp11/fpassist.s
  1488. chmod u=rw-,g=r,o=r pdp11/fpassist.s
  1489. echo x - pdp11/lfunc.s 1>&2
  1490. sed 's/^X//' > pdp11/lfunc.s << 'End of pdp11/lfunc.s'
  1491. X/               (c) P. (Rabbit) Cockcroft 1982
  1492. X/   This file contains the routines to implement the some of the
  1493. X/   more complex mathematical functions.
  1494. X/   It currently contains the code for sqrt() , log() and exp()
  1495. X
  1496. X/   The sqrt() routine is based on the the standard Newtonian method.
  1497. X/   It uses mull and divv from nfp.s
  1498. X
  1499. X.globl  _sqrt  , sqrt
  1500. X/
  1501. X/       for ( i = 0 ; i < 6 ; i++ )
  1502. X/               areg = ( areg + creg / areg ) >> 1 ;
  1503. X/
  1504. X
  1505. X_sqrt:
  1506. X    jsr     r5,csv
  1507. X    mov     4(r5),r2
  1508. X    mov     $asign,r0
  1509. X    jsr     pc,seta
  1510. X    jsr     pc,sqrt
  1511. X    mov     4(r5),r2
  1512. X    mov     $asign,r0
  1513. X    jmp     retng
  1514. X
  1515. X
  1516. X/ value in  areg
  1517. X
  1518. Xsqrt:
  1519. X    tst     asign           / test for zero
  1520. X    bne     1f
  1521. X    rts     pc
  1522. X1:
  1523. X    bit     $1,aexp         / sort out the exponent
  1524. X    beq     1f
  1525. X    mov     $areg,r0        / shifting as need be
  1526. X    asr     (r0)+
  1527. X    ror     (r0)+
  1528. X    ror     (r0)+
  1529. X    ror     (r0)+
  1530. X    inc     aexp
  1531. X1:
  1532. X    mov     $asign,r0       / save in creg
  1533. X    mov     $csign,r1
  1534. X    mov     $6,r2
  1535. X1:
  1536. X    mov     (r0)+,(r1)+
  1537. X    sob     r2,1b
  1538. X
  1539. X    asr     aexp            / initial guess in areg
  1540. X    mov     $6.,-(sp)       / number of iterations
  1541. X
  1542. X                / main loop starts here
  1543. X5:
  1544. X    mov     $4,r2
  1545. X    mov     $areg,r0
  1546. X    mov     $breg,r1        / set up to do the division
  1547. X1:                              / areg/breg
  1548. X    mov     (r0)+,(r1)+
  1549. X    sob     r2,1b
  1550. X    mov     $4,r2
  1551. X    mov     $creg,r0
  1552. X    mov     $areg,r1
  1553. X1:
  1554. X    mov     (r0)+,(r1)+
  1555. X    sob     r2,1b
  1556. X    jsr     pc,divv         / the division
  1557. X1:      mov     $areg+8,r0      / add result to old value
  1558. X    mov     $breg+8,r1
  1559. X    jsr     pc,addm
  1560. X    mov     $areg,r0        / divide by two
  1561. X    asr     (r0)+
  1562. X    ror     (r0)+
  1563. X    ror     (r0)+
  1564. X    ror     (r0)+
  1565. X    dec     (sp)            / decrement iteration counter
  1566. X    bne     5b
  1567. X    tst     (sp)+
  1568. X    jsr     pc,norm         / normalise result
  1569. X    rts     pc
  1570. X
  1571. X/   The routines below handle the log and exp functions
  1572. X/   They return zero if there is an error or on overflow
  1573. X/   these routines are almost totally incomprehensible but the algorithms
  1574. X/   are discussed in the report.
  1575. X
  1576. X
  1577. X    ITER=11.        / loop count
  1578. X
  1579. X.globl  _log
  1580. X_log:
  1581. X    jsr     r5,csv
  1582. X    mov     4(r5),r2
  1583. X    mov     $asign,r0
  1584. X    jsr     pc,seta
  1585. X    jsr     pc,log
  1586. X    mov     4(r5),r2
  1587. X    mov     $asign,r0
  1588. X    jmp     retng
  1589. X
  1590. X.globl  log
  1591. X
  1592. Xlog:
  1593. X    clr     pt
  1594. X    mov     $creg,r0
  1595. X    clr     (r0)+
  1596. X    clr     (r0)+
  1597. X    clr     (r0)+
  1598. X    clr     (r0)+
  1599. X1:
  1600. X    mov     pt,r1
  1601. X    mov     r1,r4
  1602. X    mul     $3,r1
  1603. X    mov     r1,pt1
  1604. X3:
  1605. X    mov     $areg,r0
  1606. X    mov     $breg,r1
  1607. X    jsr     pc,movm
  1608. X    mov     pt1,r1
  1609. X    beq     5f
  1610. X    mov     $breg,r0
  1611. X    jsr     pc,shiftl
  1612. X5:
  1613. X    mov     $breg+8,r0
  1614. X    mov     $areg+8,r1
  1615. X    jsr     pc,addm
  1616. X    cmp     breg,$400
  1617. X    bhi     2f
  1618. X    blo     5f
  1619. X    tst     breg+2
  1620. X    bne     2f
  1621. X    tst     breg+4
  1622. X    bne     2f
  1623. X    tst     breg+6
  1624. X    bne     2f
  1625. X5:
  1626. X    mov     $areg,r1
  1627. X    mov     $breg,r0
  1628. X    jsr     pc,movm
  1629. X    mov     pt,r1
  1630. X    ash     $3,r1
  1631. X    add     $logtable+8,r1
  1632. X    mov     $creg+8,r0
  1633. X    jsr     pc,addm
  1634. X    br      3b
  1635. X2:
  1636. X    inc     pt
  1637. X    cmp     pt,$ITER
  1638. X    blt     1b                      / first loop finished
  1639. X
  1640. X    sub     $400,areg
  1641. X    mov     $creg+8,r1
  1642. X    mov     $areg+8,r0
  1643. X    jsr     pc,subm
  1644. X
  1645. X    mov     aexp,r4                 / deal with the exponent
  1646. X    beq     3f
  1647. X    bmi     2f
  1648. X1:
  1649. X    mov     $logtable+8,r1          /log2n
  1650. X    mov     $areg+8,r0
  1651. X    jsr     pc,addm
  1652. X    dec     r4
  1653. X    bne     1b
  1654. X    br      3f
  1655. X2:
  1656. X    mov     $logtable+8,r1          /log2n
  1657. X    mov     $areg+8,r0
  1658. X    jsr     pc,subm
  1659. X    inc     r4
  1660. X    bne     2b
  1661. X3:
  1662. X    tst     areg
  1663. X    bpl     1f
  1664. X    mov     $areg+8,r0
  1665. X    jsr     pc,negat
  1666. X    neg     asign
  1667. X1:
  1668. X    clr     aexp
  1669. X    jsr     pc,norm
  1670. X    rts     pc
  1671. X
  1672. X
  1673. X.globl  _exp
  1674. X
  1675. X_exp:
  1676. X    jsr     r5,csv
  1677. X    mov     4(r5),r2
  1678. X    mov     $asign,r0
  1679. X    jsr     pc,seta
  1680. X    jsr     pc,exp
  1681. X    bec     1f
  1682. X    clr     r0
  1683. X    jmp     cret
  1684. X1:
  1685. X    mov     4(r5),r2
  1686. X    mov     $asign,r0
  1687. X    jmp     retng
  1688. X
  1689. X.globl  exp
  1690. X
  1691. Xexp:    clr     cexp
  1692. X    tst     aexp            / test of exponent.
  1693. X    bmi     1f
  1694. X    beq     5f
  1695. X    cmp     aexp,$7
  1696. X    ble     4f
  1697. X    sec
  1698. X    rts     pc
  1699. X4:
  1700. X    mov     $areg+8,r0
  1701. X    asl     -(r0)
  1702. X    rol     -(r0)
  1703. X    rol     -(r0)
  1704. X    rol     -(r0)
  1705. X    dec     aexp
  1706. X    bne     4b
  1707. X4:
  1708. X    tstb    areg+1
  1709. X    beq     5f
  1710. X    mov     $logtable+8,r1
  1711. X    mov     $areg+8,r0
  1712. X    jsr     pc,subm
  1713. X    inc     cexp
  1714. X    br      4b
  1715. X5:      mov     $logtable+8,r1
  1716. X    mov     $areg+8,r0
  1717. X    jsr     pc,subm
  1718. X    tst     areg
  1719. X    bpl     3f
  1720. X    mov     $logtable+8,r1
  1721. X    mov     $areg+8,r0
  1722. X    jsr     pc,addm
  1723. X    br      5f
  1724. X3:      inc     cexp
  1725. X    br      5f
  1726. X1:
  1727. X    mov     $areg,r0
  1728. X    mov     aexp,r1
  1729. X    neg     r1
  1730. X    jsr     pc,shiftl
  1731. X
  1732. X5:      mov     $1,r4           / main loop starts here
  1733. X3:
  1734. X    clrb    count(r4)
  1735. X    mov     r4,r1
  1736. X    ash     $3,r1
  1737. X    add     $logtable+8,r1
  1738. X    mov     r1,r3
  1739. X2:
  1740. X    mov     $areg+8,r0
  1741. X    jsr     pc,subm
  1742. X    tst     areg
  1743. X    bmi     1f
  1744. X    incb    count(r4)
  1745. X    mov     r3,r1
  1746. X    br      2b
  1747. X1:
  1748. X    mov     r3,r1
  1749. X    mov     $areg+8,r0
  1750. X    jsr     pc,addm
  1751. X    inc     r4
  1752. X    cmp     r4,$ITER
  1753. X    blt     3b              / end of first loop
  1754. X6:
  1755. X
  1756. X    add     $400,areg
  1757. X    mov     $1,pt
  1758. X1:
  1759. X    mov     pt,r1
  1760. X    mul     $3,r1
  1761. X    mov     r1,pt1
  1762. X2:
  1763. X    mov     pt,r4
  1764. X    tstb    count(r4)
  1765. X    beq     2f
  1766. X    decb    count(r4)
  1767. X    mov     $areg,r0
  1768. X    mov     $breg,r1
  1769. X    jsr     pc,movm
  1770. X    mov     pt1,r1
  1771. X    beq     5f
  1772. X    mov     $breg,r0
  1773. X    jsr     pc,shiftl
  1774. X5:
  1775. X    mov     $breg+8,r1
  1776. X    mov     $areg+8,r0
  1777. X    jsr     pc,addm
  1778. X    br      2b
  1779. X2:
  1780. X    inc     pt
  1781. X    cmp     pt,$ITER
  1782. X    blt     1b
  1783. X    tst     asign
  1784. X    bne     3f
  1785. X    inc     asign
  1786. X3:
  1787. X    mov     cexp,aexp
  1788. X    jsr     pc,norm
  1789. X    tst     asign
  1790. X    bpl     1f
  1791. X    jsr     pc,recip
  1792. X    neg     asign
  1793. X1:
  1794. X    cmp     aexp,$177
  1795. X    ble     1f
  1796. X    sec
  1797. X    rts     pc
  1798. X1:
  1799. X    clc
  1800. X    rts     pc
  1801. X
  1802. X.globl  recip
  1803. Xrecip:
  1804. X    mov     $areg,r0                / return reciprical of areg
  1805. X    mov     $breg,r1                / done by division
  1806. X    jsr     pc,movm
  1807. X    mov     $200,areg
  1808. X    clr     areg+2
  1809. X    clr     areg+4
  1810. X    clr     areg+6
  1811. X    jsr     pc,divv
  1812. X    neg     aexp
  1813. X    inc     aexp
  1814. X    jsr     pc,norm
  1815. X    rts     pc
  1816. X
  1817. X
  1818. X.bss
  1819. Xcount:  .=.+12.                 / counters for the log and exp functs.
  1820. Xpt:     .=.+2
  1821. Xpt1:    .=.+2
  1822. X
  1823. X.globl  logtable
  1824. X
  1825. X.data
  1826. X    / log2n is in fact the first entry in logtable
  1827. X
  1828. Xlogtable:
  1829. X    000261; 071027; 173721; 147572
  1830. X    000036; 023407; 067052; 171341
  1831. X    000003; 174025; 013037; 100174
  1832. X    000000; 077740; 005246; 126103
  1833. X    000000; 007777; 100005; 052425
  1834. X    000000; 000777; 177000; 001252
  1835. X    000000; 000077; 177770; 000001
  1836. X    000000; 000007; 177777; 160000
  1837. X    000000; 000000; 177777; 177600
  1838. X    000000; 000000; 017777; 177777
  1839. X    000000; 000000; 001777; 177777
  1840. X.text
  1841. X
  1842. X.globl  _fexp
  1843. X_fexp:  jsr     r5,csv              / do exponentiation
  1844. X    mov     4(r5),r2
  1845. X    mov     $asign,r0
  1846. X    jsr     pc,seta
  1847. X    tst     asign               / deal with 0^x
  1848. X    beq     1f
  1849. X    bmi     2f
  1850. X    jsr     pc,log              / call log
  1851. X    mov     6(r5),r2
  1852. X    mov     $bsign,r0
  1853. X    jsr     pc,seta
  1854. X    jsr     pc,mull             / multiply
  1855. X    add     bexp,aexp
  1856. X    dec     aexp
  1857. X    jsr     pc,xorsign
  1858. X    jsr     pc,norm
  1859. X1:
  1860. X    jsr     pc,exp              / exponentiate
  1861. X    bes     1f
  1862. X    mov     6(r5),r2
  1863. X    jmp     retng
  1864. X1:      mov     $40.,-(sp)          / overflow in ^
  1865. X    jsr     pc,_error
  1866. X2:      mov     $41.,-(sp)          / negative value to ^
  1867. X    jsr     pc,_error
  1868. X
  1869. X/ trig functions that are not as yet implemented
  1870. X/ put in as place holders. Calls error with illegal function
  1871. X
  1872. X.globl  _sin , _cos , _atan
  1873. X_sin:
  1874. X_cos:
  1875. X_atan:
  1876. X    mov     $11.,-(sp)
  1877. X    jsr     pc,_error
  1878. X
  1879. X/   These routines do quad precision arithmetic and are called by many of
  1880. X/   the higher mathematical functions. These are usually called with the
  1881. X/   addresses of the operands in r0 and r1. (r0 is usually destination )
  1882. X
  1883. X.globl  addm , subm , movm , shiftl , negat
  1884. X
  1885. Xaddm:
  1886. X    mov     $4,r2                  / add quad length
  1887. X    clc
  1888. X1:
  1889. X    adc     -(r0)
  1890. X    bcs     3f
  1891. X    add     -(r1),(r0)
  1892. X    sob     r2,1b
  1893. X    rts     pc
  1894. X3:
  1895. X    add     -(r1),(r0)
  1896. X    sec
  1897. X    sob     r2,1b
  1898. X    rts     pc
  1899. X
  1900. X
  1901. Xsubm:                               / subtract quad length
  1902. X    mov     $4,r2
  1903. X    clc
  1904. X1:
  1905. X    sbc     -(r0)
  1906. X    bcs     3f
  1907. X    sub     -(r1),(r0)
  1908. X    sob     r2,1b
  1909. X    rts     pc
  1910. X3:
  1911. X    sub     -(r1),(r0)
  1912. X    sec
  1913. X    sob     r2,1b
  1914. X    rts     pc
  1915. X
  1916. Xshiftl:                             / a misnomer
  1917. X    mov     r5,-(sp)            / it actually shifts right
  1918. X    mov     r1,r5               / the number of places in r1
  1919. X    mov     (r0)+,r1
  1920. X    mov     (r0)+,r2
  1921. X    mov     (r0)+,r3
  1922. X    mov     (r0)+,r4
  1923. X1:
  1924. X    asr     r1
  1925. X    ror     r2
  1926. X    ror     r3
  1927. X    ror     r4
  1928. X    sob     r5,1b
  1929. X    mov     r4,-(r0)
  1930. X    mov     r3,-(r0)
  1931. X    mov     r2,-(r0)
  1932. X    mov     r1,-(r0)
  1933. X    mov     (sp)+,r5
  1934. X    rts     pc
  1935. X
  1936. Xmovm:                               / quad move - the parameters are the
  1937. X    mov     (r0)+,(r1)+         / other way around
  1938. X    mov     (r0)+,(r1)+
  1939. X    mov     (r0)+,(r1)+
  1940. X    mov     (r0)+,(r1)+
  1941. X    rts     pc
  1942. X
  1943. X
  1944. Xnegat:                              / quad negation
  1945. X    mov     $4,r1
  1946. X    clc
  1947. X1:
  1948. X    adc     -(r0)
  1949. X    bcs     2f
  1950. X    neg     (r0)
  1951. X2:
  1952. X    sob     r1,1b
  1953. X    rts     pc
  1954. End of pdp11/lfunc.s
  1955. chmod u=rw-,g=r,o=r pdp11/lfunc.s
  1956. echo x - pdp11/nfp.s 1>&2
  1957. sed 's/^X//' > pdp11/nfp.s << 'End of pdp11/nfp.s'
  1958. X/       (c) P. (Rabbit) Cockcroft 1982
  1959. X/   this file contains all the floating point routines to execute the four
  1960. X/   basic mathematical functions. Also routines for exponentiation and the
  1961. X/   floating mod function.
  1962. X/
  1963. X/   These routines are the same as used in the floating point simulator
  1964. X/   but have been changed to make them more flexible and to enable the use
  1965. X/   of C calling and return conventions.
  1966. X/   They have also been modified so that they use instructions in the
  1967. X/   extended arithmetic option for the PDP-11's e.g. sob's.
  1968. X/
  1969. X
  1970. X/   It is expected that during the reading of these routines that the
  1971. X/   general principles behind floating point work and the general operation
  1972. X/   of the floating point interpreter are understood.
  1973. X
  1974. X/   definiton of all global variables.
  1975. X
  1976. X.globl  _fadd  , _fsub  , _fmul , _fdiv , csv , cret  , areg , asign , aexp
  1977. X.globl  seta , retng , norm , saret , divv , bsign , breg , bexp , retb , reta
  1978. X.globl  csign , creg , cexp , mull , xorsign
  1979. X
  1980. X/   All the standard mathematical functions expect the second argument to
  1981. X/   be the place where the result is to be put. This is exactly how they are
  1982. X/   called from the eval() routine. ( via mbin ).
  1983. X
  1984. X
  1985. X_fadd:  jsr     r5,csv              / save the registers
  1986. X    jsr     pc,setab            / set up the parameters (in areg and breg)
  1987. X    br      1f
  1988. X
  1989. X_fsub:  jsr     r5,csv
  1990. X    jsr     pc,setab
  1991. X    neg     bsign
  1992. X1:
  1993. X    tst     bsign               / test for adding zero
  1994. X    beq     reta
  1995. X    tst     asign
  1996. X    beq     retb
  1997. X    mov     areg+8,r1           / compare the exponents
  1998. X    sub     breg+8,r1
  1999. X    blt     1f
  2000. X    beq     2f
  2001. X    cmp     r1,$56.             / test for underflows
  2002. X    bge     reta
  2003. X    mov     $breg,r0
  2004. X    br      4f
  2005. X1:
  2006. X    neg     r1
  2007. X    cmp     r1,$56.
  2008. X    bge     retb
  2009. X    mov     $areg,r0
  2010. X4:
  2011. X    mov     r1,-(sp)
  2012. X    mov     (r0)+,r1
  2013. X    mov     (r0)+,r2
  2014. X    mov     (r0)+,r3
  2015. X    mov     (r0)+,r4
  2016. X    add     (sp),(r0)
  2017. X1:
  2018. X    asr     r1                      / shift the required value
  2019. X    ror     r2
  2020. X    ror     r3
  2021. X    ror     r4
  2022. X    dec     (sp)
  2023. X    bgt     1b
  2024. X    mov     r4,-(r0)
  2025. X    mov     r3,-(r0)
  2026. X    mov     r2,-(r0)
  2027. X    mov     r1,-(r0)
  2028. X    tst     (sp)+
  2029. X2:
  2030. X    mov     $areg+8,r1
  2031. X    mov     $breg+8,r2
  2032. X    mov     $4,r0
  2033. X    cmp     asign,bsign             / compare sign of arguments
  2034. X    bne     4f
  2035. X    clc
  2036. X1:
  2037. X    adc     -(r1)                   / signs are equal so add
  2038. X    bcs     3f
  2039. X    add     -(r2),(r1)
  2040. X    sob     r0,1b
  2041. X    br      5f
  2042. X3:
  2043. X    add     -(r2),(r1)
  2044. X    sec
  2045. X    sob     r0,1b
  2046. X    br      5f
  2047. X4:
  2048. X    clc
  2049. X1:
  2050. X    sbc     -(r1)                       / signs are not so subtract
  2051. X    bcs     3f
  2052. X    sub     -(r2),(r1)
  2053. X    sob     r0,1b
  2054. X    br      5f
  2055. X3:
  2056. X    sub     -(r2),(r1)
  2057. X    sec
  2058. X    sob     r0,1b
  2059. Xsaret:                                      / return of a signed areg
  2060. X    mov     $areg,r1
  2061. X5:
  2062. X    tst     (r1)                        / is it negative
  2063. X    bge     3f
  2064. X    mov     $areg+8,r1
  2065. X    mov     $4,r0
  2066. X    clc
  2067. X1:
  2068. X    adc     -(r1)                       / yes then make positive
  2069. X    bcs     2f
  2070. X    neg     (r1)
  2071. X2:
  2072. X    sob     r0,1b
  2073. X    neg     -(r1)                       / negate sign of areg
  2074. X3:
  2075. Xcreta:
  2076. X
  2077. X    jsr     pc,norm                     / normalise result
  2078. X    br      reta
  2079. X
  2080. Xretb:
  2081. X    mov     $bsign,r1
  2082. X    mov     $asign,r2
  2083. X    mov     $6,r0
  2084. X1:
  2085. X    mov     (r1)+,(r2)+
  2086. X    sob     r0,1b
  2087. Xreta:
  2088. X    mov     6(r5),r2                    / get return address
  2089. Xretng:
  2090. X    mov     $asign,r0                / convert into normal representation
  2091. X    tst     (r0)
  2092. X    beq     unflo
  2093. X    mov     aexp,r1                 / check for overflow
  2094. X    cmp     r1,$177
  2095. X    bgt     ovflo
  2096. X    cmp     r1,$-177
  2097. X    blt     unflo                   / check for overflow
  2098. X    add     $200,r1
  2099. X    swab    r1
  2100. X    clc
  2101. X    ror     r1
  2102. X    tst     (r0)+
  2103. X    bge     1f
  2104. X    bis     $100000,r1
  2105. X1:
  2106. X    bic     $!177,(r0)
  2107. X    bis     (r0)+,r1
  2108. X    mov     r1,(r2)+
  2109. X    mov     (r0)+,(r2)+
  2110. X    mov     (r0)+,(r2)+
  2111. X    mov     (r0)+,(r2)+
  2112. X    jmp     cret
  2113. Xunflo:                                  / return zero on underflow
  2114. X    clr     (r2)+
  2115. X    clr     (r2)+
  2116. X    clr     (r2)+
  2117. X    clr     (r2)+
  2118. X    jmp     cret
  2119. X
  2120. X.globl  _error
  2121. Xovflo:
  2122. X    mov     $34.,-(sp)              / call error on overflow
  2123. X    jsr     pc,_error
  2124. Xzerodiv:
  2125. X    mov     $25.,-(sp)              / call error for zero divisor
  2126. X    jsr     pc,_error
  2127. X
  2128. X_fdiv:  jsr     r5,csv
  2129. X    jsr     pc,setab                / setup parameters
  2130. X    tst     bsign                   / check for zero divisor
  2131. X    beq     zerodiv
  2132. X    sub     bexp,aexp
  2133. X    jsr     pc,xorsign              / set the signs correctly
  2134. X    jsr     pc,divv                 / call the division routine
  2135. X    jmp     creta                   / jump to return
  2136. X
  2137. Xdivv:
  2138. X    mov     r5,-(sp)                / this routine is taken straight
  2139. X    mov     $areg,r0                / out of the floating point
  2140. X    mov     (r0),r1                 / interpreter. If you have enough
  2141. X    clr     (r0)+                   / time, try to find out how it
  2142. X    mov     (r0),r2                 / works.
  2143. X    clr     (r0)+
  2144. X    mov     (r0),r3
  2145. X    clr     (r0)+
  2146. X    mov     (r0),r4
  2147. X    clr     (r0)+
  2148. X    mov     $areg,r5
  2149. X    mov     $400,-(sp)              / ??????
  2150. X1:
  2151. X    mov     $breg,r0
  2152. X    cmp     (r0)+,r1
  2153. X    blt     2f
  2154. X    bgt     3f
  2155. X    cmp     (r0)+,r2
  2156. X    blo     2f
  2157. X    bhi     3f
  2158. X    cmp     (r0)+,r3
  2159. X    blo     2f
  2160. X    bhi     3f
  2161. X    cmp     (r0)+,r4
  2162. X    bhi     3f
  2163. X2:
  2164. X    mov     $breg,r0
  2165. X    sub     (r0)+,r1
  2166. X    clr     -(sp)
  2167. X    sub     (r0)+,r2
  2168. X    adc     (sp)
  2169. X    clr     -(sp)
  2170. X    sub     (r0)+,r3
  2171. X    adc     (sp)
  2172. X    sub     (r0)+,r4
  2173. X    sbc     r3
  2174. X    adc     (sp)
  2175. X    sub     (sp)+,r2
  2176. X    adc     (sp)
  2177. X    sub     (sp)+,r1
  2178. X    bis     (sp),(r5)
  2179. X3:
  2180. X    asl     r4
  2181. X    rol     r3
  2182. X    rol     r2
  2183. X    rol     r1
  2184. X    clc
  2185. X    ror     (sp)
  2186. X    bne     1b
  2187. X    mov     $100000,(sp)
  2188. X    add     $2,r5
  2189. X    cmp     r5,$areg+8
  2190. X    blo     1b
  2191. X    tst     (sp)+
  2192. X    mov     (sp)+,r5
  2193. X    rts     pc
  2194. X
  2195. X_fmul:  jsr     r5,csv                  / almost same as _fdiv
  2196. X    jsr     pc,setab
  2197. X    add     bexp,aexp
  2198. X    dec     aexp
  2199. X    jsr     pc,xorsign
  2200. X    jsr     pc,mull
  2201. X    jmp     creta
  2202. Xmull:
  2203. X    mov     r5,-(sp)                / also taken from the interpreter
  2204. X    mov     $breg+8,r5
  2205. X    clr     r0
  2206. X    clr     r1
  2207. X    clr     r2
  2208. X    clr     r3
  2209. X    clr     r4
  2210. X1:
  2211. X    asl     r0
  2212. X    bne     2f
  2213. X    inc     r0
  2214. X    tst     -(r5)
  2215. X2:
  2216. X    cmp     r0,$400
  2217. X    bne     2f
  2218. X    cmp     r5,$breg
  2219. X    bhi     2f
  2220. X    mov     $areg,r0
  2221. X    mov     r1,(r0)+
  2222. X    mov     r2,(r0)+
  2223. X    mov     r3,(r0)+
  2224. X    mov     r4,(r0)+
  2225. X    mov     (sp)+,r5
  2226. X    rts     pc
  2227. X2:
  2228. X    clc
  2229. X    ror     r1
  2230. X    ror     r2
  2231. X    ror     r3
  2232. X    ror     r4
  2233. X    bit     r0,(r5)
  2234. X    beq     1b
  2235. X    mov     r0,-(sp)
  2236. X    mov     $areg,r0
  2237. X    add     (r0)+,r1
  2238. X    clr     -(sp)
  2239. X    add     (r0)+,r2
  2240. X    adc     (sp)
  2241. X    clr     -(sp)
  2242. X    add     (r0)+,r3
  2243. X    adc     (sp)
  2244. X    add     (r0)+,r4
  2245. X    adc     r3
  2246. X    adc     (sp)
  2247. X    add     (sp)+,r2
  2248. X    adc     (sp)
  2249. X    add     (sp)+,r1
  2250. X    mov     (sp)+,r0
  2251. X    br      1b
  2252. X
  2253. X.globl  _integ
  2254. X_integ:
  2255. X    jsr     r5,csv
  2256. X    mov     4(r5),r2
  2257. X    mov     $asign,r0
  2258. X    jsr     pc,seta
  2259. X    clr     r0
  2260. X    mov     $200,r1
  2261. X    clr     r2
  2262. X1:
  2263. X    cmp     r0,aexp
  2264. X    blt     2f
  2265. X    bic     r1,areg(r2)
  2266. X2:
  2267. X    inc     r0
  2268. X    clc
  2269. X    ror     r1
  2270. X    bne     1b
  2271. X    mov     $100000,r1
  2272. X    add     $2,r2
  2273. X    cmp     r2,$8
  2274. X    blt     1b
  2275. X    mov     4(r5),r2
  2276. X    jmp     retng
  2277. X
  2278. X
  2279. X.globl  _fmod
  2280. X_fmod:
  2281. X    jsr     r5,csv              / this routine cheats.
  2282. X    jsr     pc,setab
  2283. X    jsr     pc,divv             / the function 'a mod b' ==
  2284. X    sub     bexp,aexp
  2285. X    jsr     pc,norm
  2286. X    clr     r0                  / count
  2287. X    mov     $200,r1             / bit
  2288. X    clr     r2                  / reg offset
  2289. X1:
  2290. X    cmp     r0,aexp
  2291. X    bge     2f                  / in fraction
  2292. X    bic     r1,areg(r2)         / this bit of code is taken from
  2293. X2:                                  / the f.p. interpreter's mod function
  2294. X    inc     r0                  / N.B. this does not do the same thing
  2295. X    clc                         / as _fmod.
  2296. X    ror     r1
  2297. X    bne     1b
  2298. X    mov     $100000,r1
  2299. X    add     $2,r2
  2300. X    cmp     r2,$8
  2301. X    blt     1b
  2302. X    jsr     pc,norm
  2303. X    jsr     pc,mull
  2304. X    add     bexp,aexp
  2305. X    dec     aexp
  2306. X    jmp     creta
  2307. X
  2308. Xxorsign:
  2309. X    cmp     asign,bsign
  2310. X    beq     1f
  2311. X    mov     $-1,asign
  2312. X    rts     pc
  2313. X1:
  2314. X    mov     $1,asign
  2315. X    rts     pc
  2316. X
  2317. Xsetab:
  2318. X    mov     $asign,r0       / set up both areg and breg
  2319. X    mov     4(r5),r2
  2320. X    jsr     pc,seta
  2321. X    mov     6(r5),r2
  2322. X    mov     $bsign,r0
  2323. X
  2324. Xseta:
  2325. X    clr     (r0)            / set up one register
  2326. X    mov     (r2)+,r1
  2327. X    mov     r1,-(sp)
  2328. X    beq     1f
  2329. X    blt     2f
  2330. X    inc     (r0)+
  2331. X    br      3f
  2332. X2:
  2333. X    dec     (r0)+
  2334. X3:
  2335. X    bic     $!177,r1
  2336. X    bis     $200,r1
  2337. X    br      2f
  2338. X1:
  2339. X    clr     (r0)+
  2340. X2:
  2341. X    mov     r1,(r0)+
  2342. X    mov     (r2)+,(r0)+
  2343. X    mov     (r2)+,(r0)+
  2344. X    mov     (r2)+,(r0)+
  2345. X    mov     (sp)+,r1
  2346. X    asl     r1
  2347. X    clrb    r1
  2348. X    swab    r1
  2349. X    sub     $200,r1
  2350. X    mov     r1,(r0)+                / exp
  2351. X    rts     pc
  2352. X
  2353. Xnorm:
  2354. X    mov     $areg,r0                / normalise the areg
  2355. X    mov     (r0)+,r1
  2356. X    mov     r1,-(sp)
  2357. X    mov     (r0)+,r2
  2358. X    bis     r2,(sp)
  2359. X    mov     (r0)+,r3
  2360. X    bis     r3,(sp)
  2361. X    mov     (r0)+,r4
  2362. X    bis     r4,(sp)+
  2363. X    bne     1f
  2364. X    clr     asign
  2365. X    rts     pc
  2366. X1:
  2367. X    bit     $!377,r1
  2368. X    beq     1f
  2369. X    clc
  2370. X    ror     r1
  2371. X    ror     r2
  2372. X    ror     r3
  2373. X    ror     r4
  2374. X    inc     (r0)
  2375. X    br      1b
  2376. X1:
  2377. X    bit     $200,r1
  2378. X    bne     1f
  2379. X    asl     r4
  2380. X    rol     r3
  2381. X    rol     r2
  2382. X    rol     r1
  2383. X    dec     (r0)
  2384. X    br      1b
  2385. X1:
  2386. X    mov     r4,-(r0)
  2387. X    mov     r3,-(r0)
  2388. X    mov     r2,-(r0)
  2389. X    mov     r1,-(r0)
  2390. X    rts     pc
  2391. X
  2392. X.bss
  2393. Xasign:  .=.+2               / the areg      - sign
  2394. Xareg:   .=.+8                   /           - mantissa
  2395. Xaexp:   .=.+2                   /           - exponent
  2396. Xbsign:  .=.+2               / the breg
  2397. Xbreg:   .=.+8
  2398. Xbexp:   .=.+2
  2399. Xcsign:  .=.+2    / the creg - this register was added so that other functions
  2400. Xcreg:   .=.+8               / could use this set up. e.g. sqrt()
  2401. Xcexp:   .=.+2               / it could be that when sin() is implemented a
  2402. X                / fourth register might be needed
  2403. End of pdp11/nfp.s
  2404. chmod u=rw-,g=r,o=r pdp11/nfp.s
  2405. echo x - pdp11/term.c 1>&2
  2406. sed 's/^X//' > pdp11/term.c << 'End of pdp11/term.c'
  2407. X/*
  2408. X * BASIC by Phil Cockcroft
  2409. X */
  2410. X/*
  2411. X * machine dependent terminal interface
  2412. X */
  2413. X
  2414. X#include "pdp11/conf.h"
  2415. X#ifdef  V7
  2416. X#include <sgtty.h>
  2417. X#endif
  2418. X
  2419. X#ifndef V7
  2420. X
  2421. Xstruct  term {                  /* the structure for the terms */
  2422. X    char    _j[4];          /* system call */
  2423. X    int     flags;          /* most of it is not needed */
  2424. X    char    __j[4];
  2425. X    char    width,length;
  2426. X    int     ___j[8];
  2427. X    } nterm, oterm;
  2428. X
  2429. X#else
  2430. X
  2431. X#ifndef SCOPE
  2432. X#define SCOPE   0
  2433. X#endif
  2434. X
  2435. X#ifdef  TIOCOSTP
  2436. X#undef  TIOCSLPN
  2437. X#endif
  2438. X
  2439. X#ifdef  TIOCSLPN
  2440. Xstruct  lsgttyb osttyb,nsttyb;
  2441. X#undef  TIOCGETP
  2442. X#undef  TIOCSETN
  2443. X#define TIOCGETP        TIOCGLPG
  2444. X#define TIOCSETN        TIOCSLPN
  2445. X#else
  2446. Xstruct  sgttyb  osttyb,nsttyb;
  2447. X#endif
  2448. Xstruct  tchars  ntchr,otchr;
  2449. X#ifdef  UCB_NTTY
  2450. Xstruct  ltchars nltchr,oltchr;
  2451. X#endif
  2452. X
  2453. X#endif
  2454. X
  2455. Xextern  int     ter_width;
  2456. Xextern  char    noedit;
  2457. X
  2458. Xstatic  int     got_mode;
  2459. X
  2460. Xsetu_term()
  2461. X{
  2462. X    register i;
  2463. X#ifdef  V7
  2464. X    char    *p, *getenv();
  2465. X
  2466. X    p = getenv("TERM");
  2467. X    ioctl(0,TIOCGETP,&osttyb);
  2468. X    nsttyb=osttyb;
  2469. X#ifdef  TIOCSLPN
  2470. X    osttyb.lsg_length = DEFLENGTH;
  2471. X    nsttyb.lsg_length = 0;
  2472. X    if(ter_width <= 0)
  2473. X        ter_width = osttyb.lsg_width & 0377;
  2474. X    osttyb.lsg_width = DEFPAGE;
  2475. X    nsttyb.lsg_width = 0;
  2476. X#endif
  2477. X#ifdef  TIOCOSTP
  2478. X    osttyb.sg_length = DEFLENGTH;
  2479. X    nsttyb.sg_length = 0;
  2480. X    if(ter_width <= 0)
  2481. X        ter_width = osttyb.sg_width & 0377;
  2482. X    osttyb.sg_width = DEFPAGE;
  2483. X    nsttyb.sg_width = 0;
  2484. X#endif
  2485. X    ioctl(0,TIOCGETC,&otchr);
  2486. X    ntchr = otchr;                  /* do we need this ??? */
  2487. X    if(p && strcmp(p, "ucl7009") == 0){
  2488. X        ntchr.t_startc = -1;
  2489. X        ntchr.t_stopc = -1;
  2490. X    }
  2491. X    ntchr.t_brkc = -1;
  2492. X    ntchr.t_eofc = -1;
  2493. X    ntchr.t_intrc = CTRLINT;
  2494. X    ntchr.t_quitc = CTRLQUIT;
  2495. X#ifdef  TIOCSLPN
  2496. X    i = osttyb.lsg_flags & ( LCASE | XTABS);
  2497. X    nsttyb.lsg_flags = CBREAK | ANYP | i;
  2498. X    osttyb.lsg_flags = ECHO | ANYP | CRMOD | SCOPE | i;
  2499. X#else
  2500. X    i = osttyb.sg_flags & ( LCASE | XTABS);
  2501. X    nsttyb.sg_flags = CBREAK | ANYP | i;
  2502. X    osttyb.sg_flags = ECHO | ANYP | CRMOD | SCOPE | i;
  2503. X#endif
  2504. X
  2505. X#ifdef  UCB_NTTY
  2506. X    ioctl(0,TIOCGLTC,&oltchr);
  2507. X    nltchr = oltchr;                /* is this needed ?? */
  2508. X    nltchr.t_suspc = -1;
  2509. X    nltchr.t_dsuspc = -1;
  2510. X    nltchr.t_rprntc = -1;
  2511. X    nltchr.t_flushc = -1;
  2512. X    nltchr.t_werasc = -1;
  2513. X    nltchr.t_lnextc = -1;
  2514. X#endif
  2515. X#else
  2516. X    terms(0,('t'<<8)+2,&oterm);
  2517. X#ifndef V6C
  2518. X    nterm = oterm;
  2519. X#else
  2520. X    terms(0,('t'<<8)+2,&nterm);
  2521. X#endif
  2522. X    nterm.width=0;
  2523. X    nterm.length=0;
  2524. X    i= oterm.flags & 04;
  2525. X    nterm.flags= 040340 |i;
  2526. X    if(ter_width <= 0)
  2527. X        ter_width = oterm.width & 0377;
  2528. X    oterm.width=0;
  2529. X    oterm.length=DEFLENGTH;
  2530. X    oterm.flags= 0730 | i;
  2531. X#endif
  2532. X    if(ter_width <= 0)
  2533. X        ter_width=DEFPAGE;
  2534. X    got_mode = 1;
  2535. X}
  2536. X
  2537. Xset_term()
  2538. X{
  2539. X    if(noedit || !got_mode)
  2540. X        return;
  2541. X#ifdef  V7
  2542. X    ioctl(0,TIOCSETN,&nsttyb);
  2543. X    ioctl(0,TIOCSETC,&ntchr);
  2544. X#ifdef  UCB_NTTY
  2545. X    ioctl(0,TIOCSLTC,&nltchr);
  2546. X#endif
  2547. X#else
  2548. X    terms(0,('t'<<8)+3,&nterm);
  2549. X#endif
  2550. X}
  2551. X
  2552. Xrset_term(type)
  2553. X{
  2554. X
  2555. X    if(noedit || !got_mode)
  2556. X        return;
  2557. X#ifdef  V7
  2558. X#ifdef  TIOCOSTP
  2559. X    if(type)
  2560. X        osttyb.sg_width=ter_width;
  2561. X#endif
  2562. X#ifdef  TIOCSLPN
  2563. X    if(type)
  2564. X        osttyb.lsg_width=ter_width;
  2565. X#endif
  2566. X    ioctl(0,TIOCSETN,&osttyb);
  2567. X    ioctl(0,TIOCSETC,&otchr);
  2568. X#ifdef  UCB_NTTY
  2569. X    ioctl(0,TIOCSLTC,&oltchr);
  2570. X#endif
  2571. X#else
  2572. X    if(type)
  2573. X        oterm.width=ter_width;
  2574. X    terms(0,('t'<<8)+3,&oterm);     /* reset terminal modes */
  2575. X#endif
  2576. X}
  2577. End of pdp11/term.c
  2578. chmod u=rw-,g=r,o=r pdp11/term.c
  2579. echo x - pyramid/Makefile 1>&2
  2580. sed 's/^X//' > pyramid/Makefile << 'End of pyramid/Makefile'
  2581. X# Makefile for a pyramid
  2582. X
  2583. X# which cursor file we want.
  2584. X# can be ucl or ukc
  2585. XCURSOR = ucl
  2586. X
  2587. Xbasic:  bas1.o bas2.o bas3.o bas4.o bas5.o bas6.o bas7.o bas8.o \
  2588. X       bas9.o cursor.o termcap.o assist.o term.o
  2589. X    cc -O bas1.o bas2.o bas3.o bas4.o bas5.o bas6.o bas7.o \
  2590. X       bas8.o bas9.o cursor.o termcap.o assist.o term.o -lm -ltermcap -o basic
  2591. X
  2592. Xclean:
  2593. X    rm -f *.o *.s cursor.c term.c
  2594. X
  2595. Xassist.o: bas.h assist.c
  2596. X    cc -O -c -Dpyramid assist.c
  2597. X
  2598. Xtermcap.o: bas.h termcap.c cursor.c
  2599. X    cc -O -c -Dpyramid termcap.c
  2600. X
  2601. Xcursor.c: cursor/cursor.c.${CURSOR}
  2602. X    cp cursor/cursor.c.${CURSOR} cursor.c
  2603. X
  2604. Xcursor.o: cursor.c
  2605. X    cc -O -c -Dpyramid cursor.c
  2606. X
  2607. Xterm.o: term.c
  2608. X    cc -O -c -Dpyramid term.c
  2609. X
  2610. Xterm.c: pyramid/term.c pyramid/conf.h
  2611. X    cp pyramid/term.c term.c
  2612. X
  2613. X.c.o:
  2614. X    cc -O -c -Dpyramid -DBSD42 $*.c
  2615. X
  2616. Xbas.h: pyramid/conf.h
  2617. X
  2618. Xbas1.o: bas1.c bas.h
  2619. Xbas2.o: bas2.c bas.h
  2620. Xbas3.o: bas3.c bas.h
  2621. Xbas4.o: bas4.c bas.h
  2622. Xbas5.o: bas5.c bas.h
  2623. Xbas6.o: bas6.c bas.h
  2624. Xbas7.o: bas7.c bas.h
  2625. Xbas7.c: cursor.c
  2626. Xbas8.o: bas8.c bas.h
  2627. Xbas9.o: bas9.c bas.h
  2628. End of pyramid/Makefile
  2629. chmod u=rw-,g=r,o=r pyramid/Makefile
  2630.  
  2631.