Jump to content
IGNORED

SIO from BASIC


Recommended Posts

Hi folks, short background: I am fairly unexperienced with Atari, I could only visit a friend who owned Atari 30 years ago and mostly we were doing gaming and little of Basic programming. We used joystick ports back than to sense commands in !!Morse code!! that we were punching in over 27MHZ CB radio with spark radio key out in the street, and controlled room light over a relay attached to another joystick pin to impress the crowd. Inevitably one day short circuit killed the joystick port, so there were no more games and PC was coming... Old Atari and all cassettes are long gone, friend lives in another city.

 

OK now I am 30 years older and have my own Ataris 800XL/130XE with SDrive and 1050. Games are still fun. But I want to do something more serious again but I would like to use SIO port this time. I searched, searched but could not find anything specific. Is it possible to output short string (max 20bytes) with for example XIO commands and receive another short string as answer all done in Basic? I would like to connect for example Arduino and/or another Atari and use very simple protocol with two or three devices. I have an intelligent home with IoT so I could display on Atari actual values, that would be cool.

Link to comment
Share on other sites

Without any programming experience on Atari this may be a challenge. Not impossible, of course.

 

It all depends on your device, be it real or emulated, on how to communicate with it. If you want something useful you need a device driver on the Atari which understands the XIO commands. With a disk drive you talk to "D:" to work with data on disk because the disk drive has a ROM that listens to "D:" commands. Atari loads the "D:" from disk when DOS is booted.

 

You need to do the same on an Arduino as has been done in the disk drive, but for a custom "?:" device you invented. So, where you'd use XIO 1,#1,aux1,aux2,"D:file.ext" to work with a disk file you'll now use XIO 1,#1,aux1,aux2,"?:" to talk to your emulated device. Which commands are possible, and what they do, is up to you.

 

Not sure if an Arduino will cut it. May need something more powerful, like RPI.

 

b.t.w, using a joystick port to control things is way easier.

Link to comment
Share on other sites

Hi archeocomp!

 

Hi folks, short background: I am fairly unexperienced with Atari, I could only visit a friend who owned Atari 30 years ago and mostly we were doing gaming and little of Basic programming. We used joystick ports back than to sense commands in !!Morse code!! that we were punching in over 27MHZ CB radio with spark radio key out in the street, and controlled room light over a relay attached to another joystick pin to impress the crowd. Inevitably one day short circuit killed the joystick port, so there were no more games and PC was coming... Old Atari and all cassettes are long gone, friend lives in another city.

 

OK now I am 30 years older and have my own Ataris 800XL/130XE with SDrive and 1050. Games are still fun. But I want to do something more serious again but I would like to use SIO port this time. I searched, searched but could not find anything specific. Is it possible to output short string (max 20bytes) with for example XIO commands and receive another short string as answer all done in Basic? I would like to connect for example Arduino and/or another Atari and use very simple protocol with two or three devices. I have an intelligent home with IoT so I could display on Atari actual values, that would be cool.

SIO is a high-level protocol, in which Atari is the master and devices are slaves. It defines command and responses, with checksum, ACKs and NACKs.

 

If you only want to communicate bytes to an Arduino serial port, it is simpler to use the Pokey UART at low level, just like you would do on a micro-controller. The definitive guide is the Altirra Hardware Reference Manual, see chapter 5.4 "Serial port". Basically, you need to enable serial transmission (mode 010), set the baudrate and send the values, this example sends data at 9600 bauds via serial port:

10 POKE 53767,160
20 POKE 53764,86 : POKE 53766, 0
30 POKE 53768,40
40 POKE 53775,35 : POKE 53770,1
50 FOR A=32 TO 125
60 POKE 53773, A
70 NEXT A
80 GOTO 50
As the SIO port is standard 0/5V, you can connect directly to an arduino or USB-serial device to receive the bytes.
  • Like 2
Link to comment
Share on other sites

Low level will do but depending on what other data devices are connected to the SIO bus you may get some unwanted side effect you'd want to take care of.

 

Now the Arduino listens to all data that crosses the SIO lines it will respond to every match you implemented. The Arduino doesn't know If this is a command/data byte intended for a disk drive or one that it needs to respond to. Kind of the same behavior one gets with some SIO midi interfaces where a connected midi keyboard starts playing notes when loading a disk because some of the bytes traveling the SIO lines match the midi ones.

Link to comment
Share on other sites

Proper SIO protocol makes use of the /Command line - if you're just throwing data around without using it then standard peripherals should just ignore what's going on.

But the problem is, the command line helps everything to make sense of what the computer's trying to do.

 

It wouldn't be too much trouble to program a standard acting SIO device that only responds to commands being sent to it. The OS and Hardware manuals have adequate description to help you make your own emulation or real device be able to follow the standard.

Just use a device ID that's not in common use. Stock SIO commands often just use the relevant letter e.g. R, W, P, S for Read, Write, Put, Status (put is write without verifty to a disk)

Link to comment
Share on other sites

I ran and analysed the code from dmsc.
The baud bit rate of the data and clock is determined by audio channel 4 audio channel2, or by th einput clock, depending on the serial mode selected by bits 4,5, and 6 os SKCTL.

