Jump to content

Photo

TI 99/4A interfacing


154 replies to this topic

#151 RXB ONLINE  

RXB

    River Patroller

  • 2,513 posts
  • Location:Vancouver, Washington, USA

Posted Wed Apr 26, 2017 3:03 PM

Connecting two Consoles.

I was pondering on my Thread on Joystick Port Interfacing how I might transfer a couple of variables (or more) between two 99 consoles and wondered if the following would work?

By inter-connecting the Cassette Mic. and Ear sockets between two consoles and driving a Joystick key input with the Cassette Motor Drive output then it should be possible to PRINT and INPUT between units on a Keyboard 3 branch.

Has anyone tried this or would like to?
Any other ideas? Console and BASIC only!
To find out why I was thinking this then you would have to look at the other Post here:

 

 

http://atariage.com/...c-console-only/

RXB has a command you could do this with called

 

CALL IO

IO subprogram PAGE I3
-------------------------------------------------------------
Format CALL IO(type,address[,...])
CALL IO(type,bits,cru-base,variable,variable
[,...])
CALL IO(type,length,vdp-address[,...])
Description
The IO subprogram allows access to and control of any chip in
the console or peripheral cards. The type refers to different
access methods like playing sound from GROM or VDP memory
automatically. The type can also specify reading or writing
directly to a Control Register Unit (CRU) address. Thereby
allowing direct chip control, or direct chip bypass if the
user wishes. The IO subprogram is a Graphics Programming
Language (GPL) command. So the function is exactly like GPL
despite being run from the XB environment. As most of XB is
written in GPL the user gains greater GPL like control.
After all the Operating System is written in GPL for a
good reason.*Note these docs are from GPL Manuals.
type address specifications
~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
0 ---------- GROM sound list address.
1 ---------- VDP sound list address.
2 ---------- CRU input.
3 ---------- CRU output.
4 ---------- VDP address of Cassette write list.
5 ---------- VDP address of Cassette read list.
6 ---------- VDP address of Cassette verify list.
The length specifies the number of bytes. The length can be
from -32768 to 32767 depending on the amount of VDP memory
that is available. Of course a value of -32768 is HEX >8000
and 32767 is HEX >7FFF and VDP normally in a TI is only 16384
or HEX >4000 of VDP. So be careful or lock-up will result.
The cru-base is the CRU address divided by 2 in decimal form
as the command automatically doubles the value input. The CRU
-base ranges from 0 to 8191 or HEX >0000 to >1FFF with a EVEN
address for 8 bits or more being scanned. That means that a
value of 8191 will lock-up the system as it is looking for a
bit in 8192 that does not exist.
IO PAGE I4
-------------------------------------------------------------
The variable can input or output values ranging from 0 to 255
as that is equivalent to a single byte value. As there are
two variables 16 bits can be represented in the two 8 bit
variables. If CRU input reads less than 8 bits, the unused
bits in the byte are reset to zero. If CRU input reads less
then 16 but more than 8 bits, the unused bits in the word
will be reset to zero. The bits range from 1 to 16 for input
or output.
AUTO-SOUND INSTRUCTION GROM/GRAM/VDP
Format CALL IO(type,address[,...])
Control of the Sound Generator Chip (SGC) in the system
console is through a pre-defined table in GROM/GRAM or VDP
memory. Sound output is controlled by the table and the VDP
Interrupt Service Routine (ISR). A control byte at the end of
the table can cause control to loop back up in the table to
continue, or end sound output. The format of the table is the
same regardless of where it resides. The table consists of a
series of blocks, each of which contains a series of bytes
which are directly output to the SGC.
Since the VDP generates 60 interrupts per second, the
interrupt count is expressed in units of one-sixtieth of a
second.
When the IO command is called, upon the next occurring
VDP interrupt, the first block of bytes is output to the SGC.
The interpreter (Operating System) waits the requested number
of interrupts (for example, if interrupt counts are 1, every
interrupt causes the next block to be output). Remember that
interpretation of XB continues normally while the SGC control
is enabled.
The sound control can be terminated by using an interrupt
count of 0 in the last block of the table. Alternatively, a
primitive looping control is provided by using a block whose
first byte is 0, and the next 2 bytes indicate an address in
the same memory space of the next sound block to use. (That
means one block points to another block only in the same type
of memory).
IO PAGE I5
-------------------------------------------------------------
If the first byte is hex FF or decimal 255, the next two
bytes indicate an address in the other memory space. (That
means one block points to another block but in another type
of memory.) These allow switching sound lists from GROM/GRAM
to VDP or VDP to GRAM/GROM. By making this the beginning of
the entire table, the sound sequence can be made to repeat
indefinitely.
The type 0 indicates sound lists in GROM or GRAM and type 1
indicates sound lists in VDP.
Executing a sound list while table-driven sound control is
already in progress (from a previous sound list) causes the
old sound control to be totally supplanted by the new sound
instruction. (That means any sound chip command will override
old sound chip commands).
The SGC has 3 tone (square wave) generators - 0, 1, and 2
all of which can be working simultaneously or in combination.
The frequency (pitch) and attenuation (volume) of each
generator can be independently controlled. In addition, there
is a noise generator which can output white or periodic
noise. For more information on controlling the SGC, see the
TSM9919 SGC specification.
ATTENUATION CONTROL (for generators 0, 1, 2 or 3)
One byte must be transmitted to the SGC:
Binary 1-REG#-1-Attenuation
REG# = register number (0,1,2,3)
Attenuation = Attenuation/2
(e.g. A=0000 0 db = highest volume;
A=1000 16 db = medium volume;
A=1111 30 db = off. )
EXAMPLE: 1 10 1 0000 : turn on gen. #2 highest volume.
1 01 1 0100 : turn on gen. #1 medium high volume.
1 11 1 1111 | turn off gen. #3 (noise generator).
IO PAGE I6
-------------------------------------------------------------
FREQUENCY CONTROL (for generators 0, 1, 2)
-----------------
Two bytes must be transmitted to the SGC for a given register
and to compute the number of counts from the frequency F
use: N = 111860 / F
Binary 1-REG#-N(1s 4 bits)-00-N(ms 6 bits)
Note that N must be split up into its least
significant 4 bits and most significant 6
bits (10 bits total).
The lowest frequency possible is 110 Hz and the highest is
55938 Hz.
NOISE CONTROL |
------------- |
One byte must be transmitted to the SGC:
Binary 1-1-1-0-0-T-S
T = 0 for white noise, 1 for periodic noise;
S = Shift rate (0,1,2,3) = frequency center of noise.
S=3=frequency dependent on the frequency of tone
generator #3.
IO PAGE I7
-------------------------------------------------------------
Programs
Line 100 clears screen. | >100 CALL CLEAR ! Chimes
Line 110 to ... | >110 DATA 5,159,191,223,255,2
| 27,1,9,142,1,164,2,197,1,144
| ,182,211,6,3,145,183,212,5,3
| ,146,184,213,4
| >120 DATA 5,167,4,147,176,214
| ,5,3,148,177,215,6,3,149,178
| ,216,7
| >130 DATA 5,202,2,150,179,208
| ,6,3,151,180,209,5,3,152,181
| ,210,4
| >140 DATA 5,133,3,144,182,211
| ,5,3,145,183,212,6,3,146,184
| ,213,7
| >150 DATA 5,164,2,147,176,214
| ,6,3,148,177,215,5,3,149,178
| ,216,4
Line 160 ends sound list. | >160 DATA 5,197,1,150,179,208
| ,5,3,151,180,209,6,3,152,181
| ,210,7,3,159,191,223,0
Line 170 reads list into B and| >170 A=A+1 :: READ B :: CALL
A is counter | POKEV(A,B)
Line 180 checks end of list? | >180 IF B=0 THEN 190 ELSE 170
Line 190 shows how to access. | >190 PRINT "TYPE:": :"CALL IO(
| 1,8192)"
| >200 CALL IO(1,8192)
|
Line 310 continues AD loop. | >310 NEXT AD
Line 320 executes sound list. | >320 CALL IO(1,4096)
Line 330 prints out suggestion| >330 PRINT "CRASH": :"TYPE:":
on how to test IO. | "CALL IO(1,4096)"
IO PAGE I8
-------------------------------------------------------------
Programs
Line 100 clears the screen. | >100 CALL CLEAR ! CRASH
Line 110 to ... | >110 DATA 2,228,242,5
| >120 DATA 2,228,240,18
| >130 DATA 2,228,241,16
| >140 DATA 2,228,242,14
| >150 DATA 2,228,243,12
| >160 DATA 2,228,244,10
| >170 DATA 2,229,245,9
| >180 DATA 2,229,246,8
| >190 DATA 2,229,247,7
| >200 DATA 2,229,248,6
| >210 DATA 2,229,249,5
| >220 DATA 2,230,250,4
| >230 DATA 2,230,251,3
| >240 DATA 2,230,252,2
| >250 DATA 2,230,253,1
| >260 DATA 2,230,254,1
Line 270 ends sound list. | >270 DATA 1,255,0,0
Line 280 AD is VDP address to | >280 FOR AD=4096 TO 4160 STE
start with and ends with. | P 4
Line 290 reads list. | >290 READ V1,V2,V3,V4
Line 300 moves them into VDP. | >300 CALL POKEV(AD,V1,V2,V3,V
| 4)
Line 310 continues AD loop. | >310 NEXT AD
Line 320 executes sound list. | >320 CALL IO(1,4096)
Line 330 prints out suggestion| >330 PRINT "CRASH": :"TYPE:":
on how to test IO. | "CALL IO(1,4096)"
All data values must converted to Binary in order to see
what is going on. You now have all the data that I have as
to this phase of IO types 0 and 1. See Editor Assembler
Manual also for more data on sound lists and sound chip.
IO PAGE I9
-------------------------------------------------------------
Sound table creator for conversion of sound data.
100 CALL CLEAR :: PRINT "*SOUND DATA TABLE CREATOR*"
110 Q$="0123456789ABCDEF"
120 INPUT "GENERATOR # ?":GN
130 INPUT "DURATION ?":DUR
140 INPUT "FREQUENCY ?":FREQ
150 INPUT "VOLUME ?":VOL :: PRINT : : :
160 IF DUR>17 THEN 180
170 DUR=17
180 REM DURATION
190 DUR=INT((DUR*255)/4250) :: CONV=DUR :: GOSUB 400
200 DUR$=SEG$(HX$,3,2) :: IF FREQ>-1 THEN 290
210 REM NOISE FREQUENCY
220 FR=ABS(FREQ)-1 :: FR$="E"&STR$(FR)
230 REM NOISE VOLUME
240 VOL=INT(VOL/2) :: CONV=VOL
250 GOSUB 430 :: VOL$="F"&SEG$(HX$,4,1)
260 PRINT "DATA>02";FR$;",>";VOL$;DUR$: : :
270 GOTO 360
280 REM TONE FREQUENCY
290 FR=INT((111860.8/FREQ)+.5)
300 CONV=FR :: GOSUB 400
310 FR$=SEG$(Q$,GN*2+7,1)&SEG$(HX$,4,1)&SEG$(HX$,2,2)
320 REM TONE VOLUME
330 VOL=INT(VOL/2) :: CONV=VOL :: GOSUB 400
340 VOL$=SEG$(Q$,GN*2+8,1)&SEG$(HX$,4,1)
350 PRINT "DATA>03";SEG$(FR$,1,1)&SEG$(FR$,2,1);",>";
SEG$(FR$,3,2);VOL$;",>";DUR$;"00": : :
360 PRINT: :"ANOTHER SOUND (Y/N)?"
370 CALL ONKEY("YN",3,K,S) GOTO 100,390
380 GOTO 370
390 CALL CLEAR :: END
400 REM DECIMAL TO HEX
410 AY=INT(CONV)/16 :: BY=INT(AY)/16
420 CY=INT(BY)/16 :: DY=INT(CY)/16
430 AP=(AY-INT(AY))*16 :: BP=(BY-INT(BY))*16
440 CP=(CY-INT(CY))*16 :: DP=(DY-INT(DY))*16
450 HX$=SEG$(Q$,DP+1,1)&SEG$(Q$,CP+1,1)&
SEG$(Q$,BP+1,1)&SEG$(Q$,AP+1,1) :: RETURN
Use this program to create Hex strings that can use
CALL MOVES to move strings into VDP to be played from
a CALL IO(1,VDP-address)
IO PAGE I10
-------------------------------------------------------------
CRU ACCESS INSTRUCTION
Format CALL IO(type,bits,cru-base,variable,variable
[,...])
The IO types 2 and 3 can be used to control devices.
IO always must be the CRU address divided by 2 as any
value above 8192 will be out of range. The cru-base must be
divided by 2 as the 9901 chip ignores the least significant
bits of the base register it uses. See Editor Assembler
Manual page 61. The CRU data to be written should be right
justified in the byte or word. The least significant bit
will output to or input from the CRU address specified by
the CRU base address. Subsequent bits will come from or go
to sequentially higher CRU addresses. If the CRU input reads
less than 8 bits, the unused bits in the byte are reset to
zero. If the CRU input reads less than 16 bits but more than
8 bits, the unused bits in the full two 8 bit bytes will be
reset to zero.
Programs
Line 100 display what it does | >100 DISPLAY AT(1,1)ERASE ALL
for you. | :"THIS PROGRAM CHECKS FOR
| UNUSUAL KEYS BEING PRESSED
| , EVEN IF MORE THEN FOUR KEY
| ARE BEING PRESSED AT ONCE"
Line 110 scans CRU at >0006 | >110 CALL IO(2,16,3,A,B):: IF
and reports keys pressed. | A=18 AND B=255 THEN 110 ELS
| E CALL HPUT(24,3,RPT$(" ",30
| ),24,24,STR$(A)&" "&STR$(B))
Line 120 more reports. | >120 IF A=146 THEN CALL HPUT(
| 24,3,"FUNCTION KEY")ELSE IF
| B=191 THEN CALL HPUT(24,3,"C
| ONTROL KEY")ELSE IF B=223 TH
| EN CALL HPUT(24,3,"SHIFT KEY
| ")
Line 130 still more reports. | >130 IF B=251 THEN CALL HPUT(
| 24,3,"ENTER KEY")ELSE IF B=2
| 53 THEN CALL HPUT(24,3,"SPAC
| E BAR")ELSE IF B=254 THEN CA
| LL HPUT(24,3,"PLUS/EQUAL KEY
| ")
Line start over scan of keys. | >140 GOTO 110
IO PAGE I11
-------------------------------------------------------------
Programs
Line 100 clears screen. | >100 CALL CLEAR
Line 110 explains program. | >110 CALL HPUT(4,7,"This is a
| demo of the",6,7,"CALL IO(3
| ,8,2176,B)",8,7,"3 = TYPE(CR
| U output)",10,7,"8 = NUMBER
| OF BITS",12,7,"2176=address/
| 2")
Line 120 turn off card, show | >120 CALL IO(3,8,2176,0):: FO
the present byte value being | R B=0 TO 255 :: CALL HPUT(14
sent. | ,7,"B=byte (value "&STR$(B)&
| ")")
Line 130 display block to get | >130 CALL HPUT(18,5,"********
attention. | ******************",19,5,"WA
| TCH THE DRIVE LIGHTS",20,5,"
| **************************")
Line 140 send byte to card and| >140 CALL IO(3,8,2176,B):: NE
when done with loop, clear for| XT B :: CALL HCHAR(14,24,32,
starting over program. | 7):: GOTO 110
|
Line 100 explains program. | >100 ! TURNS OFF/ON/OFF EACH
| CARD FROM >1000 TO >1F00 BUT
| WILL LOCKUP WITH CERTAIN
| CARDS.
Line 110 cru address from | >110 FOR CRU=2048 TO 3968 STE
>1000 to >1F00, turn off card,| P 128::CALL IO(3,8,CRU,0,3,8
turn on card, delay for 2 | >,CRU,255)::FOR A=1 TO 200::N
seconds, turn off card, turn | EXT A::CALL IO(3,8,CRU,0)::N
off card. Loop end. | EXT CRU
Options
Some CRU address are used by the Operating System or XB and
any attempt to redefine them will create problems. Also some
of the address areas will return incorrect values as they
have changed since IO has accessed them. These problems will
never become completely apparent at first, so take care.
Additionally some cards have the same problem, if the card
has a program that has a interrupt or CRU links turned on as
you access it, a complete lock up will result as a fight for
control ensues. So with that happy thought, a alternate way
is to use EXECUTE or LINK instead.
IO PAGE I12
-------------------------------------------------------------
CASSETTE INPUT/OUTPUT/VERIFY INSTUCTION
Format CALL IO(type,length,vdp-address[,...])
The three different cassette I/O instructions use the same
format. The write and read instructions physically perform
Input/Output to the cassette. The verify instruction will
read a tape and compare it, byte by byte, against what is in
the specified VDP area. All will report an I/O error if one
is detected. No prompts are present with these three formats.
These three types control the cassette directly so no prompt
will tell the user to turn on or off the cassette record/play
buttons. The programmer must inform the user with own prompt.
Programs
(Presently I have no cassette to write programs with.)
AUDIO GATE
----------
CRU bit 24 is the audio gate which allows data being read to
be heard. If the bit is set to 1, the data being read is
heard, and if the bit is set to 0, the data is not heard.
Setting the bit to a 0 or 1 is done with an IO instruction, or
a Assembly instruction.
MOTOR CONTROL
-------------
There are two CRU bits (22 and 23) used to control cassettes
1 and 2, respectively. When there is no Cassette IO being
done, both motors remain on. When Cassette IO is specified,
the DSR (Device Service Routine) will control the data being
read. If there are two motor units connected, the data will be
read simultaneously, or you may have the option of reading
data from one motor unit and playing the recorded voice from
another motor unit through the TV (Monitor) speaker.
*NOTE:
Compatibility with or without 32K or other devices is not a
concern as IO needs no RAM to work with. Therefore from just
a console all IO commands will work fine. If you only have a
Cassette and RXB you can quickly load/save/verify without
menus, or just make up your own.

Using CALL IO you could make XB program doing something very new for the TI by then talking on Cassette ports.



#152 Meddler OFFLINE  

Meddler

    Space Invader

  • 43 posts

Posted Mon May 1, 2017 6:51 AM

...more Joystick Port interfacing...

 

the Joystick Port is a viable output and input port as explained in my post:

http://atariage.com/...c-console-only/

 

but frustrated by having only one axis of control I have come up with the following idea, a little more complicated but straight-forward:

 

there are binary counters and de-coders available and in the spirit and era of the TI99 that would be power hungry TTL, the 7493 binary counter and the 7415X series 16 to 1 line decoder. Connecting the counter output to the de-coder input gives 15 selectable outputs.

 

One Joystick output can clock the counter and the other would gate the De-coder. By sending a series of clock pulses the counter would increment and the de-coder would output a 'low' on the relevant line when 'gated'. If only a sequential output is required then the 'gate' is not required.

 

Several other options can be derived from this idea but if specific outputs are to be addressed at random then the 'gate' is required so position 0 would have to be the resting position and the count must always run to 16 after each selection as there is no other output to reset the counter. At power-up, position 0 can be tested by a Joystick Port input.

 

 

... I noticed that those cheap RC Model Cars from China have 4 buttons for Left-Right, Forward-Reverse..... :grin:


Edited by Meddler, Mon May 1, 2017 7:05 AM.


#153 apersson850 OFFLINE  

apersson850

    Chopper Commander

  • 222 posts

Posted Wed May 3, 2017 4:25 AM

Slightly OT, Vorticon, but have you made many attempts to interface the TI with another retro computer via serial connections?

I'm sorry, I just realized I've already mentioned this once in this thread. Please disregard.

 

I've done this, more or less, since by now I think you need to consider a computer which runs Windows XP as "vintage".

The reason for it was that I printed files to the Toshiba netbook computer (running HyperTerminal to collect the files), then printed them from there to the printer, which required a Windows driver (or similar) to work. My old impact printer works, but the ink band are dried up.

 

I've also done this at work. Not with vintage computers, but with more or less vintage machine control systems, which didn't support Ethernet or something like that. I had to use RS232, so I made up a protocol similar to what's normally used for CAN-bus networks, and exchanged information that way between two different machines. Exactly that same protocol could be applied to a 99/4A without any issues.


Edited by apersson850, Wed May 3, 2017 4:29 AM.


#154 Vorticon OFFLINE  

Vorticon

    River Patroller

  • Topic Starter
  • 2,593 posts
  • Location:Eagan, MN, USA

Posted Wed May 3, 2017 5:13 PM

I actually did, with a replica of the venerable Cosmac ELF computer, a kit computer you could easily source and build at home which was published as a series in Popular Electronics in 1976 :) 

 


  • RXB likes this

#155 Vorticon OFFLINE  

Vorticon

    River Patroller

  • Topic Starter
  • 2,593 posts
  • Location:Eagan, MN, USA

Posted Sun May 7, 2017 12:07 PM

Latest update to the wireless weather station project: Solar power and final layout :)

 

 

Development blog here: http://atariage.com/...st-update-5717/






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users