The ZX Next - The UART and Beyond.
----------------------------------

The background to this feature of the ZX Next can be found on the system website:

https://www.specnext.com/the-next-on-the-network/ - with a video!

What is the .UART command in BIN?
---------------------------------

The .UART command in the distribution is a development of the one from Victor's video
that provides more facilities to use the serial connection port either directly through
some form of serial converter e.g. a USB to TTL serial or standard RS232 module (probably
based on the MAX232) and of course to an ESP-01 WiFi module plugged in to the header.
This will work from NextOS and from ESXDOS at the moment.

The current controls are mapped to Spectrum keys:

EDIT		SHIFT+1 - Change BAUD RATE in a cycle.
CAPS LOCK	SHIFT+2 - On/off toggle (on by default)
TRUE VIDEO	SHIFT+3 - Debug mode for CIPSEND on/off (silent)
INV VIDEO	SHIFT+4 - CIPSEND mode on/off also does an ATE0
GRAPHICS	SHIFT+9 - ANSI on/off (not yet implemented)
DELETE		SHIFT+0 - (PS2 KB one does not work only first time for one backspace)
Exit Program	Symbol Shift and Space together.
  
It handles the UART protocol as per the website above:  

The ports are 0x143b = 5179 for RX and 0x133b = 4923 for TX.
A read on the TX port shows the status of the FIFO buffer and the TX line
bit 0: returns ‘0’ if the FIFO buffer is empty or ‘1’ if there is data to be collected.
bit 1: returns the TX status: ‘1’ when the TX is still transmitting the last byte or
       ‘0’ when the TX is idle.
bit 2: returns the FIFO buffer status: ‘1’ if the buffer is full, or 
       ‘0’ when the buffer has space to hold another incoming byte.

This is fine to use the serial interface as an ASCII terminal or the AT commands of
the ESP in single connection mode.  To do proper networking with the ESP you will need
a full suite of interrupt driven drivers - which I'm sure are being brewed in a lab at the
moment.

Using the UART without a WiFi module
------------------------------------

A USB serial connection allows you to do all sorts of clever things - it is possible
to connect up to a PC like this for transferring data.  In fact if you were an early
purchaser you probably bought one with your ESP-01 as it is the one needed to program it. 

If you use one of the easy to get TTL modules then you can communicate with PC's and
other older machines - E.g. a real Spectrum with Interface 1... KevB is using one
for his PC on the forum at https://www.specnext.com/forum/viewtopic.php?f=6&t=895  

It should be possible just to hook up to an external Raspberry PI for example and use
a serial console connection allowing you to use the ZX Next as the keyboard...
as the voltages match it should be fine just to connect the UART RX/TX and GND
to the PI's PIN's 4/5/6 GND/TXD0-GPIO14/RXD0-GPIO15
See https://elinux.org/RPi_Serial_Connection there is a diagram of the GPIO header
on https://elinux.org/RPi_Low-level_peripherals just be aware of the differences with a PI3.

I just want to use my WiFi module
---------------------------------

So if you are not an adventurous hardware hacker and have plugged in an ESP01 WiFi module
or hava machine with one prefitted then lets look at using that...

Having watched the Video to save you pausing all the time here is how to make it do
something with a few early steps.

First of all when you press ENTER you should get 'ERROR' because you didn't send a valid
command to the ESP module...

If you don't then it may be a number of things:

You are using the TBU and firmware BEFORE 0.8 and NextOS 1.92 - if so this will only work
at 3.5Mhz so slow the machine down and restart .UART!

Your module may have come with a default baud rate other than the 115200 of the Next.
Using EDIT (SHIFT+1) you can cycle through each option pressing enter until you see ERROR!
(If you can see the module then many have a little blue light that flashes when receiving)

Once you have that you should be able to type 'AT' and press ENTER.

That should give OK...

Probably the first thing you want to do is tell the module to use the default speed of the
next so type:

AT+UART=115200,9,1,0,0 and press ENTER

You now need to used EDIT (SHIFT and 1) to go back around to 115200 so that
[ENTER] gives ERROR and AT[ENTER] gives OK again....

We just used one of the AT commands 

AT+UART=<baudrate>,<databits>,<stopbits>,<parity>,<flow control>

Getting on the Network
----------------------

Now to do as Victor did and connect to a WIFI access point.

First let's check that the system is in STA mode

AT+CWMODE=?  will give 1,2 or 3 (where STA=1, AP=2, Both=3)

Mode 1 or 3 is fine but, more config is needed in 2!

AT+CWLAP - to List Access Points...

AT+CWJAP="wifinetwork","password" - To Join Access Point

Note that the module will retain the wifi connection and you can just do an 
AT+RST which will reset the module and give a CONNECTED and GOT IP.

AT+CIFSR will give the current IP address on the network.

Next you need to connect to something
-------------------------------------

AT+CIPSTART="TCP","www.google.com",80 is the example in the video

That is just the first stage and means there is now a pipe from the ESP to the Google server