AUDF1 53760 (D200)
AUDF2 53762 (D202)
AUDF3 53764 (D204)
AUDF4 53766 (D206)
AUDC4 53767 (D207)
AUDCTL/ALLPOT 53768 (D208)
SKRES 53770 (D20A)
SEROUT/SERIN 53773 (D20D)
IRQEN/IRQST 53774 (D20E)
SKCTL/SKSTAT 53775 (D20F)

Altiras Atari Hard. manual says: See the Audio and Serial Port Block Diagram page of the Hardware Manual [ATA82] for a logic diagram that shows precisely how the bits in AUDCx affect the output flow.

 

I can not locate that manual unfortunately. Does anybody have it? IMPORTANT

10 POKE AUDC4,160
20 POKE AUDF3,86 : POKE AUDF4,0
30 POKE AUDCTL,40
40 POKE SKCTL,35 : POKE SKRES,1
50 FOR A=32 TO 125
60 POKE SEROUT,A
70 NEXT A
80 GOTO 50

I would of course happily drive also Command pin, so that I do not introduce unneeded noise into SIO bus. I do not see it being controlled by POKEY, but I hope it would be just another pair of BASIC POKEs to another chip to activate/deactivate the signal.
I have also found new FAST BASIC with structured programming abilities, it is beautiful. But that is simply too much new things at one time for me.

Edited by archeocomp
Link to comment
Share on other sites

Hi!

 

I ran and analysed the code from dmsc.

The baud bit rate of the data and clock is determined by audio channel 4 audio channel2, or by th einput clock, depending on the serial mode selected by bits 4,5, and 6 os SKCTL.

 

AUDF1 53760 (D200)

AUDF2 53762 (D202)

AUDF3 53764 (D204)

AUDF4 53766 (D206)

AUDC4 53767 (D207)

AUDCTL/ALLPOT 53768 (D208)

SKRES 53770 (D20A)

SEROUT/SERIN 53773 (D20D)

IRQEN/IRQST 53774 (D20E)

SKCTL/SKSTAT 53775 (D20F)

 

Altiras Atari Hard. manual says: See the Audio and Serial Port Block Diagram page of the Hardware Manual [ATA82] for a logic diagram that shows precisely how the bits in AUDCx affect the output flow.

 

I can not locate that manual unfortunately. Does anybody have it? IMPORTANT

The "Atari Home Computer System Hardware Manual" is the third part of CO16555, the "Atari Home Computer Technical Reference Notes", and can be found over the internet archive at https://archive.org/details/bitsavers_atari40080mputerTechnicalReferenceNotes1982_20170986starting at page 417.

 

*BUT*. as Rybags said, the AUDC* values are not used for serial communication, they only affect the audio output.

 

10 POKE AUDC4,160

20 POKE AUDF3,86 : POKE AUDF4,0

30 POKE AUDCTL,40

40 POKE SKCTL,35 : POKE SKRES,1

50 FOR A=32 TO 125

60 POKE SEROUT,A

70 NEXT A

80 GOTO 50

 

I would of course happily drive also Command pin, so that I do not introduce unneeded noise into SIO bus. I do not see it being controlled by POKEY, but I hope it would be just another pair of BASIC POKEs to another chip to activate/deactivate the signal.

I have also found new FAST BASIC with structured programming abilities, it is beautiful. But that is simply too much new things at one time for me.

The idea is doing the opposite: If you don't drive the command line, all peripherals *should* ignore any serial data, so you are free to use the bus for other activities.

 

About the register values, the 160 in AUDC4 simply ensures that it is at zero volume and normal waveform, so you don't listen to the serial frequency through the speaker.

 

The AUDCTL value of 40 is 00101000b. Bit 5 sets 1.79MHz for the channel 3 clock, bit 3 links channel 3 and 4 to form a 16 bit counter.

The SKCTL value of 35 is 00100011. Bits 6-4 are 010 = channel 4 clock for serial output, bits 0 and 1 enables keyboard scan.

 

And the value for AUDF3 & AUDF4 sets the clock to 1.79MHz / (2*(7 + 86)) = 9623 bauds.

Link to comment
Share on other sites

Hi!

 

Sorry I do not understand what channel you mean?

 

BTW I want to do something similar like this guy but on ATARI and SIO bus

https://www.youtube.com/watch?v=twlBscAwhcw

This is much simpler in an Atari, as you have the SIO port with the UART already available, I did this in the past. And you can always use the joystick port if you want an alternative digital I/O.

Link to comment
Share on other sites

I am going to add another option to transfer data to and from an Arduino. If you have/or can get a RS-232 interface (850 or P:R:Connection) you can equip the Arduino with a TTL to RS232 converter and null modem the two ports. I have documented this in my Out of the Pack blog.

 

http://atariage.com/forums/blog/572/entry-11653-atari-8-bit-850-interface-rs232-shield-arduino/

 

Working with the R: device may not be easy but at least the driver software has already been written.

 

There are several other Atari/Arduino interfacing projects within the blog that you may find of interest.

Link to comment
Share on other sites

