? DS, DS$: rem The Error Channel

In Commodore Hacking Issue #10, the end of the "Second SID Chip Installation" article was omitted. The omitted section is included below.

Certain early revisions of C=Hacking #10 are missing the end of the article by Alan Jones entitled "Solving Large Systems of Linear Equations on a C64 Without Memory". The omitted text is included below.

Second SID Chip Installation (Line 137 on)

         (c) 1987 Mark A. Dickenson

Here comes the difficult part to explain.  This is the coupling
circuit for the audio output.  Here is a rough schematic.
 
 
 
Pin 27 on             12volts dc
SID chip   resistor    !
--.          10k ohm   !collector
27!----.--/!/!/--.-----O 2n2222
--'    !         !     !emitter
       !         !     !
       <resistor !     !
       >1k       !     ! +
       <ohm      !     :--!]---to RCA
       !         !     !  10 uf
       !         !     !electrol cap
       !         !     !
ground---        !     !
       -         !     <resistor
                 !     >1k
                 !     <ohm
                 !     !
                 !     !
                 !     !
                 !    ---ground
                 !     -
                 !
                === 1000 pf (.001mf)
                 !  capacitor
                 !
                ---ground
                 -
 
 
You can get the 12 volts you need for the transistor directly from pin #28 of
the SID chip.
 
If you need any help on constructing this circuit check out any of the
many books that have schematics on the C-64.  This is similar to the one
already inside the C-64.
 
The ground wire from the RCA plug can be soldered to the main grounding
strip between the serial and video ports.  The center wire will be
connected to the negative side of the 10uf electrolitic capacitor.
 
I still think you should have someone familier with electronics install
this circuit for you.
 
If you have a problem with some cartridges, you will have to install
a switch between pin #25 of BOTH SID chips.  This will CUT the power to the
extra SID chip, effectivly turning it off.  I would suggest that you turn
OFF the computer before you turn the extra SID chip ON or OFF with this
switch.
 
A good place to mount the switch and RCA plug is on the back of the
computer and above the monitor jack on the 64.  I still haven't found a GOOD
place on the 128.  A suggestion was made that if you are not going to use
the RF output on the computer, you can cut the wire going to that RCA plug.
Then connect your audio output wire to the center connector of the plug.  This
does work but BE CAREFUL!
 
Good luck on the construction.
 
 
Mark A. Dickenson

SOLVING LARGE SYSTEMS OF LINEAR EQUATIONS ON A C64

by Alan Jones (alan.jones@qcs.org) WITHOUT MEMORY (Line 239 on)