Before it does anything you need to send it something 

If you do feel brave before you close the connection then you can send

AT+CIPSEND=7

at the ">" prompt type:

"GET /" followed by 13 CR and 10 linefeed

I.E. Just press return twice...

AT+CIPSEND=length allows you to get the > prompt and type 'length' characters.

Incoming replies will be "+IPD,length:" followed by the data.

Finally you will need to close down the connection:

AT+CIPCLOSE

That all looked to hard
-----------------------

This is very fiddly so UART includes a mode called CIPSEND that does all the decoding for you

If you press INV VIDEO (SHIFT+4) then system will send an ATE0 to stop the ESP echoing everything
and then anything you type will be sent followed by a Return and Newline.

Anything the other end replies with will just appear. Note that at 14MHz you will get
more text before the system begins to lose data due to the delays in printing what is
received.

This mode is good enough to be a simple text terminal for a shell on a linux box or any test system.

If you connect to Google again and send four lines EXACTLY like this:

GET / HTTP/1.1\r\n
Host: www.google.com\r\n
Connection: close\r\n
\r\n

(where the \r\n represent what CIPSEND will do when you press ENTER)

Your screen will fill with the RAW data that makes up the very simple
Google home page...

So that's a bust then, the World Wide Web is just too advanced for the poor old speccy.
(maybe the PI accelerator will be able to help in the future...)

Let's try something different:

AT+CIPSTART="TCP","dict.org",2628

Should get you:

220 ..............some WELCOME.....

Go into CIPSEND mode with INV. VIDEO (SHIFT+4) and type:

DEFINE wn server\r\n

And you should get:

150 1 definitions retrieved
151 "server" wn "WordNet (r) 2.0"
server
     n 1: a person whose occupation is to serve at table (as in a
          restaurant) [syn: {waiter}]
     2: (court games) the player who serves to start a point
     3: (computer science) a computer that provides client stations
        with access to files and printers as shared resources to a
        computer network [syn: {host}]
     4: utensil used in serving food or drink
.
250 ok [d/m/c = 1/0/18; 0.000r 0.000u 0.000s]

Now send:

QUIT

and you will get

221 bye [d/m/c = 0/0/0; 16.000r 0.000u 0.000s]


I want the module to forget my WiFi network and password
--------------------------------------------------------

AT+CWQAP

Will close it all down if you do not want it to remember for next time.


So what else can you do at the moment with such a limited system?
-----------------------------------------------------------------

Truthfully not a lot yet - experimenting with connecting to text only services
is about it, as most modern systems use very complex sequences now that are hard
to type.

Until a few years ago you could have sent an e-mail but, due to spam most
servers need complex logins now!  Your ISP may allow simple SMTP but, it is 
unlikely...


This is nearly enough to get on an old BBS system
-------------------------------------------------

Info about the sinclair retro BBS which has a limited number of connections
(10 I believe) run by Simone from Sinclair Software Preservation can be found at:

http://telnetbbsguide.com/bbs/sinclair-retro-bbs/

The CIPSTART connect you actually need to use it on a Next is: 

AT+CIPSTART="TCP","retrobbs.sinclair.homepc.it",23

Port 23 is Telnet for those in the know.

You can make a connection to this and it will stop with a prompt asking
you for a graphics mode buried among the control codes - and then kick you off when
you answer ASCII.

A priority is to make the ANSI support good enough for us to login to this server
 - watch the forum and fb for updates.

There are others around as well like http://www.mono.org/ many are
listed on the telnetbbsguide.


More reading on the ESP modules
-------------------------------

Some good guides to the module in general:

http://www.esp8266.com/wiki/doku.php?id=getting-started-with-the-esp8266

https://medium.com/@nowir3s/getting-started-with-esp8266-875fb54441d6

http://www.instructables.com/id/Getting-Started-With-the-ESP8266-ESP-01/

The full set of AT instructions is here (and also linked on the SpecNext article):

http://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf

or more easily navigable onine:

https://room-15.github.io/blog/2015/03/26/esp8266-at-command-reference/#AT+CIPSEND

Advanced dicsussion on the UART - the ESP has more advanced ones than the ZX Next:

http://forgetfullbrain.blogspot.co.uk/2015/08/uart-sending-and-receiving-data-using.html


I need an ANSI terminal to connect to a BBS
-------------------------------------------

This is partially implemented but, diasabled in the current UART as it has errors - it
is possible that it will not be fully developed and it is more likely that the ANSI system
from Z88DK is used with the soon to be developed full networking support to create a terminal.

http://ascii-table.com/ansi-escape-sequences.php

Min support for:

