Tag Archives: Basic

1st basic example

Like with the T2C64, the CPLD on the T2A2 maps the C012 registers into the memory area of the used slot, using just 6 addresses starting at 0xc080 + (SLOT# * 0x10). So for e.g. Slot 4 this would be:

  • BASE        (0xc080 + (4 * 0x10))  = 49344
  • Data in:    BASE                   49344
  • Data out:  (BASE + 1)           49345
  • in-status:  (BASE + 2)           49346
  • out-status:(BASE + 3)           49347
  • reset:       (BASE + 8)           49352 (writing)
  • analyse:   (BASE + 12)          49356
  • errorflag:  (BASE + 8)           49352 (reading)

With this ‘knowlege’ we can start talking to the Transputer… and to make our first babysteps we’re using BASIC. It’s pretty much the same code as used on the C64 with the exception that there’s no “elegant” timeout handling due to the missing clock in AppleSoft, so you have to wait a bit longer until you get the printout in the end.
For details about what’s going on here, see the C64 page.

 10  PRINT "INIT TRANSPUTER"
11 BASE = 49344:IN = BASE:OUT = BASE + 1:IS = BASE + 2
12 OS = BASE + 3:RESET = BASE + 8:ANA = BASE + 12
13  POKE RESET,0: POKE ANA,1: POKE RESET,1
20  REM CLEAR I/O ENABLE
21  POKE IS,0
22  POKE OS,0
30  REM READ STATI
31  PRINT "I STATUS: ";( PEEK (IS) AND 1)
35  PRINT "O STATUS: ";( PEEK (OS) AND 1)
40  PRINT "ERROR: ";( PEEK (RESET) AND 1)
45  PRINT "SENDING POKE COMMAND"
46  POKE OUT,0
50  PRINT "O STATUS: ";( PEEK (OS) AND 1)
58 :
59  PRINT "SENDING DATA TO T."
60  POKE OUT,0: POKE OUT,0: POKE OUT,0: POKE OUT,128
61  POKE OUT,12: POKE OUT,34: POKE OUT,56: POKE OUT,78
70  PRINT "I STATUS: ";( PEEK (IS) AND 1)
79 :
80  PRINT "READING FROM T."
90  POKE OUT,1: REM PEEKING
100  POKE OUT,0: POKE OUT,0: POKE OUT,0: POKE OUT,128
110  PRINT  PEEK (IN); PEEK (IN); PEEK (IN); PEEK (IN)
128  DIM R(4)
129  PRINT "SENDING PROGRAM TO TRANSPUTER..."
130  FOR X = 1 TO 24
140  READ T: POKE OUT,T
150  WAIT OS,1
160  NEXT X
170  PRINT : PRINT "READING RESULT:"
175 C = 0: REM RETRIES
180  IF C = 10 GOTO 220
181  FOR X = 0 TO 5000: NEXT X: REM DELAY
189 ER = ER + 1: IF ER = 10 GOTO 220
190  IF ( PEEK (IS) AND 1) = 0 GOTO 181
195 R(C) =  PEEK (IN)
200 C = C + 1:ER = 0
210  GOTO 180
211  REM ------------------------
220  IF C = 1 THEN  PRINT "C004 FOUND"
230  IF C = 2 THEN  PRINT "16 BIT TRANSPUTER FOUND"
240  IF C = 4 THEN  PRINT "32 BIT TRANSPUTER FOUND"
250  IF C = 0 OR C > 4 THEN  PRINT "COULD NOT IDENTIFY""
1000  DATA 23,177,209,36,242,33,252,36,242,33,248
1001  DATA 240,96,92,42,42,42,74,255,33,47,255,2,0 

Ok, if this is running fine, i.e. a Transputer was actually found and your Apple didn’t went up in smoke, we’re set for some serious numbercruncing… and a video! Yay! We love Videos, don’t we?

(I’m skipping the other sample code available on the T2C64 page. It’ll work the same on an Apple, so no need for redundancy)

2nd code example

This example actually puts the Transputer to some sort of use… well, it’s still way beneath him but it does its job as an example.
Two tasks: a) Read the Transputer executable from disk and b) exchange data with the Transputer.

Here we go:

10 PRINT"INIT TRANSPUTER"
15 IF (PEEK(57107))=100 THEN POKE57105,9
20 POKE 56840,0
30 POKE 56844,0
40 POKE 56840,1:POKE 56840,0
50 FOR W=0 TO 1000:NEXT W
60 POKE 56834,0
70 POKE 56835,0
80 REM READ STATI
90 PRINT "I STATUS: ";(PEEK(56834)AND1)
100 PRINT"O STATUS: ";(PEEK(56835)AND1)
110 PRINT"ERROR: ";(PEEK(56840)AND1)
140 PRINT"O STATUS: ";(PEEK(56835)AND1)

Up to here everything should be clear. Init Transputer, read stati -just to be sure.
Now we’re reading the executable (“GRAB”) from floppy and poke the bytes to the Transputer as they come flying crawling in:

150 DIM R(4)
160 PRINT"SENDING PROGRAM TO TRANSPUTER..."
170 REM READ TRANSPUTER BIN FILE
180 OPEN 1,8,2,"0:GRAB,S,R"
190 FOR I=0 TO 1 STEP 0
200 IF ST=64 GOTO 240
210 GET#1,A$:A=ASC(A$+CHR$(0))
220 POKE 56833,A
230 NEXT I
240 CLOSE 1

