v07i077: A BASIC Interpreter, Part05/06

sources-request at mirror.UUCP sources-request at mirror.UUCP
Fri Dec 5 01:35:44 AEST 1986


Submitted by: phil at Cs.Ucl.AC.UK
Mod.sources: Volume 7, Issue 77
Archive-name: basic/Part05

# Shar file shar05 (of 6)
#
# This is a shell archive containing the following files :-
#	pdp11/assist.s
#	pdp11/conf.h
#	pdp11/fpassist.s
#	pdp11/lfunc.s
#	pdp11/nfp.s
#	pdp11/term.c
#	pyramid/Makefile
# ------------------------------
# This is a shell archive, shar, format file.
# To unarchive, feed this text into /bin/sh in the directory
# you wish the files to be in.

echo x - pdp11/assist.s 1>&2
sed 's/^X//' > pdp11/assist.s << 'End of pdp11/assist.s'
X/       (c) P. (Rabbit) Cockcroft 1982
X/   This file contains machine code routines that either can't
X/   be implemented or are very slow in C.
X/
X
X/   When the 'shell' command was first added it was noticed that
X/   it would bus-error about five times ( an old form of memory
X/   allocation was being used at the time ) before it started to
X/   do the wait. The reason for this is rather awful. In the call
X/   it uses _nargs to find how many arguments it has got. This is
X/   a routine that will not work in split i and d space, since it tries
X/   to access the text segment.
X/       The routine was thus taken from the C library and has been changed
X/   to need no parameters. It just returns -1 on error or the waited for's
X/   process id.
X/
X/ pid == -1 if error
X
X.globl  _wait, cerror
X
Xwait = 7.
X
X_wait:
X	mov     r5,-(sp)
X	mov     sp,r5
X	sys     wait
X	bec     1f
X	jmp     cerror
X1:
X	tst     4(r5)
X	beq     1f
X	mov     r1,*4(r5)
X1:
X	mov     (sp)+,r5
X	rts     pc
X
X/   getch() is used all over the place to get the next character on the line.
X/   It uses 'point' ( _point ) as the pointer to the next character.
X/   It skips over all leading spaces.
X/       It was put into machine code for speed since it does not have to
X/   call csv and cret ( the C subroutine call and return routines ).
X/   this saves a lot of time. It can also be written more efficiently
X/   in machine code.
X/
X
X.text
X.globl  _point , _getch
X
X_getch:
X	mov     _point,r1
X1:      cmpb    $40,(r1)+       / ignore spaces
X	beq     1b
X	mov     r1,_point
X	clr     r0
X	bisb    -(r1),r0
X	rts     pc
X
X/   check() is used by many routines that want to know if there is any
X/   garbage characters after its arguments. e.g. in 'goto' there
X/   should be nothing after the line number. It gives a SYNTAX
X/   error if the next character is not a terminator.
X/   check() was also taken out of C for speed reasons.
X
X.globl  _point  , _check   , _elsecount  , _error
X
XELSE=   0351
X
X_check:
X	mov     _point,r0
X1:      cmpb    $40,(r0)+
X	beq     1b
X	movb    -(r0),r1
X	beq     1f
X	cmpb    r1,$':
X	beq     1f
X	cmpb    r1,$ELSE
X	bne     2f
X	tstb    _elsecount
X	beq     2f
X1:      mov     r0,_point
X	rts     pc
X2:      mov     $1,-(sp)        / syntax error
X	jsr     pc,_error
X
X/   startfp() this is called in main to intialise the floating point
X/   hardware if it is used. it is only called once to set up fpfunc()
X/   this routine does nothing in non-floating point hardware machines
X/
X.globl  _startfp  ,  _fpfunc
X
X_startfp:
X	clr     _fpfunc
X	rts     pc
X
X.bss
X_fpfunc: .=.+2
X.text
X
X/   getop() will convert a number into in ascii form to a binary number
X/   it returns non-zero if the number is ok, with the number in
X/   the union 'res'. It uses the floating point routines (nfp.s) and
X/   some of its storage locations ( areg ) to do the hard work.
X/   If the number will fit into an integer, then the value returned is an
X/   integer, with 'vartype' set accordingly. This convertion to integers
X/   is only operative if the convertion needed is an easy one.
X/   Zero is always returned as an integer.
X/       This routine was written in assembler since it is impossible
X/   to write in C.
X
X.globl  _getop
X_getop:
X	jsr     r5,csv
X	mov     $areg,r0
X	clr     (r0)+
X	clr     (r0)+
X	clr     (r0)+
X	clr     (r0)+
X	clr     aexp
X	clr     dpoint
X	clr     dflag
X	mov     $1,asign
X	clrb    _vartype
X	clr     count           / number of actual digits
X1:      movb    *_point,r4
X	inc     _point
X	cmp     r4,$'.
X	bne     4f
X	tst     dflag           / decimal point
X	bne     out1            / already had one so get out of loop
X	inc     dflag           / set the decimal point flag.
X	br      1b
X4:
X	cmp     r4,$'0
X	blt     out1
X	cmp     r4,$'9
X	bgt     out1
X	inc     count               / we have a digit
X	bit     $!07,areg           / enough space for another digit
X	bne     2f                  / no
X	sub     $'0,r4              / multiply number by ten
X	mov     r4,r2               / and add the new digit.
X	jsr     pc,tenmul
X	tst     dflag               / if we have not had a decimal point
X	beq     1b                  / don't decrement the significance
X	dec     dpoint              / counter.
X	br      1b
X2:                                  / get here if all digits are filled
X	tst     dflag               / if decimal point , forget it
X	bne     1b
X	inc     dpoint              / increment the significance counter
X	br      1b                  / get some more.
Xout1:
X	tst     count               / check to see that we have had a digit
X	bne     9f                  / yes then continue.
X	jmp     bad                 / no goto bad.
X9:      cmp     r4,$'e              / do we have an exponent.
X	bne     out2                / no.
X	clr     count               / count number of exponent digits
X	clr     r3                  / clear exponent value
X	clr     r2                  / clear exponent sign
X	movb    *_point,r4
X	inc     _point
X	cmp     r4,$'-              / exponents sign
X	bne     1f
X	inc     r2                  / set the flag
X	br      2f
X1:      cmp     r4,$'+
X	bne     3f
X2:      movb    *_point,r4
X	inc     _point
X3:
X	cmp     r4,$'0              / get the exponent digits
X	blt     1f
X	cmp     r4,$'9
X	bgt     1f
X	inc     count               / we have a digit.
X	sub     $'0,r4
X	cmp     r3,$1000.           / if the digit would make the exponent
X	blt     7f                  / greater than ten thousand
X3:                                  / for get the following digits
X	movb    *_point,r4          / ( we are heading for an overflow )
X	inc     _point
X	cmp     r4,$'0
X	blt     1f
X	cmp     r4,$'9
X	ble     3b
X	br      1f
X7:
X	mul     $12,r3              / multiply the exponent by ten and
X	add     r4,r3               / add the new digit.
X	br      2b                  / get some more
X1:
X	tst     r2                  / check sign of exponent
X	beq     1f
X	neg     r3
X1:      add     r3,dpoint           / add the exponent to the decimal
X	tst     count               / point counter
X	beq     bad                 / check to see if we had any digits
Xout2:
X	dec     _point              / adjust the character pointer
X	tst     dpoint              / check to see if number can be
X	ble     1f                  / multiplied by ten if need be.
X2:      bit     $!07,areg
X	bne     1f                  /  no
X	clr     r2
X	jsr     pc,tenmul           / multiply by ten
X	dec     dpoint
X	bne     2b
X1:
X	tst     areg                / check to see if we have an integer
X	bne     1f
X	tst     areg+2
X	bne     1f
X	tst     areg+4
X	bne     1f
X	tst     dpoint
X	bne     2f
X	bit     $100000,areg+6
X	beq     3f
X2:      tst     areg+6              / test for zero
X	bne     1f
X3:      mov     areg+6,_res         / yes we have an integer put the
X	movb    $1,_vartype         / value in 'res' and set 'vartype'
X	inc     r0                  / stop bad number error, since at this
X	jmp     cret                / point r0 is zero.
X1:
X	mov     $56.,aexp           / convert to floating point format
X	jsr     pc,norm
X	tst     dpoint              / number wants to be multiplied
X	ble     2f                  / by ten
X	cmp     dpoint,$1000.
X	bgt     bad
X1:      clr     r2
X	jsr     pc,tenmul           /  do it
X3:      bit     $!377,areg          / normalise the number
X	bne     1f
X	dec     dpoint              / decrement the counter
X	bne     1b
X	br      2f
X1:      mov     $areg,r0            / shift right to normalise
X	asr     (r0)+
X	ror     (r0)+
X	ror     (r0)+
X	ror     (r0)+
X	inc     aexp
X	cmp     aexp,$177
X	bgt     bad
X	br      3b
X2:
X	tst     dpoint              / wants to be divided by ten
X	bge     2f
X3:      mov     $3,r1
X1:      mov     $areg+8,r0          / shift left to save significant
X	asl     -(r0)               / digits
X	rol     -(r0)
X	rol     -(r0)
X	rol     -(r0)
X	dec     aexp
X	sob     r1,1b
X	jsr     pc,tendiv           / divide number by ten
X1:      bit     $200,areg           / normalise number
X	bne     1f
X	mov     $areg+8,r0          / shift left
X	asl     -(r0)
X	rol     -(r0)
X	rol     -(r0)
X	rol     -(r0)
X	dec     aexp
X	br      1b
X1:      inc     dpoint
X	bne     3b
X2:
X	cmp     aexp,$177       / check for overflow
X	bgt     bad
X	mov     $_res,r2        / return value to 'res' via the floating
X	jmp     retng           / point return routine, r0 is non-zero
Xbad:    clr     r0              / bad number , clear r0
X	jmp     cret            / return
X
X.bss
Xdflag:  .=.+2                   / temporary space for decimal point counter
X
X.text
X
X/   cmp() is used to compare two numbers , it uses 'vartype' to decide
X/   which kind of variable to test.
X/   The result is -1,0 or 1 , depending on the result of the comparison
X/
X
X.globl  _cmp   , _vartype
X
X_cmp:   mov     2(sp),r0
X	mov     4(sp),r1
X	tstb    _vartype
X	beq     6f
X	cmp     (r0)+,(r1)+
X	blt     4f
X	bgt     3f
X5:      clr     r0
X	rts     pc
X3:      mov     $1,r0
X	rts     pc
X4:      mov     $-1,r0
X	rts     pc
X				/ floating point comparisons
X6:      tst     (r0)            / straight out of the floating
X	bge     1f              / point trap routines
X	tst     (r1)
X	bge     1f
X	cmp     (r0),(r1)
X	bgt     4b
X	blt     3b
X1:
X	cmp     (r0)+,(r1)+
X	bgt     3b
X	blt     4b
X	cmp     (r0)+,(r1)+
X	bne     1f
X	cmp     (r0)+,(r1)+
X	bne     1f
X	cmp     (r0)+,(r1)+
X	beq     5b
X1:
X	bhi     3b
X	br      4b
X
X/   routine to multiply two numbers together. returns zero on overflow
X/   used in dimensio() only.
X
X.globl  _dimmul
X
X_dimmul:
X	mov     2(sp),r1
X	mul     4(sp),r1
X	bcc     1f
X	clr     r1
X1:      mov     r1,r0
X	rts     pc
X
X/   The calling routines for the maths functions ( from bas3.c).
X/   The arguments passed to the routines are as follows.
X/       at  6(sp)   The operator funtion required.
X/       at  4(sp)   The pointer to second parameter and
X/                   the location where the result is to be put.
X/       at  2(sp)   The pointer to the first parameter.
X
X/   The jump table is called by the following sequence:-
X/       (*mbin[priority*2+vartype])(&j->r1,&res,j->operator)
X/
X/   So the values in this table are such that integer and real
X/   types are dealt with separately, and the different types of operators
X/   are also dealt with seperately.
X/       e.g. *, /, mod for reals are dealt with by 'fmdm'
X/            and , or , xor for integers are dealt with by 'andor'
X/
X
X.globl  _mbin   , csv , cret , _error  , _fmul , _fdiv , _fadd , _fsub
X
X/   jump table for the maths functions
X/   straight from the eval() routine in bas3.c
X
X.data
X_mbin:  0
X	0
X	fandor
X	andor
X	comop
X	comop
X	fads
X	ads
X	fmdm
X	mdm
X	fex
X	ex
X.text
X
X/   locations from the jump table
X/   integer exponentiation , convert to reals then call the floating
X/   point convertion routines.
X/
X
Xex:     mov     2(sp),-(sp)
X	jsr     pc,_cvt
X	mov     6(sp),(sp)
X	jsr     pc,_cvt
X	tst     (sp)+
X	clrb    _vartype
Xfex:    jmp     _fexp
X
X
Xfmdm:
X	cmp     $'*,6(sp)       / times
X	bne     1f
X	jmp     _fmul
X1:
X	cmp     $'/,6(sp)       / div
X	bne     1f
X	jmp     _fdiv
X1:
X	jmp     _fmod           / mod
X
X
Xmdm:    cmp     $'*,6(sp)       / integer multiply
X	bne     1f
X	mov     *2(sp),r0
X	mul     *4(sp),r0
X	bcs     over            / overflow
X	br      2f
X1:      mov     *2(sp),r1       / divide or mod
X	sxt     r0
X	div     *4(sp),r0
X	bvs     1f
X	cmp     $'/,6(sp)       / div
X	bne     2f              / no , must be mod.
X	tst     r1
X	bne     3f
X	mov     r0,*4(sp)
X	rts     pc
X2:      mov     r1,*4(sp)
X	rts     pc
X1:      mov     $25.,-(sp)      / zero divisor error
X	jsr     pc,_error
X				/ code to do integer divisions.. etc.
X3:      mov     2(sp),-(sp)     / if the result of the integer division
X	jsr     pc,_cvt         / is not an integer then convert to
X	mov     6(sp),(sp)      / float and call the floationg point
X	jsr     pc,_cvt         / routine
X	clrb    _vartype
X	tst     (sp)+
X	jmp     _fdiv
X
Xfads:                           / floating add and subtract
X	cmp     $'+,6(sp)
X	bne     1f
X	jmp     _fadd
X1:
X	jmp     _fsub
X
X
Xads:    mov     *2(sp),r1
X	cmp     $'+,6(sp)           / add or subtract
X	bne     1f
X	add     *4(sp),r1           / add
X	br      2f
X1:      sub     *4(sp),r1           / subtract
X2:      bvs     over1               / branch on overflow
X	mov     r1,*4(sp)
X	rts     pc
X
Xover1:  tst     *2(sp)              / move value to 'overfl'
X	sxt     r0
Xover:   mov     r0,_overfl
X	mov     r1,_overfl+2
X	jmp     _over               /  return via call to 'over'
X
X/   comparison operators ( float and integer )
X/   cmp() expects to have only two parameters . So save return address
X/   and so simulate environment.
X
Xcomop:  mov     (sp)+,comsav        / save return address
X	jsr     pc,_cmp             / call comparison routine
X	mov     r0,-(sp)
X	mov     6(sp),-(sp)         / call routine to convert
X	jsr     pc,_compare         / this result into logical result
X	tst     (sp)+
X	mov     comsav,(sp)         / restore return address
X	rts     pc                  / return
X.bss
Xcomsav: .=.+2
X.text
X
X/   floating logical operators
X/   convert floating types into integers. If the value is non zero
X/   then value has a true (-1) value.
X/
X
Xfandor:
X	mov     *2(sp),r0
X	beq     2f
X	mov     $-1,r0
X2:      mov     *4(sp),r1
X	beq     2f
X	mov     $-1,r1
X2:      movb    $1,_vartype
X	br      2f
X
X/   integer logical operators
X/   does a bitwise operaotion on the two numbers ( in r0 , r1 ).
X/
X
Xandor:
X	mov     *2(sp),r0
X	mov     *4(sp),r1
X2:      cmpb    $356,6(sp)
X	bne     2f
X	com     r1
X	bic     r1,r0
X	br      1f
X2:      cmp     $357,6(sp)
X	bne     2f
X	bis     r1,r0
X	br      1f
X2:      xor     r1,r0
X1:      mov     r0,*4(sp)
X	rts     pc
X
X/   This routine converts a floationg point number into an integers
X/   if the result would overflow then return non zero.
X/
X
X.globl  _conv
X
X_conv:
X	mov     2(sp),r1
X	mov     (r1)+,r0
X	beq     3f
X	mov     (r1),r1
X	asl     r0
X	clrb    r0
X	swab    r0
X	sub     $200,r0
X	cmp     r0,$20
X	bge     1f                  / overflow or underflow
X	sub     $8,r0
X	mov     r0,-(sp)            / counter
X	mov     *4(sp),r0
X	bic     $!0177,r0
X	bis     $200,r0
X	ashc    (sp)+,r0
X	tst     *2(sp)
X	bpl     3f
X	neg     r0
X3:
X	mov     r0,*2(sp)
X	clr     r0
X	rts     pc
X
X1:      bne     1f
X	cmp     *2(sp),$144000  / check for -32768
X	bne     1f
X	bit     r1,$177400
X	bne     1f
X	mov     $-32768.,r0
X	br      3b
X1:      rts     pc
X
X
X/   convert from integer to floating point , this will never fail.
X/
X
X.globl  _cvt
X_cvt:   mov     r2,-(sp)
X	clr     r0
X	mov     *4(sp),r1
X	beq     4f
X	bpl     1f
X	neg     r1
X1:      mov     $220,r2                 /counter
X	ashc    $8,r0
X1:      bit     $200,r0
X	bne     1f
X	ashc    $1,r0
X	dec     r2
X	br      1b
X1:      swab    r2
X	ror     r2
X	tst     *4(sp)
X	bpl     1f
X	bis     $100000,r2
X1:      bic     $!177,r0
X	bis     r2,r0
X4:      mov     4(sp),r2
X	mov     r0,(r2)+
X	mov     r1,(r2)+
X	clr     (r2)+
X	clr     (r2)+
X	mov     (sp)+,r2
X	rts     pc
X
X/   add two numbers used in the 'next' routine
X/   depends on the type of the number. calls error on overflow.
X/
X
X.globl  _foreadd
X_foreadd:
X	add     2(sp),*4(sp)
X	bvs     1f
X	rts     pc
X1:      mov     $35.,-(sp)      / integer overflow
X	jsr     pc,_error
X
X/   This routine converts a floating point number into decimal
X/   It uses the following algorithm:-
X/   forever{
X/       If X > 1 then {
X/               X = X / 10
X/               decpoint++
X/               continue
X/               }
X/       If X < 0.1 then {
X/               X = X * 10
X/               decpoint--
X/               continue
X/               }
X/           }
X/       for i = 1 to 10 do {
X/               digit[i] = int ( X * 10)
X/               X = frac ( X * 10 )
X/               }
X/   This routine is not very complicated but very fiddly so was one
X/   of the last ones written.
X/
X
X
X.globl  _necvt  , tendiv , tenmul
X
X_necvt: jsr     r5,csv          / needs to look like ecvt to
X	clr     dpoint          / the outside world
X	clr     *10.(r5)
X	mov     $buf,r3
X	mov     6(r5),r2
X	mov     r2,mdigit
X	inc     r2
X	mov     r2,count
X	tst     *4(r5)
X	beq     zer
X	bpl     1f
X	inc     *10.(r5)        / sign part of ecvt
X1:      mov     4(r5),r2
X	mov     $asign,r0
X	jsr     pc,seta         / set up number in areg
X1:      tst     aexp
X	ble     1f
X	mov     $3,r1           / number is greater than one
X2:      mov     $areg+8,r0
X	asl     -(r0)           / save significant digits
X	rol     -(r0)
X	rol     -(r0)
X	rol     -(r0)
X	dec     aexp
X	sob     r1,2b
X	jsr     pc,tendiv
X	inc     dpoint          / increment decimal point
X2:      bit     $200,areg
X	bne     1b
X	mov     $areg+8,r0      / normalise after the division
X	asl     -(r0)
X	rol     -(r0)
X	rol     -(r0)
X	rol     -(r0)
X	dec     aexp
X	br      2b
X1:
X	cmp     aexp,$-3            / number greate than 0.1
X	bgt     5f
X	blt     2f
X	cmp     areg,$314
X	bgt     5f
X	blt     2f
X	mov     $3,r1
X	mov     $areg+2,r0
X3:      cmp     (r0)+,$146314
X	bhi     5f
X	blo     2f
X	sob     r1,3b
X2:                                  / no
X	clr     r2
X	jsr     pc,tenmul           / multiply by ten
X3:      tstb    areg+1
X	bne     4f
X	dec     dpoint
X	br      1b
X4:
X	mov     $areg,r0            / normalise
X	asr     (r0)+
X	ror     (r0)+
X	ror     (r0)+
X	ror     (r0)+
X	inc     aexp
X	br      3b
X5:
X	tst     aexp                / get decimal point in correct place
X	beq     9f
X1:      mov     $areg,r0
X	asr     (r0)+
X	ror     (r0)+
X	ror     (r0)+
X	ror     (r0)+
X	inc     aexp
X	bne     1b
X9:
X	clr     r2                  / get  the digits
X	jsr     pc,tenmul
X	bic     $!377,areg
X	clrb    r1                  / top word in r1
X	swab    r1
X	add     $'0,r1
X	movb    r1,(r3)+
X	dec     count               / got all digits
X	bne     9b
X	br      out
X
Xzer:    inc     dpoint              / deal with zero
X1:      movb    $'0,(r3)+
X	sob     r2,1b
Xout:                                / correct the last digit
X	mov     $buf,r0
X	add     mdigit,r0
X	movb    (r0),r2
X	add     $5,r2
X	movb    r2,(r0)
X1:
X	cmpb    (r0),$'9
X	ble     1f                  / don't correct it
X	movb    $'0,(r0)
X	cmp     r0,$buf
X	blos    2f
X	incb    -(r0)
X	br      1b
X2:
X	inc     dpoint
X	movb    $'1,(r0)            / correction has made number a one
X1:
X	mov     mdigit,r0           / pass values back
X	clrb    buf(r0)
X	mov     $buf,r0
X	mov     dpoint,*8(r5)
X	jmp     cret
X
Xtenmul:                             / multiply value in areg by 10
X	mov     $areg+8.,r4
X1:      mov     -(r4),r0
X	mul     $12,r0
X	bpl     2f
X	add     $12,r0
X2:      add     r2,r1
X	adc     r0
X	mov     r1,(r4)
X	mov     r0,r2
X	cmp     r4,$areg
X	bne     1b
X	rts     pc
X
Xtendiv:                             / divide value in areg by 10
X	mov     $areg,r4
X	clr     r0
X1:      mov     (r4),r1             / has to divide by 20 to stop
X	div     $24,r0              / multiply thinking there is an
X	asl     r0                  / overflow
X	cmp     r1,$9
X	ble     2f
X	inc     r0
X	sub     $12,r1
X2:      mov     r0,(r4)+
X	mov     r1,r0
X	cmp     r4,$areg+8
X	bne     1b
X	rts     pc
X
X	.bss
Xmdigit: .=.+2
Xcount:  .=.+2
Xbuf:    .=.+20.
Xdpoint: .=.+2
X	.text
X
X/   convert a long in 'overfl' to a real. uses the floating point
X/   routines. returns via these routines.
X
X.globl  _over
X_over:
X	jsr     r5,csv
X	clrb    _vartype
X	mov     _overfl,areg
X	mov     _overfl+2,areg+2
X	clr     areg+4
X	clr     areg+6
X	mov     $1,asign
X	mov     $32.-8,aexp
X	jmp     saret
X
X/
X/   put a value into a variable , does the convertions from integer
X/   to real and back as needed.
X/
X
X.globl  _putin
X_putin: cmpb    4(sp),_vartype
X	beq     3f
X	mov     $_res,-(sp)
X	tstb    6(sp)
X	beq     2f
X	jsr     pc,_conv
X	tst     r0
X	beq     1f
X	mov     $35.,(sp)
X	jsr     pc,_error       / no return
X2:      jsr     pc,_cvt
X1:      tst     (sp)+
X3:      mov     $_res,r0
X	mov     2(sp),r1
X	mov     (r0)+,(r1)+
X	tstb    4(sp)           / type of variable that is to be assigned
X	bne     1f              / to
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X1:      rts     pc
X
X/   high speed move of variables
X/   can't use floating point moves because of '-0'.
X
X.globl  _movein
X_movein: mov     2(sp),r0
X	mov     4(sp),r1
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	rts     pc
X
X/   puts the value from a variable into 'res'. It might be thought
X/   that 'movein' could be used but it can't for the reason given in
X/   the report.
X/
X
X.globl  _getv
X_getv:  mov     2(sp),r0
X	mov     $_res,r1
X	mov     (r0)+,(r1)+
X	tstb    _vartype
X	bne     1f
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X1:      rts     pc
X
X/   move the value in res onto the maths 'stack'. A simple floating
X/   move cannot be used due to the possibility of "minus zero" or
X/   -32768 being in 'res'. This could check 'vartype' but for speed just
X/   does the move.
X
X.globl  _push
X_push:  mov     2(sp),r1
X	mov     $_res,r0
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	rts     pc
X
X/   negate a number , checks for overflow and for type of number.
X/
X
X.globl  _negate
X_negate:
X	tstb    _vartype
X	beq     1f
X	neg     _res
X	bvs     2f                      / negating -32768
X	rts     pc
X1:      tst     _res                    / stop -0
X	beq     1f
X	add     $100000,_res
X1:      rts     pc
X2:
X	mov     $044000,_res            / 32768 in floating form
X	clr     _res+2
X	clr     _res+4
X	clr     _res+6
X	clrb    _vartype
X	rts     pc
X
X/ unary negation
X
X.globl  _notit
X
X_notit: tstb    _vartype
X	beq     1f
X	com     _res
X	rts     pc
X1:      movb    $1,_vartype
X	tst     _res
X	bne     1f
X	com     _res
X	rts     pc
X1:      clr     _res
X	rts     pc
X
X/ routine to dynamically check the stack
X.globl  _checksp
X
X_checksp:
X	cmp     sp,$160000+1024.
X	blos    1f
X	rts     pc
X1:      mov     $44.,(sp)
X	jsr     pc,_error       / no return
End of pdp11/assist.s
chmod u=rw-,g=r,o=r pdp11/assist.s
echo x - pdp11/conf.h 1>&2
sed 's/^X//' > pdp11/conf.h << 'End of pdp11/conf.h'
X/*
X * BASIC by Phil Cockcroft
X */
X/*
X * Configuration file for a pdp11
X */
X/*
X * hardware specific. Can't change MAXMEM upwards
X */
X
X#define MAXMEM          (memp)0160000   /* max data address on a pdp11 */
X#define MEMINC          1023            /* size of memory increments - 1 */
X
X/*
X * various options.
X */
X
X#define V7
X#define UCB_NTTY
X#define LKEYWORDS
X#define LNAMES
X#define RENUMB
X#define SCOMMS
X#define BERK
X
X#ifdef  BERK
X#define BLOCKSIZ        1024
X#else
X#define BLOCKSIZ        512
X#endif
X
X/*
X * terminal specific options
X */
X#define DEFPAGE         80      /* default page width */
X#define DEFLENGTH       24      /* default page length */
X#define CTRLINT         03      /* ctrl -c - sig int */
X#define CTRLQUIT        034     /* ctrl - \ FS sig quit */
X
X/* #define V7     */    /* define for v7 */
X/* #define SOFTFP */    /* define if not got fp hardware */
X/* #define V6C    */    /* if got V6 compiler (no structure assignments ) */
X/* #define BERK   */    /* define if got Berkley tty driver ( not v6 ) */
X/* #define UCB_NTTY */  /* if got the new driver ..... */
X
X/* #define NOEDIT    /* define if don't want editing ever ! */
X		     /* NB basic -e will still turn on editing */
X		     /* basic -x will still turn off editing */
X
X/* #define LKEYWORDS /* define this if you want to have variable names which*/
X		     /* contain commands this is like the later versions of */
X		     /* microsoft but not like the orignal version */
X		     /* it wastes more space since you have to have some */
X		     /* spaces in to distinguish keywords */
X
X/* #define RENUMB    /* define if you want to put the code for renumbering */
X		     /* in. It works but is very wasteful of space. If you */
X		     /* are short of space then don't use it. */
X
X/* #define LNAMES    /* define if you want long variables names. This only */
X		     /* slows it down by a small fraction */
X
X/* #define _BLOCKED  /* This is a switch to allow block mode files */
X		     /* don't define it here look below for where it is done*/
X		     /* in the file handling bits */
X/* #define SCOMMS    /* to allow shortened command names e.g. l. -> list */
X		     /* this might cause some problems with overwriting of */
X		     /* core but I think they have all been solved */
End of pdp11/conf.h
chmod u=rw-,g=r,o=r pdp11/conf.h
echo x - pdp11/fpassist.s 1>&2
sed 's/^X//' > pdp11/fpassist.s << 'End of pdp11/fpassist.s'
X/       (c) P. (Rabbit) Cockcroft 1982
X
X.globl  _wait, cerror
X
Xwait = 7.
X
X_wait:
X	mov     r5,-(sp)
X	mov     sp,r5
X	sys     wait
X	bec     1f
X	jmp     cerror
X1:	
X	tst	4(r5)
X	beq	1f
X	mov	r1,*4(5)
X1:
X	mov     (sp)+,r5
X	rts     pc
X
X/   getch() is used all over the place to get the next character on the line.
X/   It uses 'point' ( _point ) as the pointer to the next character.
X/   It skips over all leading spaces.
X/       It was put into machine code for speed since it does not have to
X/   call csv and cret ( the C subroutine call and return routines ).
X/   this saves a lot of time. It can also be written more efficiently
X/   in machine code.
X/
X
X.text
X.globl  _point , _getch
X
X_getch:
X	mov     _point,r1
X1:      cmpb    $40,(r1)+       / ignore spaces
X	beq     1b
X	mov     r1,_point
X	clr     r0
X	bisb    -(r1),r0
X	rts     pc
X
X/   check() is used by many routines that want to know if there is any
X/   garbage characters after its arguments. e.g. in 'goto' there
X/   should be nothing after the line number. It gives a SYNTAX
X/   error if the next character is not a terminator.
X/   check() was also taken out of C for speed reasons.
X
X.globl  _point  , _check   , _elsecount  , _error
X
XELSE=   0351
X
X_check:
X	mov     _point,r0
X1:      cmpb    $40,(r0)+
X	beq     1b
X	movb    -(r0),r1
X	beq     1f
X	cmpb    r1,$':
X	beq     1f
X	cmpb    r1,$ELSE
X	bne     2f
X	tstb    _elsecount
X	beq     2f
X1:      mov     r0,_point
X	rts     pc
X2:      mov     $1,-(sp)        / syntax error
X	jsr     pc,_error
X
X/   startfp() this is called in main to intialise the floating point
X/   hardware if it is used. it is only called once to set up fpfunc()
X/   this routine does nothing in non-floating point hardware machines.
X/
X
X .globl _startfp , _fpfunc
X
Xldfps = 0170100 ^ tst
X
X_startfp:
X	mov     $fpcrash,_fpfunc
X	ldfps   $1200
X	rts     pc
X.bss
X_fpfunc: .=.+2
X.text
X
Xfpcrash:
X	mov     $34.,-(sp)
X	jsr     pc,_error       / no return
X
X/   cmp() is used to compare two numbers , it uses 'vartype' to decide
X/   which kind of variable to test.
X/   The result is -1,0 or 1 , depending on the result of the comparison
X/
X
X.globl  _cmp   , _vartype
X
X_cmp:
X	tstb    _vartype
X	beq     6f
X	cmp     *2(sp),*4(sp)
X1:
X	blt     4f
X	bgt     3f
X5:      clr     r0
X	rts     pc
X3:      mov     $1,r0
X	rts     pc
X4:      mov     $-1,r0
X	rts     pc
X				/ floating point comparisons
X6:      movf    *4(sp),fr0
X	cmpf    *2(sp),fr0
X	cfcc
X	br      1b
X
X
X/   routine to multiply two numbers together. returns zero on overflow
X/   used in dimensio() only.
X
X.globl  _dimmul
X
X_dimmul:
X	mov     2(sp),r1
X	mul     4(sp),r1
X	bcc     1f
X	clr     r1
X1:      mov     r1,r0
X	rts     pc
X
X.globl  _mbin
X
X/   jump table for the maths functions
X/   straight from the eval() routine in bas3.c
X
X.data
X_mbin:  0
X	0
X	fandor
X	andor
X	comop
X	comop
X	fads
X	ads
X	fmdm
X	mdm
X	fex
X	ex
X.text
X
X/   locations from the jump table
X/   integer exponentiation , convert to reals then call the floating
X/   point convertion routines.
X/
X.globl  _exp , _log
X
Xexp:    movf    fr0,-(sp)
X	jsr     pc,_exp
X	tstf    (sp)+
X	rts     pc
X
Xlog:    movf    fr0,-(sp)
X	jsr     pc,_log
X	tstf    (sp)+
X	rts     pc
X
X
Xex:     movif   *2(sp),fr0
X	movif   *4(sp),fr1
X	movf    fr1,*4(sp)
X	clrb    _vartype
X	br      1f
Xfex:
X	movf    *2(sp),fr0
X1:
X	tstf    fr0
X	cfcc
X	beq     1f
X	bmi     2f
X	jsr     pc,log              / call log
X	mulf    *4(sp),fr0
X1:
X	jsr     pc,exp              / exponentiate
X	bes     1f
X	movf    fr0,*4(sp)
X	rts     pc
X1:      mov     $40.,-(sp)          / overflow in ^
X	jsr     pc,_error
X2:      mov     $41.,-(sp)          / negative value to ^
X	jsr     pc,_error
X
Xfmdm:
X	movf    *2(sp),fr0
X	cmp     $52,6(sp)       / times
X	bne     1f
X	mulf    *4(sp),fr0
X	movf    fr0,*4(sp)
X	rts     pc
X1:
X	movf    *4(sp),fr2
X	cfcc
X	beq     zerodiv
X	divf    fr2,fr0
X	cmp     $'/,6(sp)       / div
X	beq     1f
X	modf    $040200,fr0     / mod
X	mulf    fr2,fr0
X1:
X	movf    fr0,*4(sp)
X	rts     pc
X
X
Xmdm:    cmp     $52,6(sp)       / integer multiply
X	bne     1f
X	mov     *2(sp),r0
X	mul     *4(sp),r0
X	bcs     over            / overflow
X	br      2f
X1:      mov     *2(sp),r1       / divide or mod
X	sxt     r0
X	div     *4(sp),r0
X	bvs     1f
X	cmp     $57,6(sp)       / div
X	bne     2f              / no , must be mod.
X	tst     r1
X	bne     3f
X	mov     r0,r1
X2:      mov     r1,*4(sp)
X	rts     pc
X1:
Xzerodiv:
X	mov     $25.,-(sp)      / zero divisor error
X	jsr     pc,_error
X				/ code to do integer divisions.. etc.
X3:      movif   *2(sp),fr0
X	movif   *4(sp),fr1
X	divf    fr1,fr0
X	movf    fr0,*4(sp)
X	clrb    _vartype
X	rts     pc
X
Xfads:                           / floating add and subtract
X	movf    *2(sp),fr0
X	cmp     $53,6(sp)
X	bne     1f
X
X	addf    *4(sp),fr0
X	movf    fr0,*4(sp)
X	rts     pc
X1:
X	subf    *4(sp),fr0
X	movf    fr0,*4(sp)
X	rts     pc
X
X
Xads:    mov     *2(sp),r1
X	cmp     $53,6(sp)           / add or subtract
X	bne     1f
X	add     *4(sp),r1           / add
X	br      2f
X1:      sub     *4(sp),r1           / subtract
X2:      bvs     over1               / branch on overflow
X	mov     r1,*4(sp)
X	rts     pc
X
Xover1:  tst     *2(sp)              / move value to 'overfl'
X	sxt     r0
Xover:   mov     r0,_overfl
X	mov     r1,_overfl+2
X	jmp     _over               /  return via call to 'over'
X
X/   comparison operators ( float and integer )
X/   cmp() expects to have only two parameters . So save return address
X/   and so simulate environment.
X
Xcomop:  mov     (sp)+,comsav        / save return address
X	jsr     pc,_cmp             / call comparison routine
X	mov     r0,-(sp)
X	mov     6(sp),-(sp)         / call routine to convert
X	jsr     pc,_compare         / this result into logical result
X	tst     (sp)+
X	mov     comsav,(sp)         / restore return address
X	rts     pc                  / return
X.bss
Xcomsav: .=.+2
X.text
X
X/   floating logical operators
X/   convert floating types into integers. If the value is non zero
X/   then value has a true (-1) value.
X/
X
Xfandor:
X	mov     *2(sp),r0
X	beq     2f
X	mov     $-1,r0
X2:      mov     *4(sp),r1
X	beq     2f
X	mov     $-1,r1
X2:      movb    $1,_vartype
X	br      2f
X
X/   integer logical operators
X/   does a bitwise operaotion on the two numbers ( in r0 , r1 ).
X/
X
Xandor:
X	mov     *2(sp),r0
X	mov     *4(sp),r1
X2:      cmpb    $356,6(sp)
X	bne     2f
X	com     r1
X	bic     r1,r0
X	br      1f
X2:      cmp     $357,6(sp)
X	bne     2f
X	bis     r1,r0
X	br      1f
X2:      xor     r1,r0
X1:      mov     r0,*4(sp)
X	rts     pc
X
X/   This routine converts a floationg point number into an integers
X/   if the result would overflow then return non zero.
X/
X
X.globl  _conv
X
X_conv:
X	movf    *2(sp),fr0
X	movfi   fr0,r0
X	cfcc
X	bcs     1f
X	mov     r0,*2(sp)
X	clr     r0
X	rts     pc
X1:
X	mov     $1,r0
X	rts     pc
X
X
X/   add two numbers used in the 'next' routine
X/   depends on the type of the number. calls error on overflow.
X/
X
X.globl  _foreadd
X_foreadd:
X	add     2(sp),*4(sp)
X	bvs     1f
X	rts     pc
X1:      mov     $35.,-(sp)      / integer overflow
X	jsr     pc,_error
X
X/   convert a long in 'overfl' to a real. uses the floating point
X/   routines. returns via these routines.
X
X.globl  _over
X_over:
X	setl
X	movif   _overfl,fr0
X	clrb    _vartype
X	movf    fr0,*4(sp)
X	seti
X	rts     pc
X/
X/   put a value into a variable , does the convertions from integer
X/   to real and back as needed.
X/
X
X.globl  _putin
X_putin: cmpb    4(sp),_vartype
X	beq     1f
X	tstb    4(sp)
X	beq     2f
X	movf    _res,fr0
X	movfi   fr0,r0
X	cfcc
X	bes     3f
X	mov     r0,*2(sp)
X	rts     pc
X3:
X	mov     $35.,-(sp)
X	jsr     pc,*$_error     / no return
X2:
X	movif   _res,fr0
X	movf    fr0,*2(sp)
X	rts     pc
X1:
X	tstb    4(sp)
X	bne     1f
X	movf    _res,fr0
X	movf    fr0,*2(sp)
X	rts     pc
X1:
X	mov     _res,*2(sp)
X	rts     pc
X
X/   high speed move of variables
X/   can't use floating point moves because of '-0'.
X
X.globl  _movein
X_movein: mov     2(sp),r0
X	mov     4(sp),r1
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	rts     pc
X
X/   puts the value from a variable into 'res'. It might be thought
X/   that 'movein' could be used but it can't for the reason given in
X/   the report.
X/
X
X.globl  _getv
X_getv:  mov     2(sp),r0
X	mov     $_res,r1
X	mov     (r0)+,(r1)+
X	tstb    _vartype
X	bne     1f
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X1:      rts     pc
X
X/   move the value in res onto the maths 'stack'. A simple floating
X/   move cannot be used due to the possibility of "minus zero" or
X/   -32768 being in 'res'. This could check 'vartype' but for speed just
X/   does the move.
X
X.globl  _push
X_push:  mov     2(sp),r1
X	mov     $_res,r0
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	rts     pc
X
X/   negate a number , checks for overflow and for type of number.
X/
X
X.globl  _negate
X_negate:
X	tstb    _vartype
X	beq     1f
X	neg     _res
X	bvs     2f                      / negating -32768
X	rts     pc
X1:      tst     _res                    / stop -0
X	beq     1f
X	add     $100000,_res
X1:
X	rts     pc
X2:
X	mov     $044000,_res            / 32768 in floating form
X	clr     _res+2
X	clr     _res+4
X	clr     _res+6
X	clrb    _vartype
X	rts     pc
X
X/ unary negation
X
X.globl  _notit
X
X_notit: tstb    _vartype
X	beq     1f
X	com     _res
X	rts     pc
X1:      movb    $1,_vartype
X	tst     _res
X	bne     1f
X	com     _res
X	rts     pc
X1:      clr     _res
X	rts     pc
X
X/ routine to dynamically check the stack
X
X.globl  _checksp
X
X_checksp:
X	cmp     sp,$160000+1024.
X	blos    1f
X	rts     pc
X1:      mov     $44.,(sp)       / expression too complex
X	jsr     pc,_error       / no return
End of pdp11/fpassist.s
chmod u=rw-,g=r,o=r pdp11/fpassist.s
echo x - pdp11/lfunc.s 1>&2
sed 's/^X//' > pdp11/lfunc.s << 'End of pdp11/lfunc.s'
X/               (c) P. (Rabbit) Cockcroft 1982
X/   This file contains the routines to implement the some of the
X/   more complex mathematical functions.
X/   It currently contains the code for sqrt() , log() and exp()
X
X/   The sqrt() routine is based on the the standard Newtonian method.
X/   It uses mull and divv from nfp.s
X
X.globl  _sqrt  , sqrt
X/
X/       for ( i = 0 ; i < 6 ; i++ )
X/               areg = ( areg + creg / areg ) >> 1 ;
X/
X
X_sqrt:
X	jsr     r5,csv
X	mov     4(r5),r2
X	mov     $asign,r0
X	jsr     pc,seta
X	jsr     pc,sqrt
X	mov     4(r5),r2
X	mov     $asign,r0
X	jmp     retng
X
X
X/ value in  areg
X
Xsqrt:
X	tst     asign           / test for zero
X	bne     1f
X	rts     pc
X1:
X	bit     $1,aexp         / sort out the exponent
X	beq     1f
X	mov     $areg,r0        / shifting as need be
X	asr     (r0)+
X	ror     (r0)+
X	ror     (r0)+
X	ror     (r0)+
X	inc     aexp
X1:
X	mov     $asign,r0       / save in creg
X	mov     $csign,r1
X	mov     $6,r2
X1:
X	mov     (r0)+,(r1)+
X	sob     r2,1b
X
X	asr     aexp            / initial guess in areg
X	mov     $6.,-(sp)       / number of iterations
X
X				/ main loop starts here
X5:
X	mov     $4,r2
X	mov     $areg,r0
X	mov     $breg,r1        / set up to do the division
X1:                              / areg/breg
X	mov     (r0)+,(r1)+
X	sob     r2,1b
X	mov     $4,r2
X	mov     $creg,r0
X	mov     $areg,r1
X1:
X	mov     (r0)+,(r1)+
X	sob     r2,1b
X	jsr     pc,divv         / the division
X1:      mov     $areg+8,r0      / add result to old value
X	mov     $breg+8,r1
X	jsr     pc,addm
X	mov     $areg,r0        / divide by two
X	asr     (r0)+
X	ror     (r0)+
X	ror     (r0)+
X	ror     (r0)+
X	dec     (sp)            / decrement iteration counter
X	bne     5b
X	tst     (sp)+
X	jsr     pc,norm         / normalise result
X	rts     pc
X
X/   The routines below handle the log and exp functions
X/   They return zero if there is an error or on overflow
X/   these routines are almost totally incomprehensible but the algorithms
X/   are discussed in the report.
X
X
X	ITER=11.        / loop count
X
X.globl  _log
X_log:
X	jsr     r5,csv
X	mov     4(r5),r2
X	mov     $asign,r0
X	jsr     pc,seta
X	jsr     pc,log
X	mov     4(r5),r2
X	mov     $asign,r0
X	jmp     retng
X
X.globl  log
X
Xlog:
X	clr     pt
X	mov     $creg,r0
X	clr     (r0)+
X	clr     (r0)+
X	clr     (r0)+
X	clr     (r0)+
X1:
X	mov     pt,r1
X	mov     r1,r4
X	mul     $3,r1
X	mov     r1,pt1
X3:
X	mov     $areg,r0
X	mov     $breg,r1
X	jsr     pc,movm
X	mov     pt1,r1
X	beq     5f
X	mov     $breg,r0
X	jsr     pc,shiftl
X5:
X	mov     $breg+8,r0
X	mov     $areg+8,r1
X	jsr     pc,addm
X	cmp     breg,$400
X	bhi     2f
X	blo     5f
X	tst     breg+2
X	bne     2f
X	tst     breg+4
X	bne     2f
X	tst     breg+6
X	bne     2f
X5:
X	mov     $areg,r1
X	mov     $breg,r0
X	jsr     pc,movm
X	mov     pt,r1
X	ash     $3,r1
X	add     $logtable+8,r1
X	mov     $creg+8,r0
X	jsr     pc,addm
X	br      3b
X2:
X	inc     pt
X	cmp     pt,$ITER
X	blt     1b                      / first loop finished
X
X	sub     $400,areg
X	mov     $creg+8,r1
X	mov     $areg+8,r0
X	jsr     pc,subm
X
X	mov     aexp,r4                 / deal with the exponent
X	beq     3f
X	bmi     2f
X1:
X	mov     $logtable+8,r1          /log2n
X	mov     $areg+8,r0
X	jsr     pc,addm
X	dec     r4
X	bne     1b
X	br      3f
X2:
X	mov     $logtable+8,r1          /log2n
X	mov     $areg+8,r0
X	jsr     pc,subm
X	inc     r4
X	bne     2b
X3:
X	tst     areg
X	bpl     1f
X	mov     $areg+8,r0
X	jsr     pc,negat
X	neg     asign
X1:
X	clr     aexp
X	jsr     pc,norm
X	rts     pc
X
X
X.globl  _exp
X
X_exp:
X	jsr     r5,csv
X	mov     4(r5),r2
X	mov     $asign,r0
X	jsr     pc,seta
X	jsr     pc,exp
X	bec     1f
X	clr     r0
X	jmp     cret
X1:
X	mov     4(r5),r2
X	mov     $asign,r0
X	jmp     retng
X
X.globl  exp
X
Xexp:    clr     cexp
X	tst     aexp            / test of exponent.
X	bmi     1f
X	beq     5f
X	cmp     aexp,$7
X	ble     4f
X	sec
X	rts     pc
X4:
X	mov     $areg+8,r0
X	asl     -(r0)
X	rol     -(r0)
X	rol     -(r0)
X	rol     -(r0)
X	dec     aexp
X	bne     4b
X4:
X	tstb    areg+1
X	beq     5f
X	mov     $logtable+8,r1
X	mov     $areg+8,r0
X	jsr     pc,subm
X	inc     cexp
X	br      4b
X5:      mov     $logtable+8,r1
X	mov     $areg+8,r0
X	jsr     pc,subm
X	tst     areg
X	bpl     3f
X	mov     $logtable+8,r1
X	mov     $areg+8,r0
X	jsr     pc,addm
X	br      5f
X3:      inc     cexp
X	br      5f
X1:
X	mov     $areg,r0
X	mov     aexp,r1
X	neg     r1
X	jsr     pc,shiftl
X
X5:      mov     $1,r4           / main loop starts here
X3:
X	clrb    count(r4)
X	mov     r4,r1
X	ash     $3,r1
X	add     $logtable+8,r1
X	mov     r1,r3
X2:
X	mov     $areg+8,r0
X	jsr     pc,subm
X	tst     areg
X	bmi     1f
X	incb    count(r4)
X	mov     r3,r1
X	br      2b
X1:
X	mov     r3,r1
X	mov     $areg+8,r0
X	jsr     pc,addm
X	inc     r4
X	cmp     r4,$ITER
X	blt     3b              / end of first loop
X6:
X
X	add     $400,areg
X	mov     $1,pt
X1:
X	mov     pt,r1
X	mul     $3,r1
X	mov     r1,pt1
X2:
X	mov     pt,r4
X	tstb    count(r4)
X	beq     2f
X	decb    count(r4)
X	mov     $areg,r0
X	mov     $breg,r1
X	jsr     pc,movm
X	mov     pt1,r1
X	beq     5f
X	mov     $breg,r0
X	jsr     pc,shiftl
X5:
X	mov     $breg+8,r1
X	mov     $areg+8,r0
X	jsr     pc,addm
X	br      2b
X2:
X	inc     pt
X	cmp     pt,$ITER
X	blt     1b
X	tst     asign
X	bne     3f
X	inc     asign
X3:
X	mov     cexp,aexp
X	jsr     pc,norm
X	tst     asign
X	bpl     1f
X	jsr     pc,recip
X	neg     asign
X1:
X	cmp     aexp,$177
X	ble     1f
X	sec
X	rts     pc
X1:
X	clc
X	rts     pc
X
X.globl  recip
Xrecip:
X	mov     $areg,r0                / return reciprical of areg
X	mov     $breg,r1                / done by division
X	jsr     pc,movm
X	mov     $200,areg
X	clr     areg+2
X	clr     areg+4
X	clr     areg+6
X	jsr     pc,divv
X	neg     aexp
X	inc     aexp
X	jsr     pc,norm
X	rts     pc
X
X
X.bss
Xcount:  .=.+12.                 / counters for the log and exp functs.
Xpt:     .=.+2
Xpt1:    .=.+2
X
X.globl  logtable
X
X.data
X	/ log2n is in fact the first entry in logtable
X
Xlogtable:
X	000261; 071027; 173721; 147572
X	000036; 023407; 067052; 171341
X	000003; 174025; 013037; 100174
X	000000; 077740; 005246; 126103
X	000000; 007777; 100005; 052425
X	000000; 000777; 177000; 001252
X	000000; 000077; 177770; 000001
X	000000; 000007; 177777; 160000
X	000000; 000000; 177777; 177600
X	000000; 000000; 017777; 177777
X	000000; 000000; 001777; 177777
X.text
X
X.globl  _fexp
X_fexp:  jsr     r5,csv              / do exponentiation
X	mov     4(r5),r2
X	mov     $asign,r0
X	jsr     pc,seta
X	tst     asign               / deal with 0^x
X	beq     1f
X	bmi     2f
X	jsr     pc,log              / call log
X	mov     6(r5),r2
X	mov     $bsign,r0
X	jsr     pc,seta
X	jsr     pc,mull             / multiply
X	add     bexp,aexp
X	dec     aexp
X	jsr     pc,xorsign
X	jsr     pc,norm
X1:
X	jsr     pc,exp              / exponentiate
X	bes     1f
X	mov     6(r5),r2
X	jmp     retng
X1:      mov     $40.,-(sp)          / overflow in ^
X	jsr     pc,_error
X2:      mov     $41.,-(sp)          / negative value to ^
X	jsr     pc,_error
X
X/ trig functions that are not as yet implemented
X/ put in as place holders. Calls error with illegal function
X
X.globl  _sin , _cos , _atan
X_sin:
X_cos:
X_atan:
X	mov     $11.,-(sp)
X	jsr     pc,_error
X
X/   These routines do quad precision arithmetic and are called by many of
X/   the higher mathematical functions. These are usually called with the
X/   addresses of the operands in r0 and r1. (r0 is usually destination )
X
X.globl  addm , subm , movm , shiftl , negat
X
Xaddm:
X	mov     $4,r2                  / add quad length
X	clc
X1:
X	adc     -(r0)
X	bcs     3f
X	add     -(r1),(r0)
X	sob     r2,1b
X	rts     pc
X3:
X	add     -(r1),(r0)
X	sec
X	sob     r2,1b
X	rts     pc
X
X
Xsubm:                               / subtract quad length
X	mov     $4,r2
X	clc
X1:
X	sbc     -(r0)
X	bcs     3f
X	sub     -(r1),(r0)
X	sob     r2,1b
X	rts     pc
X3:
X	sub     -(r1),(r0)
X	sec
X	sob     r2,1b
X	rts     pc
X
Xshiftl:                             / a misnomer
X	mov     r5,-(sp)            / it actually shifts right
X	mov     r1,r5               / the number of places in r1
X	mov     (r0)+,r1
X	mov     (r0)+,r2
X	mov     (r0)+,r3
X	mov     (r0)+,r4
X1:
X	asr     r1
X	ror     r2
X	ror     r3
X	ror     r4
X	sob     r5,1b
X	mov     r4,-(r0)
X	mov     r3,-(r0)
X	mov     r2,-(r0)
X	mov     r1,-(r0)
X	mov     (sp)+,r5
X	rts     pc
X
Xmovm:                               / quad move - the parameters are the
X	mov     (r0)+,(r1)+         / other way around
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	mov     (r0)+,(r1)+
X	rts     pc
X
X
Xnegat:                              / quad negation
X	mov     $4,r1
X	clc
X1:
X	adc     -(r0)
X	bcs     2f
X	neg     (r0)
X2:
X	sob     r1,1b
X	rts     pc
End of pdp11/lfunc.s
chmod u=rw-,g=r,o=r pdp11/lfunc.s
echo x - pdp11/nfp.s 1>&2
sed 's/^X//' > pdp11/nfp.s << 'End of pdp11/nfp.s'
X/       (c) P. (Rabbit) Cockcroft 1982
X/   this file contains all the floating point routines to execute the four
X/   basic mathematical functions. Also routines for exponentiation and the
X/   floating mod function.
X/
X/   These routines are the same as used in the floating point simulator
X/   but have been changed to make them more flexible and to enable the use
X/   of C calling and return conventions.
X/   They have also been modified so that they use instructions in the
X/   extended arithmetic option for the PDP-11's e.g. sob's.
X/
X
X/   It is expected that during the reading of these routines that the
X/   general principles behind floating point work and the general operation
X/   of the floating point interpreter are understood.
X
X/   definiton of all global variables.
X
X.globl  _fadd  , _fsub  , _fmul , _fdiv , csv , cret  , areg , asign , aexp
X.globl  seta , retng , norm , saret , divv , bsign , breg , bexp , retb , reta
X.globl  csign , creg , cexp , mull , xorsign
X
X/   All the standard mathematical functions expect the second argument to
X/   be the place where the result is to be put. This is exactly how they are
X/   called from the eval() routine. ( via mbin ).
X
X
X_fadd:  jsr     r5,csv              / save the registers
X	jsr     pc,setab            / set up the parameters (in areg and breg)
X	br      1f
X
X_fsub:  jsr     r5,csv
X	jsr     pc,setab
X	neg     bsign
X1:
X	tst     bsign               / test for adding zero
X	beq     reta
X	tst     asign
X	beq     retb
X	mov     areg+8,r1           / compare the exponents
X	sub     breg+8,r1
X	blt     1f
X	beq     2f
X	cmp     r1,$56.             / test for underflows
X	bge     reta
X	mov     $breg,r0
X	br      4f
X1:
X	neg     r1
X	cmp     r1,$56.
X	bge     retb
X	mov     $areg,r0
X4:
X	mov     r1,-(sp)
X	mov     (r0)+,r1
X	mov     (r0)+,r2
X	mov     (r0)+,r3
X	mov     (r0)+,r4
X	add     (sp),(r0)
X1:
X	asr     r1                      / shift the required value
X	ror     r2
X	ror     r3
X	ror     r4
X	dec     (sp)
X	bgt     1b
X	mov     r4,-(r0)
X	mov     r3,-(r0)
X	mov     r2,-(r0)
X	mov     r1,-(r0)
X	tst     (sp)+
X2:
X	mov     $areg+8,r1
X	mov     $breg+8,r2
X	mov     $4,r0
X	cmp     asign,bsign             / compare sign of arguments
X	bne     4f
X	clc
X1:
X	adc     -(r1)                   / signs are equal so add
X	bcs     3f
X	add     -(r2),(r1)
X	sob     r0,1b
X	br      5f
X3:
X	add     -(r2),(r1)
X	sec
X	sob     r0,1b
X	br      5f
X4:
X	clc
X1:
X	sbc     -(r1)                       / signs are not so subtract
X	bcs     3f
X	sub     -(r2),(r1)
X	sob     r0,1b
X	br      5f
X3:
X	sub     -(r2),(r1)
X	sec
X	sob     r0,1b
Xsaret:                                      / return of a signed areg
X	mov     $areg,r1
X5:
X	tst     (r1)                        / is it negative
X	bge     3f
X	mov     $areg+8,r1
X	mov     $4,r0
X	clc
X1:
X	adc     -(r1)                       / yes then make positive
X	bcs     2f
X	neg     (r1)
X2:
X	sob     r0,1b
X	neg     -(r1)                       / negate sign of areg
X3:
Xcreta:
X
X	jsr     pc,norm                     / normalise result
X	br      reta
X
Xretb:
X	mov     $bsign,r1
X	mov     $asign,r2
X	mov     $6,r0
X1:
X	mov     (r1)+,(r2)+
X	sob     r0,1b
Xreta:
X	mov     6(r5),r2                    / get return address
Xretng:
X	mov     $asign,r0                / convert into normal representation
X	tst     (r0)
X	beq     unflo
X	mov     aexp,r1                 / check for overflow
X	cmp     r1,$177
X	bgt     ovflo
X	cmp     r1,$-177
X	blt     unflo                   / check for overflow
X	add     $200,r1
X	swab    r1
X	clc
X	ror     r1
X	tst     (r0)+
X	bge     1f
X	bis     $100000,r1
X1:
X	bic     $!177,(r0)
X	bis     (r0)+,r1
X	mov     r1,(r2)+
X	mov     (r0)+,(r2)+
X	mov     (r0)+,(r2)+
X	mov     (r0)+,(r2)+
X	jmp     cret
Xunflo:                                  / return zero on underflow
X	clr     (r2)+
X	clr     (r2)+
X	clr     (r2)+
X	clr     (r2)+
X	jmp     cret
X
X.globl  _error
Xovflo:
X	mov     $34.,-(sp)              / call error on overflow
X	jsr     pc,_error
Xzerodiv:
X	mov     $25.,-(sp)              / call error for zero divisor
X	jsr     pc,_error
X
X_fdiv:  jsr     r5,csv
X	jsr     pc,setab                / setup parameters
X	tst     bsign                   / check for zero divisor
X	beq     zerodiv
X	sub     bexp,aexp
X	jsr     pc,xorsign              / set the signs correctly
X	jsr     pc,divv                 / call the division routine
X	jmp     creta                   / jump to return
X
Xdivv:
X	mov     r5,-(sp)                / this routine is taken straight
X	mov     $areg,r0                / out of the floating point
X	mov     (r0),r1                 / interpreter. If you have enough
X	clr     (r0)+                   / time, try to find out how it
X	mov     (r0),r2                 / works.
X	clr     (r0)+
X	mov     (r0),r3
X	clr     (r0)+
X	mov     (r0),r4
X	clr     (r0)+
X	mov     $areg,r5
X	mov     $400,-(sp)              / ??????
X1:
X	mov     $breg,r0
X	cmp     (r0)+,r1
X	blt     2f
X	bgt     3f
X	cmp     (r0)+,r2
X	blo     2f
X	bhi     3f
X	cmp     (r0)+,r3
X	blo     2f
X	bhi     3f
X	cmp     (r0)+,r4
X	bhi     3f
X2:
X	mov     $breg,r0
X	sub     (r0)+,r1
X	clr     -(sp)
X	sub     (r0)+,r2
X	adc     (sp)
X	clr     -(sp)
X	sub     (r0)+,r3
X	adc     (sp)
X	sub     (r0)+,r4
X	sbc     r3
X	adc     (sp)
X	sub     (sp)+,r2
X	adc     (sp)
X	sub     (sp)+,r1
X	bis     (sp),(r5)
X3:
X	asl     r4
X	rol     r3
X	rol     r2
X	rol     r1
X	clc
X	ror     (sp)
X	bne     1b
X	mov     $100000,(sp)
X	add     $2,r5
X	cmp     r5,$areg+8
X	blo     1b
X	tst     (sp)+
X	mov     (sp)+,r5
X	rts     pc
X
X_fmul:  jsr     r5,csv                  / almost same as _fdiv
X	jsr     pc,setab
X	add     bexp,aexp
X	dec     aexp
X	jsr     pc,xorsign
X	jsr     pc,mull
X	jmp     creta
Xmull:
X	mov     r5,-(sp)                / also taken from the interpreter
X	mov     $breg+8,r5
X	clr     r0
X	clr     r1
X	clr     r2
X	clr     r3
X	clr     r4
X1:
X	asl     r0
X	bne     2f
X	inc     r0
X	tst     -(r5)
X2:
X	cmp     r0,$400
X	bne     2f
X	cmp     r5,$breg
X	bhi     2f
X	mov     $areg,r0
X	mov     r1,(r0)+
X	mov     r2,(r0)+
X	mov     r3,(r0)+
X	mov     r4,(r0)+
X	mov     (sp)+,r5
X	rts     pc
X2:
X	clc
X	ror     r1
X	ror     r2
X	ror     r3
X	ror     r4
X	bit     r0,(r5)
X	beq     1b
X	mov     r0,-(sp)
X	mov     $areg,r0
X	add     (r0)+,r1
X	clr     -(sp)
X	add     (r0)+,r2
X	adc     (sp)
X	clr     -(sp)
X	add     (r0)+,r3
X	adc     (sp)
X	add     (r0)+,r4
X	adc     r3
X	adc     (sp)
X	add     (sp)+,r2
X	adc     (sp)
X	add     (sp)+,r1
X	mov     (sp)+,r0
X	br      1b
X
X.globl  _integ
X_integ:
X	jsr     r5,csv
X	mov     4(r5),r2
X	mov     $asign,r0
X	jsr     pc,seta
X	clr     r0
X	mov     $200,r1
X	clr     r2
X1:
X	cmp     r0,aexp
X	blt     2f
X	bic     r1,areg(r2)
X2:
X	inc     r0
X	clc
X	ror     r1
X	bne     1b
X	mov     $100000,r1
X	add     $2,r2
X	cmp     r2,$8
X	blt     1b
X	mov     4(r5),r2
X	jmp     retng
X
X
X.globl  _fmod
X_fmod:
X	jsr     r5,csv              / this routine cheats.
X	jsr     pc,setab
X	jsr     pc,divv             / the function 'a mod b' ==
X	sub     bexp,aexp
X	jsr     pc,norm
X	clr     r0                  / count
X	mov     $200,r1             / bit
X	clr     r2                  / reg offset
X1:
X	cmp     r0,aexp
X	bge     2f                  / in fraction
X	bic     r1,areg(r2)         / this bit of code is taken from
X2:                                  / the f.p. interpreter's mod function
X	inc     r0                  / N.B. this does not do the same thing
X	clc                         / as _fmod.
X	ror     r1
X	bne     1b
X	mov     $100000,r1
X	add     $2,r2
X	cmp     r2,$8
X	blt     1b
X	jsr     pc,norm
X	jsr     pc,mull
X	add     bexp,aexp
X	dec     aexp
X	jmp     creta
X
Xxorsign:
X	cmp     asign,bsign
X	beq     1f
X	mov     $-1,asign
X	rts     pc
X1:
X	mov     $1,asign
X	rts     pc
X
Xsetab:
X	mov     $asign,r0       / set up both areg and breg
X	mov     4(r5),r2
X	jsr     pc,seta
X	mov     6(r5),r2
X	mov     $bsign,r0
X
Xseta:
X	clr     (r0)            / set up one register
X	mov     (r2)+,r1
X	mov     r1,-(sp)
X	beq     1f
X	blt     2f
X	inc     (r0)+
X	br      3f
X2:
X	dec     (r0)+
X3:
X	bic     $!177,r1
X	bis     $200,r1
X	br      2f
X1:
X	clr     (r0)+
X2:
X	mov     r1,(r0)+
X	mov     (r2)+,(r0)+
X	mov     (r2)+,(r0)+
X	mov     (r2)+,(r0)+
X	mov     (sp)+,r1
X	asl     r1
X	clrb    r1
X	swab    r1
X	sub     $200,r1
X	mov     r1,(r0)+                / exp
X	rts     pc
X
Xnorm:
X	mov     $areg,r0                / normalise the areg
X	mov     (r0)+,r1
X	mov     r1,-(sp)
X	mov     (r0)+,r2
X	bis     r2,(sp)
X	mov     (r0)+,r3
X	bis     r3,(sp)
X	mov     (r0)+,r4
X	bis     r4,(sp)+
X	bne     1f
X	clr     asign
X	rts     pc
X1:
X	bit     $!377,r1
X	beq     1f
X	clc
X	ror     r1
X	ror     r2
X	ror     r3
X	ror     r4
X	inc     (r0)
X	br      1b
X1:
X	bit     $200,r1
X	bne     1f
X	asl     r4
X	rol     r3
X	rol     r2
X	rol     r1
X	dec     (r0)
X	br      1b
X1:
X	mov     r4,-(r0)
X	mov     r3,-(r0)
X	mov     r2,-(r0)
X	mov     r1,-(r0)
X	rts     pc
X
X.bss
Xasign:  .=.+2               / the areg      - sign
Xareg:   .=.+8                   /           - mantissa
Xaexp:   .=.+2                   /           - exponent
Xbsign:  .=.+2               / the breg
Xbreg:   .=.+8
Xbexp:   .=.+2
Xcsign:  .=.+2    / the creg - this register was added so that other functions
Xcreg:   .=.+8               / could use this set up. e.g. sqrt()
Xcexp:   .=.+2               / it could be that when sin() is implemented a
X			    / fourth register might be needed
End of pdp11/nfp.s
chmod u=rw-,g=r,o=r pdp11/nfp.s
echo x - pdp11/term.c 1>&2
sed 's/^X//' > pdp11/term.c << 'End of pdp11/term.c'
X/*
X * BASIC by Phil Cockcroft
X */
X/*
X * machine dependent terminal interface
X */
X
X#include "pdp11/conf.h"
X#ifdef  V7
X#include <sgtty.h>
X#endif
X
X#ifndef V7
X
Xstruct  term {                  /* the structure for the terms */
X	char    _j[4];          /* system call */
X	int     flags;          /* most of it is not needed */
X	char    __j[4];
X	char    width,length;
X	int     ___j[8];
X	} nterm, oterm;
X
X#else
X
X#ifndef SCOPE
X#define SCOPE   0
X#endif
X
X#ifdef  TIOCOSTP
X#undef  TIOCSLPN
X#endif
X
X#ifdef  TIOCSLPN
Xstruct  lsgttyb osttyb,nsttyb;
X#undef  TIOCGETP
X#undef  TIOCSETN
X#define TIOCGETP        TIOCGLPG
X#define TIOCSETN        TIOCSLPN
X#else
Xstruct  sgttyb  osttyb,nsttyb;
X#endif
Xstruct  tchars  ntchr,otchr;
X#ifdef  UCB_NTTY
Xstruct  ltchars nltchr,oltchr;
X#endif
X
X#endif
X
Xextern  int     ter_width;
Xextern  char    noedit;
X
Xstatic  int     got_mode;
X
Xsetu_term()
X{
X	register i;
X#ifdef  V7
X	char    *p, *getenv();
X
X	p = getenv("TERM");
X	ioctl(0,TIOCGETP,&osttyb);
X	nsttyb=osttyb;
X#ifdef  TIOCSLPN
X	osttyb.lsg_length = DEFLENGTH;
X	nsttyb.lsg_length = 0;
X	if(ter_width <= 0)
X		ter_width = osttyb.lsg_width & 0377;
X	osttyb.lsg_width = DEFPAGE;
X	nsttyb.lsg_width = 0;
X#endif
X#ifdef  TIOCOSTP
X	osttyb.sg_length = DEFLENGTH;
X	nsttyb.sg_length = 0;
X	if(ter_width <= 0)
X		ter_width = osttyb.sg_width & 0377;
X	osttyb.sg_width = DEFPAGE;
X	nsttyb.sg_width = 0;
X#endif
X	ioctl(0,TIOCGETC,&otchr);
X	ntchr = otchr;                  /* do we need this ??? */
X	if(p && strcmp(p, "ucl7009") == 0){
X		ntchr.t_startc = -1;
X		ntchr.t_stopc = -1;
X	}
X	ntchr.t_brkc = -1;
X	ntchr.t_eofc = -1;
X	ntchr.t_intrc = CTRLINT;
X	ntchr.t_quitc = CTRLQUIT;
X#ifdef  TIOCSLPN
X	i = osttyb.lsg_flags & ( LCASE | XTABS);
X	nsttyb.lsg_flags = CBREAK | ANYP | i;
X	osttyb.lsg_flags = ECHO | ANYP | CRMOD | SCOPE | i;
X#else
X	i = osttyb.sg_flags & ( LCASE | XTABS);
X	nsttyb.sg_flags = CBREAK | ANYP | i;
X	osttyb.sg_flags = ECHO | ANYP | CRMOD | SCOPE | i;
X#endif
X
X#ifdef  UCB_NTTY
X	ioctl(0,TIOCGLTC,&oltchr);
X	nltchr = oltchr;                /* is this needed ?? */
X	nltchr.t_suspc = -1;
X	nltchr.t_dsuspc = -1;
X	nltchr.t_rprntc = -1;
X	nltchr.t_flushc = -1;
X	nltchr.t_werasc = -1;
X	nltchr.t_lnextc = -1;
X#endif
X#else
X	terms(0,('t'<<8)+2,&oterm);
X#ifndef V6C
X	nterm = oterm;
X#else
X	terms(0,('t'<<8)+2,&nterm);
X#endif
X	nterm.width=0;
X	nterm.length=0;
X	i= oterm.flags & 04;
X	nterm.flags= 040340 |i;
X	if(ter_width <= 0)
X		ter_width = oterm.width & 0377;
X	oterm.width=0;
X	oterm.length=DEFLENGTH;
X	oterm.flags= 0730 | i;
X#endif
X	if(ter_width <= 0)
X		ter_width=DEFPAGE;
X	got_mode = 1;
X}
X
Xset_term()
X{
X	if(noedit || !got_mode)
X		return;
X#ifdef  V7
X	ioctl(0,TIOCSETN,&nsttyb);
X	ioctl(0,TIOCSETC,&ntchr);
X#ifdef  UCB_NTTY
X	ioctl(0,TIOCSLTC,&nltchr);
X#endif
X#else
X	terms(0,('t'<<8)+3,&nterm);
X#endif
X}
X
Xrset_term(type)
X{
X
X	if(noedit || !got_mode)
X		return;
X#ifdef  V7
X#ifdef  TIOCOSTP
X	if(type)
X		osttyb.sg_width=ter_width;
X#endif
X#ifdef  TIOCSLPN
X	if(type)
X		osttyb.lsg_width=ter_width;
X#endif
X	ioctl(0,TIOCSETN,&osttyb);
X	ioctl(0,TIOCSETC,&otchr);
X#ifdef  UCB_NTTY
X	ioctl(0,TIOCSLTC,&oltchr);
X#endif
X#else
X	if(type)
X		oterm.width=ter_width;
X	terms(0,('t'<<8)+3,&oterm);     /* reset terminal modes */
X#endif
X}
End of pdp11/term.c
chmod u=rw-,g=r,o=r pdp11/term.c
echo x - pyramid/Makefile 1>&2
sed 's/^X//' > pyramid/Makefile << 'End of pyramid/Makefile'
X# Makefile for a pyramid
X
X# which cursor file we want.
X# can be ucl or ukc
XCURSOR = ucl
X
Xbasic:  bas1.o bas2.o bas3.o bas4.o bas5.o bas6.o bas7.o bas8.o \
X       bas9.o cursor.o termcap.o assist.o term.o
X	cc -O bas1.o bas2.o bas3.o bas4.o bas5.o bas6.o bas7.o \
X       bas8.o bas9.o cursor.o termcap.o assist.o term.o -lm -ltermcap -o basic
X
Xclean:
X	rm -f *.o *.s cursor.c term.c
X
Xassist.o: bas.h assist.c
X	cc -O -c -Dpyramid assist.c
X
Xtermcap.o: bas.h termcap.c cursor.c
X	cc -O -c -Dpyramid termcap.c
X
Xcursor.c: cursor/cursor.c.${CURSOR}
X	cp cursor/cursor.c.${CURSOR} cursor.c
X
Xcursor.o: cursor.c
X	cc -O -c -Dpyramid cursor.c
X
Xterm.o: term.c
X	cc -O -c -Dpyramid term.c
X
Xterm.c: pyramid/term.c pyramid/conf.h
X	cp pyramid/term.c term.c
X
X.c.o:
X	cc -O -c -Dpyramid -DBSD42 $*.c
X
Xbas.h: pyramid/conf.h
X
Xbas1.o: bas1.c bas.h
Xbas2.o: bas2.c bas.h
Xbas3.o: bas3.c bas.h
Xbas4.o: bas4.c bas.h
Xbas5.o: bas5.c bas.h
Xbas6.o: bas6.c bas.h
Xbas7.o: bas7.c bas.h
Xbas7.c: cursor.c
Xbas8.o: bas8.c bas.h
Xbas9.o: bas9.c bas.h
End of pyramid/Makefile
chmod u=rw-,g=r,o=r pyramid/Makefile



More information about the Mod.sources mailing list