ESC[2J		- Erase display cursor to 0,0 (top left)
ESC[line;colH   - Move print position to line,col

Spectrum should be easy to do some of:

Esc[Value;...;Valuem 	Set Graphics Mode:
Calls the graphics functions specified by the following values. These specified functions
remain active until the next occurrence of this escape sequence. Graphics mode changes the
colors and attributes of text (such as bold and underline) displayed on the screen.
 

Text attributes
0	All attributes off
1	Bold on
4	Underscore (on monochrome display adapter only)
5	Blink on
7	Reverse video on
8	Concealed on
 
Foreground colors
30	Black
31	Red
32	Green
33	Yellow
34	Blue
35	Magenta
36	Cyan
37	White
 
Background colors
40	Black
41	Red
42	Green
43	Yellow
44	Blue
45	Magenta
46	Cyan
47	White 


Making sure you have the latest firmware on the ESP:
----------------------------------------------------

Programming these using the Serial programmer is slightly complex and covered in the above
links - but, there is a built in function to do it once you have a WiFi connection. Use
at your risk the Author has done it once on a module and it did work but, you need patience
as the +CIPUPDATE:1-4 messages can take several minutes - DO NOT TURN OFF DURING THIS.

Updating the ESP8266 over the air

# Update steps
1.Make sure TE(terminal equipment) is in sta or sta+ap mode

    AT+CWMODE=3
    OK

2.Make sure TE got ip address

    AT+CWJAP="ssid","12345678"
    OK
    
    AT+CIFSR
    192.168.1.134

3.Let's update

    AT+CIUPDATE
    +CIPUPDATE:1    found server
    +CIPUPDATE:2    connect server
    +CIPUPDATE:3    got edition
    +CIPUPDATE:4    start start
    
    OK

> NOTICE: If there are mistakes in the updating, then break update and print ERROR.

http://bbs.espressif.com/viewtopic.php?t=2613


Modern security means I cannot get a shell on a unix box using netcat -b
------------------------------------------------------------------------

Fifo's are your friend the whole world is your enemy so make sure you do
not expose your system...

rm -f /tmp/f;mkfifo /tmp/f
cat /tmp/f | /bin/sh -i 2>&1 | nc -l -p 10000 > /tmp/f

Also on netcat see:

https://www.g-loaded.eu/2006/11/06/netcat-a-couple-of-useful-examples/

This is the source of the dict.org example above!

Other security issues:
----------------------

Don't forget 
			
https://www.youtube.com/watch?v=Hkr60GE5yfY			
	
Now the other two wifi
	
https://www.raspberrypi.org/blog/why-raspberry-pi-isnt-vulnerable-to-spectre-or-meltdown/	


Notes from AA on timings to empty the buffer
--------------------------------------------

Once per frame should be enough

Are you waiting too long to check if data is available?  At 115200, it's a max of 11.5k/s sent from the esp.
At 3.5MHz, that's about 300 cycles per byte sent.  I think you can get away with checking for data once per
frame and draining the Rx buffer.

The ESP-01 does have two gpio pins exposed so if the esp firmware is rewritten you could use those for hw flow control.
I don't know if the default firmware is able to do sw flow control but probably not (it can't)


Example Assembly Language to use the UART
-----------------------------------------

;The ports are 0x143b = 5179 for RX and BAUD rate and 0x133b = 4923 for TX and Status Test
;A read on the TX port shows the status of the FIFO buffer and the TX line:
;the bit 0 returning ‘1’ if the FIFO buffer is empty or ‘0’ if there is data to be collected.
;The bit 1 returns the TX status: ‘1’ when the TX still transmitting the last byte or ‘0’ and when the TX is idle.
;Bit 2 WILL BE Fifo full indicator

;-------Send bytes from (HL) terminated with LF (10)

tx_out:			
			LD DE,2048		;Delay timeout - was 20 at 112500 baud - need to be higher at lower baud rates...
						
			LD BC,TX_CHKREADY
tx_out_wait:		IN A,(C)
			AND @00000010		;Check if TX available for send, wait until it is (with timeout)
			JR Z,tx_out_ready
					
			DEC DE
			LD A,D
			OR E
			JR NZ,tx_out_wait

			LD HL, str_TIMEOUT	;Prints an error if we do not become ready...
			JP print
			
tx_out_ready:		LD A,(HL)
			OUT (c),a		
	
			CP 10
			RET Z

			INC HL
			JR tx_out

;------- Wait upto DE loops for data to be available in the UART buffer...		
			
GET_BYTE_WAIT:		LD DE,1000
			JR GET_BYTE_2

GET_BYTE:		LD DE,20

GET_BYTE_2:		LD BC,TX_CHKREADY
			IN A,(C)
			AND @00000001			;***TODO Change this to preserve BIT 2 to see if buffer was full
			JR Z,GET_BYTE_READY
			
			DEC DE
			LD A,E
			OR D
			JR NZ,GET_BYTE_2
			SCF
			RET				;We timed out
			
GET_BYTE_READY:						;*** TODO check here if Bit 2 is a 1 and warn of possible data loss...
	
			LD A,14h			;143Bh - RX_SETBAUD
			IN A,(3Bh)			;Used as no effect on Flags for Zero from above
			OR A				;CCF
			RET
	
			
Tim Gilberts - January 2018