Ok, the Transputer binary expects us to tell it the number of integers we’re about to send to it (AN), the we send these (X) and finally re-read the results… which should all be X+7.

250 INPUT"COUNT:";AN
255 POKE 56833,AN
260 FOR AA=1 TO AN
270 PRINT"ENTER ";AA:INPUT X
280 POKE56833,X
290 NEXT AA
295 PRINT"GETTING";PEEK(56832);" RESULTS"
300 FOR BB=1 TO AN
310 PRINTPEEK(56832);
320 NEXT BB

Some final words about Transputer executables. There are many kinds depending which development system was used. Some need special loaders or bootfiles before the actual binary will be send to the Transputer. A ‘raw’ upload is only possible with binaries mostly having the extension of “.btl” (BooTfromLink). AFAIK only the OCCAM SDK and the Inmos C-compiler ‘icc’ will create those executables.

For those geeks who actually (still) do know their OCCAM, here’s the source of GRAB:

PROC first(CHAN OF BYTE in, out)
  #USE "hostio.lib"

  BYTE data.in, data.out :
  INT count, temp :
  [1000]BYTE array :

-- {{{ start main SEQ

  SEQ
    in ? data.in
    count := (INT data.in)
    SEQ i=0 FOR count
      in ? array[i]                   

        -- {{{ inner loop
        
            SEQ i=0 FOR count
              SEQ
                temp := (INT array[i])
                temp := temp + 7
                array[i] := (BYTE temp)
        
        -- end of inner loop
        -- }}}
                
    out ! (BYTE count)
    SEQ i=0 FOR count
      out ! array[i]          
    in ? data.in       -- debug only
    CAUSEERROR()

-- }}}
        
:

1st code example

For the fun of it, here’s my first Commodore BASIC v2 program which does 3 things.

  1. Line 1-50: Initialize the Transputer and set/get its status.
  2. Line 69-110: Write (poke) some data into T’s memory and read (peek) it back.
  3. Line 128-240: Send a little program to the T and read its result.

10 PRINT"INIT TRANSPUTER"
11 POKE 56840,1:POKE 56844,0:POKE 56840,0
20 REM CLEAR I/O ENABLE
21 POKE 56834,0: POKE 56835,0
30 REM READ STATI
31 PRINT "I STATUS: ";(PEEK(56834)AND1)
35 PRINT"O STATUS: ";(PEEK(56835)AND1)
40 PRINT"ERROR: ";(PEEK(56840)AND1)

This is the Transputer POKE command (0) which tells the T that the next 4 bytes are an address followed by 4 bytes of data:

45 PRINT"SENDING POKE COMMAND"
46 POKE 56833,0
50 PRINT"O STATUS: ";(PEEK(56835)AND1)
58 :

Mind that were little endian and BASIC is using decimal numbers. So we’re POKEing 0,0,0,128 which is 0x00, 0x00, 0x00, 0x80 in hex which again is the 32bit address of 0x80000000.

59 PRINT"SENDING DATA TO T."
60 POKE56833,0:POKE56833,0:POKE56833,0:POKE56833,128
61 POKE56833,12:POKE56833,34:POKE56833,56:POKE56833,78
70 PRINT"I STATUS: ";(PEEK(56834)AND1)
79 :

Now reading back (PEEK) from 0x80000000 what we just wrote:

80 PRINT"READING FROM T."
90 POKE56833,1:REM PEEKING
100 POKE56833,0:POKE56833,0:POKE56833,0:POKE56833,128
110 PRINTPEEK(56832);PEEK(56832);PEEK(56832);PEEK(56832)

These 4 sequential PEEKs print 12 34 56 78. Yay! A very simple Ram-disk if you want.

Now something more serious. A very small programm is sent to the T and executed. Instead of peek and poke (1/0) the initial ‘command’ is the length of the program (23 in this case), so the T starts executing after he received the 23rd byte.
The program itself is trivial, after some initialisation it writes 0xAAAA0000 to link0out. The use of it is very simple. If the Transputer is working correctly the first 2 bytes will allways be “0xAA”, if it is just a 16bit Transputer (T2xx) there won’t be more than 0xAAAA. A 32bit Transputer returns the full 0xAAAA0000. Voilá, that’s a simple T-detection.
To handle timeouts end error conditions I had to do some ugly things in BASIC. Sorry, don’t blame me, BASIC v2 is just… very basic.

120:
128 DIM R(4)
129 PRINT"SENDING PROGRAM TO TRANSPUTER..."
130 FOR X=1 TO 24
140 READ T:POKE56833,T
150 WAIT 56835,1
160 NEXT X
170 PRINT:PRINT"READING RESULT:"
175 C=0
180 N=TI+50
181 IF C=10GOTO 220
189 IF TI>N THEN ER=ER+1:IF ER=10 GOTO 220
190 IF (PEEK(56834)AND1)=0 GOTO 189
195 R(C)=PEEK(56832)
200 C=C+1
210 GOTO 180
211 REM ------------------------
220 IF C=1 THEN PRINT"C004 FOUND"
230 IF C=2 THEN PRINT"16 BIT TRANSPUTER FOUND"
240 IF C=4 THEN PRINT"32 BIT TRANSPUTER FOUND"
1000 DATA 23,177,209,36,242,33,252,36,242,33,248
1001 DATA 240,96,92,42,42,42,74,255,33,47,255,2,0

Next up a bit more useful example, reading the Transputer executable directly from a binary file instead of having it in-line.