PROC slv(n#,nr#,i#,REF a(),REF c(),REF b(,),sdb#,REF sw#(),REF fail#) CL
OSED
  // This routine solves a system of equations using the quartersolve
  // algorithm with partial pivoting.
  // It is called a "line at a time" and uses only
  // 0.25*nn memory locations which enables larger problems to be solved

Slv calls the swap'real and swap'integer proocedures from the strings
package.  The strings package is a ROMMED package on the Super Chip ROM.

It does exactly what it says, e.g.  swap'real(a,b) is the same as:
t:=a; a:=b; b:=t.

Slv calls the sdot, isamax#, sswap, sscal, saxpy, and scopy routines
from the blas package.  The blas package is LINKed to the program, but
it could, and should, be placed on EPROM.

Basic Linear Algebra Subroutines, BLAS

The BLAS were originally written for the Fortran language to speed
execution and streamline code used for solving linear algebra and other
matrix problems.  The LINPACK routines, Ref. 3, use the BLAS and are
perhaps the best known.  The idea is that the BLAS routines will be
highly optimized for a particular computer, coded in ML or a High Order
Language.  Some operating systems even include BLAS like routines.
Writing fast efficient programs is then a simple matter of selecting the
best solution algorithm and coding it in a manner that makes best use of
the blas routines.  There are blas routines for single precision, double
precision, and complex numbers.  The level 1 BLAS perform operations on
rows or columns of an array and typicaly do n scalar operations
replacing the inner most loop of code.  There are also level 2 BLAS that
perform n*n operations and Level 3 BLAS that perform n*n*n operations.
Nicholas Higham has coded most of the single precision level 1 blas
routines and put them in a Comal 2.0 package.  The Comal blas package is
included on the Packages Library Volume 2 disk.  I am not aware of ML
blas routines coded for any other C64/128 languages although this is
certainly possible and recommended.

The Comal blas routines behave exactly the same way that the Fortran
blas routines do except that Fortran can pass the starting address of an
array with just "a", while Comal requires "a(1)".  The Comal blas will
allow you pass an array, by reference, of single or multiple dimensions
and start from any position in the array.  If you code the blas routines
as ordinary Comal routines you have to pass additional parameters and
have separate routines for single dimensioned arrays and two dimensional
arrays.  Note also that Fortran stores two dimensional arrays by
columns, and Comal (like many other languages) stores two dimensional
arrays by rows.  If you translate code between Fortran and Comal using
blas routines you will have to change the increment variables.

            Fortran                          Comal
    dimension c(n), a(ilda,isda)     DIM c(n#), a(lda#,sda#)
    scopy(n,c,1,a(i,1),ilda)         scopy(n#,c(1),1,a(i#,1),1)
    scopy(n,c,1,a(1,j),1)            scopy(n#,c(1),1,a(1,j#),sda#)

The first scopy copies array c into the ith row of array a.  The second
scopy copies array c into the jth column of array a.

This is what scopy does in Fortran:

    subroutine scopy(n,sx,incx,sy,incy)
    real sx(1),sy(1)
    ix=1
    iy=1
    do 10 i = 1,n
      sy(iy) = sx(ix)
      ix = ix + incx
      iy = iy + incy
 10 continue
    return
    end

The Comal BLAS does exactly the same thing.  If coded entirely in COMAL
rather than as a package it would have to be different.  The call would
change.

scopy(n#,c(1),1,a(1,j#),sda#) would have to become,
scopy(n#,c(),1,1,a(,),1,j#,sda#,sda#) and the Comal procedure might be:

PROC scopy(n#, REF x(), ix#, incx#, REF y(,), iy#, jy#, sdy#, incy#) CLOSED
  iyinc#:=incy# DIV sdy#  //assuming y is dimensioned y(?,sdy#)
  jyinc#:=incy# MOD sdy#
  FOR i#=1 TO n# DO
    y(iy#,jy#):=x(ix#)
    ix#:+incx#; iy#:+iyinc#; jy#:+jyinc#
  ENDFOR
ENDPROC scopy

Note that more information has to be passed to the procedure and used
that the ML blas picks up automatically.  Also we would need separate
procedures to handle every combination of single and multi dimensional
arrays.  The Comal ML blas are indeed wonderful.  For speed
considerations this should also be left as an open procedure or better
yet just use in line code.

Here is a very simplified description of what each of the routines in
the Comal BLAS package does.

sum:=sasum(n#,x(1),1)  Returns sum of absolute values in x().
  sum:=0
  FOR i#:=1 TO n# DO sum:+ABS(x(i#))

saxpy(n#,sa,x(1),1,y(1),1)  Add a multiple of x() to y().
  FOR i#:=1 TO n# DO y(i#):+sa*x(i#)

prod:=sdot(n#,x(1),1,y(1),1)  Returns dot product of x() and y().
  prod:=0
  FOR i#:=1 TO n# DO prod:+x(i#)*y(i#)

sswap(n#,x(1),1,y(1),1)  Swaps x() and y().
  FOR i#:=1 TO n# DO t:=x(i#); x(i#):=y(i#); y(i#):=t

scopy(n#,x(1),1,y(1),1)  Copy x() to y().
  For i#:=1 TO n# DO y(i#):=x(i#)

max#:=isamax#(n,x(1),1)  Returns index of the element of x() with the
                         largest absolute value.
  t:=0; max#:=1
  FOR i#:=1 TO n#
    IF ABS(x(i#))>t THEN t:=ABS(x(i#)); max#:=i#
  ENDFOR i#

sscal(n#,sa,x(1),1)  Scale x() by a constant sa.
  FOR i#:=1 TO n# DO x(i#):=sa*x(i#)

snrm2(n#,x(1),1)  Returns the 2 norm of x().
  norm2:=0
  FOR i#:=1 TO n# DO norm2:+x(i#)*x(i#)
  norm2:=SQR(norm2)

srot(n#,x(1),1,y(1),1,c,s)  Apply Givens rotation.
  FOR i#:=1 TO n# DO
    t:=c*x(i#) + s*y(i#)
    y(i#):=s*x(i#) + c*y(i#)
    x(i#):=t
  ENDFOR i#


Bear in mind that each of these simple examples can be more complex as
was given for scopy.  You now have enough information to write your own
BLAS routines in ML or the programming language of your choice, or to
expand the BLAS routine calls in slv to ordinary in line code.

You can also apply the BLAS routines in creative ways besides just
operating on rows or columns.  For example you could create the identity
matrix with:

  DIM a(n#,n#)
  a(1,1):=1; a(1,2):=0
  scopy(n#*n#-2,a(1,2),0,a(1,3),1) // zero the rest of the matrix
  scopy(n#-1,a(1,1),0,a(2,2),n#+1) // copy ones to the diagonal.

References

1.  Zambardino, R. A., "Solutions of Systems of Linear Equations with
Partial Pivoting and Reduced Storage Requirements", The Computer Journal
Vol. 17, No. 4, 1974, pp. 377-378.

2.  Orden A., "Matrix Inversion and Related Topics by Direct Methods",
in Mathematical Methods for Digital Computers, Vol. 1, Edited by A.
Ralston and H. Wilf, John Wiley and Sons Inc.,  1960.

3.  Dongarra, J. J., Moeler, C. B., Bunch, J. R., Stewart, G. W.,
Linpack Users' Guide, SIAM Press, Philadelphia, 1979.


Last Updated: 1995-12-4: Rev A