Nice work. Defintelly will read everything. But I do not want to buy/use Atari 850, I really only want to plug Arduino into SIO bus. One SIO Connector and one diode on Tx is all, that is needed.

 

Meanwhile I rewrote and tested the program in fast basic, still need working receive routine.

' SERIAL test program
AUDC4  = $D207 : AUDF3  = $D204
AUDF4  = $D206 : AUDCTL = $D208
SKRES  = $D20A : SEROUT = $D20D
IRQEN  = $D20E : SKCTL  = $D20F

' Initial Conditions
  MSG$ = "#$%NA01SE"  : ' arduino node 1, request send values, end

  REPEAT
    EXEC SerialSend : ' send string
	PAUSE 25
  UNTIL Key()
END

PROC SerialSend
  POKE AUDC4,160
  POKE AUDF3,86 : POKE AUDF4,0
  POKE AUDCTL,40
  POKE SKCTL,35 : POKE SKRES,1
  B = LEN(MSG$)
  FOR A=1 TO B
    POKE SEROUT,MSG$[A,1]  'output first char
  NEXT A
ENDPROC

Link to comment
Share on other sites

Hi!

 

Nice work. Defintelly will read everything. But I do not want to buy/use Atari 850, I really only want to plug Arduino into SIO bus. One SIO Connector and one diode on Tx is all, that is needed.

 

Meanwhile I rewrote and tested the program in fast basic, still need working receive routine.

' SERIAL test program
AUDC4  = $D207 : AUDF3  = $D204
AUDF4  = $D206 : AUDCTL = $D208
SKRES  = $D20A : SEROUT = $D20D
IRQEN  = $D20E : SKCTL  = $D20F

' Initial Conditions
  MSG$ = "#$%NA01SE"  : ' arduino node 1, request send values, end

  REPEAT
    EXEC SerialSend : ' send string
	PAUSE 25
  UNTIL Key()
END

PROC SerialSend
  POKE AUDC4,160
  POKE AUDF3,86 : POKE AUDF4,0
  POKE AUDCTL,40
  POKE SKCTL,35 : POKE SKRES,1
  B = LEN(MSG$)
  FOR A=1 TO B
    POKE SEROUT,MSG$[A,1]  'output first char
  NEXT A
ENDPROC

 

You certainly mean " POKE SEROUT, ASC(MSG$[A,1]) ". Note that the loop can be written with " FOR A=1 TO LEN(MSG$) ", this makes the program smaller and it is as fast (or a little faster) than using the variable "B". And, in the IDE (that does not perform optimizations), it is faster to write:

  FOR A=1 TO LEN(MSG$)
    POKE SEROUT, PEEK(ADR(MSG$)+A)  'output first char
  NEXT A
This is because the expression " MSG$[A,1] " creates a new string of length 1 and then " ASC(X$) " is compiled to " PEEK(ADR(X$)+1) ", so it is slower than " PEEK( ADR(MSG$) + A ) " that simply adds the (fixed) address of MSG$ to A.

 

About receivin serial characters, that is not as easy inside BASIC. The reason is that you need to read bytes fast enough to keep with the transmission speed, and POKEY has no buffer for received characters, as was designed to read in the IRQ routine. So, to get the state of the serial bytes, you need to *disable* the interrupts, *enable* the serial interrupt in pokey and wait for the interrupt flag to toggle, like this (untested!) code:

  DATA CLI() BYTE = $58, $60
  DATA SEI() BYTE = $78, $60

  POKE AUDC4,160
  POKE AUDF3,86 : POKE AUDF4,0
  POKE AUDCTL,40

  X=USR(ADR(SEI))                                       ' Disable IRQs
  POKE IRQEN, $A0                                       ' Enable SERIAL + BREAK interrupt bits, so we can deetct break key!
  POKE SKCTL,19 : POKE SKRES,1                          ' Set async serial input mode

  MSG$="0123456789"
  FOR N=1 TO 10  ' Receive 10 characters
    REPEAT : I = PEEK(IRQST) EXOR $FF : UNTIL (I & $A0) ' Wait for any interrupt
    X = PEEK(SERIN)                                     ' Read serial data
    IF I & $80 THEN EXIT                                ' Exit on BREAK key
    POKE IRQEN, $80 : POKE IRQEN, $A0                   ' Clear IRQ bit
    POKE ADR(MSG$)+N, X
  NEXT N
  POKE ADR(MSG$), N                                     ' Set received length
  X=USR(ADR(CLI))                                       ' Enable IRQs again
  POKE IRQEN, PEEK( POKMSK )

You should also add detection of overrun and framing errors by reading SKSTAT, and some means of detecting timeouts also, but I don't know if FastBasic is fast enough for this, it probably would be easir to simply write the "receive one byte with timeout" routine is assembler.
Link to comment
Share on other sites

Thank you very much. I will test it.

 

Of coarse I meant ASC(MSG$[..) but I am rewriting the program between PC and Atari by hand so errors occurs. The need to rewrite programs by hand or need to remove uSD card from SDrive and hassling with different programs (ATADIM and DRATEX subsequently) to extract data, is another thing that makes me not so comfortable on Atari.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...