COMPUTADOR
- ZX SPECTRUM

TUTORIAIS
"Como Ligar o ZX
Spectrum ao Raspberry PI3"
-
Parte 1 de 10 - Hardware
Necessário para o Projecto.- Ver
- Parte 2 de 10 -
Instalação do S.O. do
Raspberry PI3. - Ver
- Parte 3 de 10 -
Instalação de alguns
utilitários
necessários.- Ver
- Parte 4
de 10 -
Teste da Conexão entre Raspberry e ZX Spectrum.- Ver
- Parte 5
de 10 - Apresentação dos Programas utilizados no
Projecto.
Nesta parte do Tutorial vamos aprofundar mais os detalhes da
programação do ZX Spectrum. Todas as rotinas que
executam funções com grande rigor na
temporização têm que ser colocadas na
memória RAM Alta. A memória Alta é
utilizada exclusivamente pela CPU e está localizada a partir
do endereço 32768 até ao 65535. No nosso
programa vamos colocar na memória Alta, as rotinas
de
Envio/Recepção de Dados através da
Porta RS232. Optamos por colocar essas Rotinas no endereço
65436, ocupando apenas os últimos 100 bytes da
memória RAM do ZX Spectrum.
Nas transferências de dados entre o ZX Spectrum e o Raspberry
não vamos usar o controle de fluxo por hardware, porque o
Raspberry não tem os sinais RTS/CTS. A
solução que
arranjamos foi usar um protocolo de software que não precisa
desses sinais. Vamos utilizar um sistema de Pacotes de Dados de tamanho
variável, para evitar erros na
transmissão/recepção. Vejamos
a estrutura
dum Pacote de Dados:
#Bytes
Funcao
==============================
2 Tamanho
Pacote menos 2
1 Flag
n Dados
1 CRC
==============================
Os dois primeiros bytes indicam o tamanho do bloco de dados. O byte
seguinte, chamado FLAG é usado para identificar o bloco de
dados.
Depois vêem os Dados propriamente ditos e que podem ter o
tamanho que quisermos sem ultrapassar o limite de 64K. Por
último temos o byte de controle CRC, este byte fecha o Bloco
de dados.
Observe o seguinte exemplo, vamos enviar a letra "A", com o
código ASCII 65 e a FLAG 128, fica assim.
==============================
3 - Tamanho Bloco Dados
0 - Tamanho Bloco Dados
128 - Flag
65 - Dados
193 - CRC
O
byte CRC é obtido realizando a
operação Lógica XOR entre os bytes do
Bloco, excluindo o Tamanho. Vamos fazer o calculo em binário
para se perceber melhor.
Binário Decimal
==============================
Entrada:
10000000 128
01000001 65
Saida (CRC):
11000001 193
A
função lógica XOR dá um
valor lógico "1" na saida se os dois bits de entrada forem
diferentes, caso contrário dá
"0". No nosso protocolo de comunicação o
Raspberry desempenha o papel de Servidor e o ZX Spectrum de Cliente.
Cabe ao Spectrum iniciar a comunicação e ao
Raspberry responder ao comando solicitado.
O Interface 1 usa três Portos de Entrada/Saída
para controlar o Hardware.
=========================================================
- Porto 247 - Leitura/Escrita de Dados na Porta
RS232
ou na Rede.
- Porto 239 - Estado e Controle de
vários Sinais.
- Porto 231 - Leitura/Escrita de Dados na
Microdrive.
=========================================================
Vejamos a
descrição dos mesmos.
=========================================================
Porto 247
(RS232/NETWORK DATA) - Leitura
=========================================================
Bits:
B0 --> NETWORK INPUT
B1 --- x
B2 --- x
B3 --- x
B4 --- x
B5 --- x
B6 --- x
B7 --> RS232 RX DATA
=========================================================
Porto 247 (RS232/NETWORK DATA) - Escrita
=========================================================
Bits:
B0 <-- NETWORK OUTPUT / RS232 TX DATA
B1 --- x
B2 --- x
B3 --- x
B4 --- x
B5 --- x
B6 --- x
B7 --- x
=========================================================
Porto 239
(STATUS/CONTROL) - Leitura
=========================================================
Bits:
B0 --> WR PROTECT
B1 --> SYNC
B2 --> GAP
B3 --> CTS
B4 --> BUSY
B5 --- x
B6 --- x
B7 --- x
=========================================================
Porto 239 (STATUS/CONTROL) - Escrita
=========================================================
Bits:
B0 <-- COMMS OUT = 0 NETWORK OUTPUT
= 1 RS232 OUTPUT
B1 <-- COMMS CLK
B2 <-- R/W
B3 <-- ERASE
B4 <-- RTS
B5 <-- WAIT
B6 --- x
B7 --- x
=========================================================
Porto 231 (MICRODRIVE R/W)
=========================================================
Para ler os dados da Porta RS232 utilizamos o Porto 247 e verificamos o
estado do Bit 7. O circuito electrónico
responsável por gerir as tensões
eléctricas nos
pinos da ficha RS232 não inverte os niveis
eléctricos, assim se o Bit 7 for zero, significa que o sinal
RXD está a -15v, caso contrário a
tensão é de +15v. O mesmo acontece com o sinal
TXD. Vamos apresentar o primeiro programa para o ZX Spectrum,
responsável pelo carregamento do nosso Sistema Operativo.
Este programa Abre, Carrega e Executa o ficheiro "ZX-SOS" que
está localizado no Raspberry.
;================================================
;Programa de arranque do Sistema ZX-SOS V1.4
;
;Linguagem:
;
;ASM Z80 (Compilador AZ80)
;
;Computador:
;
;ZX Spectrum 48K c/ Interface 1
;
;Actualização:
;
;2023-06-25
;
;(C) por Jorge Pedro Soares
;================================================
;Constantes usadas no programa.
if1_rwdat equ 247 ;Porto Leitura/Escrita Dados
if1_ctrl equ 239 ;Porto de Controle
if1_mdrv equ 231 ;Porto da MicroDrive
rx_chk equ 128 ;Mascara para Sinal RXD
baud equ 20 ;9600
bauds
rs_in_rot equ 65436 ;Rotina de recepção
de dados
rs_out_rot equ 65486 ;Rotina de envio de dados
org 23818 ;O programa começa neste endereço
di
ld hl,rs_in_48K ;Copia as rotinas da
ld de,rs_in_rot ;porta rs232 para o
ld bc,100 ;topo da memoria
RAM!
ldir
;------------------------------------------------
;Selecciona a Porta RS232 e coloca a linha RTS
;em repouso!
ld a,239 ;Em
binário é 11101111
out (if1_ctrl),a ;Porto de Controle
;Coloca também a linha TXD em repouso.
xor a
;Faz Reg. A=0
out (if1_rwdat),a ;Porto de Entrada/Saida Dados
;------------------------------------------------
;Envia o Comando OPEN_ZXFILE, neste caso
;abre o ficheiro "ZX-SOS".
ld hl,Cmd_OPEN_ZXFILE ;Bloco de dados do
;Comando OPEN_ZXFILE
call Send_Block ;Envia Bloco de dados ao Raspberry
ld hl,Buf_RX ;Buffer para colocar os dados recebidos.
call Recv_Block ;Recebe Bloco de dados do Raspbrry
;Recebe a resposta do Raspberry. Todos os ficheiros
;para o ZX Spectrum têm que ter um Bloco Inicial chamado
;"BOOT_BLOCK" de 12 bytes, com os caracteres "ZXFILE" e
;com o endereço onde vai ser carregado o proximo bloco.
jr nz,error ;Termina o programa se ocorreu erro!
;A resposta só é válida se for
recebido o
;"BOOT_BLOCK", indicado pela FLAG com código "128".
ld a,b ;O Reg.A contem o
valor da FLAG. Se for
cp 128 ;128
é um ficheiro para o
Spectrum.
jr z,Main2
;Para os outros valores é indicado erro
;assinalado pelo piscar da margem do ecrã.
Error:
ei
Error2:
ld a,r
and 7
out (254),a
halt
jr Error2
;Continua neste ponto se tudo estiver OK.
main2:
;Carrega o segundo bloco (PROGRAM_BLK),
;no endereço RAM indicado pelo BOOT_BLK.
;Envia o comando LD_BLK ao Raspberry.
;Recebe como resposta o Bloco de dados
;a seguir ao BOOT_BLK.
ld hl,Cmd_LD_BLK ;Comando LD_BLK
call Send_Block ;Envia ao Raspberry
;Como resposta o Raspberry envia o PROGRAM_BLK.
ld hl,(ADDR_LD);Endereço da RAM para o
PROGRAM_BLK.
push hl
call Recv_Block ;Recebe Bloco de dados do Raspbrry
pop hl ;Recupera
valor de
HL.
jr nz,error ;se ZF=0 Salta para ERROR.
jp (hl) ;Salta para
o
endereço de
;execução do PROGRAMA.
;------------------------------------------------
;Rotinas
;------------------------------------------------
;Esta rotina é usada para sincronizar a
comunicação
;entre o ZX spectrum e o Raspberry, basicamente
;consiste no seguinte, o Spectrum envia os caracteres
;"ZX" ao Raspberry e aguarda que o Raspberry os devolva.
;Este procedimento é executado sempre pelo ZX
Spectrum
;antes de enviar um Comando.
rs_sync:
ld a,90 ;Letra "Z"
ld c,a ;C="Z"
rs_sync2:
ld a,c
call rs_out ;Envia a letra "Z" ao Raspberry.
call rs_in ;Aguarda a resposta do Raspberry.
cp c ;Se for a
letra "Z"
continua.
jr nz,rs_sync2 ;Senão repete de novo.
;Envia a letra "X" e fica a aguardar
;que o Rspberry reenvie a mesma letra.
ld a,88 ;Letra "X"
ld b,a ;B="X"
call rs_out ;Envia Letra "X"
rs_sync3:
;Fica num ciclo a
ler os bytes da Porta
;RS232. Só são aceites as letras "Z" e "X",
;outros valores reiniciam a rotina!
call rs_in
cp c
;Se for a letra "Z" continua
;a ler a Porta RS232.
jr z,rs_sync3
cp b
;Termina a rotina se for
;detectada a letra "X"
jr nz,rs_sync ;Senão Reenicia o
Procedimento.
ret
;------------------------------------------------
;Esta rotina lê un bloco de dados para o
;endereço indicado em HL.
recv_block:
;HL tem o endereço da RAM onde vamos colocar
;os dados recebidos.
call rs_in ;Lê 1 byte da Porta RS232
ld e,a ;1º byte do tamanho do bloco.
call rs_in ;Lê outro byte da Porta RS232
ld d,a ;2º byte do tamanho do bloco.
dec de ;Ajusta o Tamanho do Bloco porque
;vamos
receber ainda a FLAG_BLK
;que
já faz parte do Bloco de Dados.
;DE Contém o tamanho do bloco menos 1.
call rs_in ;Lê a FLAG_BLK da Porta RS232
ld c,a ;Inicializa o CRC c/ FLAG_BLK
ld b,a ;Guarda FLAG_BLK no Reg.B
;A detecçao de erros é feita em
;tempo real, sendo assim quando
;terminar a transferência de dados
;a Flag Z deve apresentar o valor 1
;para ter sucesso.
;Entramos agora num ciclo que Lê o numero
;de bytes indicados em DE e coloca-os no
;endereço apontado por HL.
recv_data:
call rs_in
ld (hl),a
xor c ;Calcula o CRC!
ld c,a ;Guarda-o no regist C!
inc hl
dec de
ld a,d
or e
jr nz,recv_data
ld a,c ;CRC
or a ;Z=1 OK / Z=0 Erro!
ret
;------------------------------------------------
Send_block:
call rs_sync ;Sincroniza a Comunicação.
ld e,(hl) ;Carrega DE com o tamanho do Bloco.
inc hl
ld d,(hl)
dec hl
inc de ;Ajusta Tamanho Bloco pois vamos
inc de ;enviar mais 2 bytes.
Send_data:
ld a,(hl)
call rs_out
inc hl
dec de
ld a,d
or e
jr nz,Send_data
ret
;================================================
;Esta rotina controla a cor da margem enquanto
;recebe um byte, coloca primeiro a magem em azul
;e depois de receber um byte coloca-a em preto.
rs_in:
ld a,1
out (254),a
call rs_in_rot
ex af,af'
xor a
out (254),a
ex af,af'
ret
;------------------------------------------------
;Esta rotina faz o mesmo que a anterior, só que
;coloca primeiro a magem em vermelho e depois de
;enviar um byte coloca-a em preto.
rs_out:
ex af,af'
ld a,2
out (254),a
ex af,af'
call rs_out_rot
xor a
out (254),a
ret
;==============================================================
;Actualizaçao:
;
;2023-04-20
;2023-04-06
;2022-10-16
;
;(C) Jorge P. Soares
;Rotinas RS232 para ZX Spectrum 48K - Interface 1
;BAUD Constantes
;
;19200 -> 273,182
;9600 -> 364T,546T -> E=20
;4800 -> 729T,1093T -> E=43
;2400 -> 1458T,2187T -> E=88
;
;==============================================================
rs_in_48K:
exx
ld c,if1_rwdat
ld d,rx_chk
ld l,128 ;Em binário
é 10000000. O Bit 7 vai ser usado como
;marcador, quando chegar ao BIT 0 passa
;depois para a CF provocando o Termino da ROIINA
ld e,baud ;Constante de
Temporização
rs_start:
in a,(c) ;Lê linha RXD
and d ;Verifica Bit 7,
jr z,rs_start ;Se for zero repete
;Após a detecção do START BIT espera
1,5 BAUDS
;antes de ler a linha RXD.
;As instrucoes a seguir calculam a constante
;BAUD * 1,5 + 1 necessaria para a temporizaçao inicial.
ld a,e ;E = Constante de
Temporizaçao.
rra ;
add a,e ;
add a,1 ;
ld d,a ;D = E * 1,5 + 1
;------------------------------------------------
;Aguarda 1,5 BAUDS antes de ler a porta RS232.
rs_loop:
dec d
jr nz,rs_loop ;Ciclo de temporização.
;------------------------------------------------
and a ;
ld d,e ;E = Proximas
Temporizações
;são de 1 BAUD.
in h,(c) ;Lê linha RXD.
;------------------------------------------------
rlc h ;Coloca BIT 7 do Reg. H na CF.
rr l ;Coloca CF no BIT 7 do Reg. L. Ao
mesmo
;tempo
move o BIT 0 para a CF.
jr nc,rs_loop ;Repete o ciclo enquanto a CF=0
;
;------------------------------------------------
srl e ;Calcula Baud/2
rs_stop:
dec e
jr nz,rs_stop ;Temporização Final de
1/2 BAUD
ld a,l ;A = L = Byte Recebido.
cpl ;Inverte os Bits para cumprir a
norna RS232.
exx
ret ;Termina a rotina no inicio do STOP
BIT
;para dar tempo a
receber o proximo Byte.
rs_inx:
dx 8,0 ;Sem importancia, só para ajustar o tamanho
;das duas
rotinas para 100 Bytes.
;==============================================================
rs_out_48K:
;==============================================================
exx ;Usa os registos alternativos para ser mais rapido.
cpl ;Inverte os bits de
acordo
;com
o Protocolo RS232.
ld h,a ;A = Byte para Enviar.
ld e,baud ;E = Velocidade de Transmissão.
;No Total vamos enviar 10 bits:
;
; - 1 START BIT
; - 8 BITS DADOS
; - 1 STOP BIT
ld l,10 ;L =
Contador de Bits
ld a,1 ;A =
Linha TX ligada para START BIT
ld c,if1_rwdat ;C = Porto de Envio de dados
rs_out2:
;--------------------------------------------------------------
out (c),a ;Coloca linha TX
no estado indicado
;no registo A
ld d,e ;E =
Constante de Temporizaçao
rs_out3:
dec d
jr nz,rs_out3 ;Ciclo de Temporizaçao
xor a
;Limpa A
rr h
;H contém Byte a Enviar, Coloca Bit 0 de H
;na Flag C e Limpa Bit 7
rla
;Roda a Flag C para o Bit 0 do Reg. A para
;controlar sinal TXD.
dec l
;
jr nz,rs_out2 ;Repete o Ciclo até L=0
exx
;
ret
;
rs_outx:
;------------------------------------------------------------------------------
;Dados
;--------------------------------------
Buf_RX:
DX 6,0
ADDR_LD:
DX 8,0
;--------------------------------------
Cmd_OPEN_ZXFILE:
DB 9 ;Tamanho BLOCO 11-2=9
DB 0
DB 4 ;Cmd_OPEN_ZXFILE
DB "Z" ;Nome "ZX-SOS"
DB "X"
DB "-"
DB "S"
DB "O"
DB "S"
DB 10
DB 110 ;CRC
;------------------------------------------------
Cmd_LD_BLK:
db 2 ;LEN
db 0
db 32 ;Cmd_LD_BLK
db 32 ;CRC
;------------------------------------------------
;eof
Este
é o programa que vamos usar para iniciar o sistema operativo
ZX-SOS. O código ASM mostrado produz 274 bytes de dados.
Vamos usar um truque que consiste em colocar este código
dentro dum programa BASIC. Normalmente o Programa BASIC do ZX Spectrum
48K é carregado no endereço 23755, mas quando se
liga o Interface 1 o sistema altera esse endereço
para 23813. Podemos saber qual é o valor actual, escrevendo
o
seguinte programa BASIC:
PRINT PEEK
23635+256*PEEK 23636
Quando
que se liga o ZX Spectrum com o Interface 1 conectado, ainda
é apresentado o endereço 23755, só
depois de usar um dos comando concebidos para o Interface é
que o Sistema muda o dito endereço. Como tinhamos dito no
parágrafo anterior, vamos colocar o código ASM
dentro do programa BASIC, para isso criamos uma linha com o comando REM
com 300 caracteres, depois é só fazer LOAD ""
CODE e gravar o programa normalmente. Não podemos
esquecer-nos de digitar por exemplo o comando "CAT 1" antes de carregar
o código ASM, para o ZX
Spectrum mudar o endereço do BASIC. Veja a imagem 5.1 para
ter uma ideia dum programa BASIC para essa
função.
Para
obter o Código Máquina, escrevemos com um editor
de
texto no Windows/Ms-Dos o programa que mostramos neste tutorial e
gravamos com o nome "sos48k.asm". Todos os programas ASM apresentados
neste tutorial devem ser compilados com o nosso utilitario "AZ80". Este
utilitário é muito prático e funciona
em vários Sistemas Operativos da MicroSoft, só
possui uma limitação, não usa nomes
grandes para Ficheiros/Directorios. Para o nosso exemplo use a seguinte
linha de comandos no PC:
AZ80.COM
-all -cod sos48k sos48k > log.txt
Abra
o
ficheiro "log.txt" para obter mais informações
sobre o
ficheiro que acabamos de compilar. Este utilitário cria
um ficheiro "TAP" pronto a ser carregado pelo ZX Spectrum. Para quem
não quiser ter esse trabalho todo pode descarregar os
ficheiros (TXT,ASM,AZ80,TAP e WAV).
Programa
SOS48K - download
Notas
importantes sobre as Microdrives.
À
semelhança do que se passa com o Raspberry em
relação às letras
maiúsculas, nas
Microdrives também acontece o mesmo, assim ao gravar ou
carregar um programa temos que ter atenção ao
nome do
mesmo, não podemos trocar as maiúscula por
minúsculas pois vai dar erro. Por
exemplo "Teste" é diferente de "teste". O melhor mesmo
é
gravar tudo em minúsculas para não haver
confusão.
Como
já é do conhecimento dos utilizadores do
Spectrum, existe a opção de
execução automática dos programas
BASIC. Para usar essa opção temos
que colocar a
função LINE à frente do SAVE, como
indicado a seguir.
SAVE
"programa" LINE 10
O
Sistema da Microdrive acrescentou mais uma facilidade, trata-se do
carregamento automático dum programa que esteja na
Microdrive.
Para isso acontecer o programa tem que chamar-se "run" e ter sido
gravado com a função LINE. Para
executa-lo basta escrever no Spectrum "run" e carregar em "ENTER", o
programa arranca imediatamente. Esta função
só está activa se o Spectrum acabou de
ser ligado ou se foi executado o
comando
"NEW". Para concluir, depois de carregar o programa a partir
duma Cassete com o comando MERGE "", grave-o numa Microdrive com o
comando:
SAVE
*"m";1;"run" LINE 10
Assim
sempre que precisar de carregar o nosso Sistema Operativo,
só tem que premir as teclas "RUN" e "ENTER" do
ZX Spectrum.
Para
o Raspberry escrevemos o programa em Python3 que mostramos a seguir. O
programa é uma versão de teste. Pode
editá-lo com o utilitário NANO como mostramos num
tutorial anterior ou pode fazer o download no link que vamos indicar
mais à frente. Alertamos para os cuidados a ter ao
escrevermos o programa, devemos respeitar escrupulosamente o
espaçamento do texto, basta colocar um espaço a
mais ou a menos para provocar erro na execução do
programa. É uma boa prática usar multiplos de 4
espaços para alinhar o código (0, 4, 8, 12, 16,
etc). Segue o programa:
#
---------------------------------------
# Programa RPI3SERVER Versão 1.1
#
# Linguagem: PYTHON3
#
# Este programa implementa os COMANDOS:
#
# OPEN_ZXFILE
# LD_BLK
# DIR
#
# Actualizações:
#
# 2023-04-11
# 2023-04-09
# 2023-04-08
# (C) by Jorge P. Soares
# ----------------------------------------
import os
import serial
import time
rs = serial.Serial("/dev/ttyAMA0", 9600)
path = "./FTP/files/"
fflag = 0
print("Sistema Online!")
rs.write([170])
# CODE 1
while True:
rst = 0
old = 0
new = 0
while (rst == 0):
old
= new
rxd
= rs.read(1)
rs.write(rxd)
new
= int.from_bytes(rxd, "little")
print(rxd)
if
new == 88 and old == 90:
print("Codigo
Detectado!")
rst
= 1
else:
print("Lixo!")
print("Aguardando Ordens!")
rxd = rs.read(2)
rxsz = 256 * rxd[1]+rxd[0]
print("Recebendo ", rxsz,"
Bytes")
rxd = rs.read(rxsz)
crc = 0
print("Verificando CRC.")
for i in range(0, rxsz):
crc
= crc ^ (rxd[i])
print("CRC = ",crc)
if crc == 0:
print("Descodificando
Comandos.")
cmd
= rxd[0]
if
cmd == 2:
#
Lista os ficheiros do directorio ZX
print("Comando
DIR.")
zx_dir
= []
files
= os.listdir(path)
for
f in files:
zx_dir.append(f+"\n")
n_files
= len(zx_dir)
print("Numero
de Ficheiros:",n_files)
txd
= [0,0,2,n_files]
for
i in range(n_files):
fn_bytes
= bytes (zx_dir[i], 'utf-8')
for
n in range(len(fn_bytes)):
txd.append(fn_bytes[n])
crc
= 0
print("Calculando
CRC dos dados a Enviar!")
for
m in range(2, len(txd)):
crc
= crc ^ (txd[m])
txd.append(crc)
txsz
= len (txd)
txsz2
= txsz -2
txszb
= txsz2.to_bytes(2,"little")
txd
[0] = txszb [0]
txd
[1] = txszb [1]
print("Enviando
dados para o ZX!")
rs.write(txd)
elif
cmd == 32:
print("Lendo
Bloco de Dados!")
rdd
= f.read(2)
rdsz
= 256 * rdd[1] + rdd[0]
rdd2
= f.read(rdsz)
rs.write(rdd)
rs.write(rdd2)
elif
cmd == 4:
print("Abrindo
Ficheiro para Execucao!")
fn
= rxd[1:rxsz - 2]
fn2
= "".join(map(chr,fn))
try:
print("Lendo
Ficheiro Indicado!")
f
= open(path + fn2,"rb")
rdd
= f.read(12)
rdsz
= 256 * rdd[1] + rdd[0]
print(rdsz)
id1
= "ZXFILE"
id2
= "".join(map(chr, rdd[3:9]))
print("Abrir
Ficheiro:",fn2)
if
rdsz == 10 and id1 == id2:
rs.write(rdd)
print("BOOT
Block enviado!")
fflag
= 1
else:
print("Bad
File!")
txd
= [2, 0,66,66]
rs.write(txd)
f.close()
fflag
= 0
except
FileNotFoundError:
txd
= [2,0,65,65]
rs.write(txd)
print("O
Ficheiro nao existe!")
else:
print("Comando
Invalido")
else:
print("Deu
Merda!")
break
# --------------------------------------------------------
# eof
# --------------------------------------------------------
Programa
RPI3SERVER - download
Vamos agora
instalar e configurar um Cliente FTP para podermos enviar os ficheiros
(jogos e programas) para o Raspberry. Já
instalámos num artigo anterior um servidor FTP no Raspberry,
chegou o momento de usá-lo. Podemos utilizar
vários equipamentos para comunicar com o Servidor FTP,
optámos por um Telemóvel Android. Vamos instalar
um Cliente FTP
chamado "AndFTP" no nosso Telemóvel. Observe as imagens
seguintes para
acompanhar o processo.
Vamos
pesquisar no Play
Store a aplicação "andftp".
Da
lista
que aparece, seleccionamos a aplicação "andftp
(your ftp client)".
Clicamos
no
icon da aplicação para avançar!
Carregamos
em instalar para prosseguir!
Abrimos
a aplicação e clicamos no botão "+"
para adicionarmos o Servidor do Raspberry!
Introduzimos
os dados pedidos na imagem e clicamos em guardar, os valores podem ser
outros, depende das configurações de cada
Raspberry!
Atribuimos
um
nome ao Servidor que acabámos de criar!
E
pronto
já está configurado o Cliente FTP. Sempre que
precisarmos de enviar ficheiros para o Raspberry é
só abrir a aplicação e clicar no icon
do Servidor!
Este
ecrã mostra os Ficheiros/Directorios do Raspberry,
seleccionamos o
directorio "files", para colocarmos os ficheiros do nosso projecto.
Clique no icon que representa o
Telemóvel no topo do ecrã, para escolhermos os
ficheiros que vamos enviar
para o
Raspberry.
Neste
ecrã temos acesso aos
Ficheiro/Directorios do Telemóvel, clicamos no directorio
onde estão os
ficheiros que queremos enviar para o Raspberry (upload).
Por
fim
seleccionamos os
ficheiros que queremos enviar e clicamos na seta que aponta para cima.
Esta seta indica que vamos enviar os ficheiros para o computador remoto
Raspberry, esta operação chama-se upload. Quando
a seta aponta
para baixo significa download. Para mudar dum modo para o outro
(upload/download) clicamos no icon do despositivo (Telemóvel
ou Nuvem) que está no topo do ecrã.
Podemos
usar também um Cliente FTP para o Computador Pessoal. Um dos
mais
utilizádos é o "FileZilla" e é
grátis. O FileZilla permite fazer as
transferências mais facilmente entre os dois computadores.
Essa
facilidade é devida ao facto de o FileZilla mostrar
simultaneamente os
ficheiros do computador local e os do computador remoto.
Assim é
só clicarmos nos ficheiros duma janela para transferir para
a outra. A janela da
esquerda mostra os ficheiros do computador local e a da direita os do
computador remoto. Para fazer o upload clicamos num ficheiro da
janela da esquerda e para o download clicamos num ficheiro da janela da
direita.
Observe
a Fig.5.13 para perceber como configurar o FileZilla, resumidamente os
dados são os mesmos que foram usados com o "AndFTP".
Programa
Cliente FTP FileZilla para Windows XP - download
Para
terminar esta parte do tutorial vamos criar no
Telemóvel/Tablet ou Computador Pessoal um Directorio chamado
"_RPI3", é nele que vamos colocar os ficheiros que queremos
enviar para o Raspberry. Vamos copiar o ficheiro rpi3server.py
para esse directrorio. Com o Cliente FTP vamos enviar agora esse
ficheiro para o Raspberry. Para ser mais fácil de usar o
programa rpi3server temos que copiá-lo para o directorio do
Python3 que é o "home", para faze-lo digite o seguinte
comando no Putty:
cp
FTP/files/rpi3server.py rpi3server.py
O
comando "cp" abreviatura de "copy" copia o ficheiro rpi3server.py do
directorio FTP/files para o directorio "home". Para executar o programa
digite:
python3
rpi3server.py
Descarregue
alguns jogos da nossa lista e transfira-os para o Raspberry com o
Cliente FTP (Atenção temos que descompacta-los
com o WinRAR antes de envia-los ). Execute os dois programas
"rpi3server.py" no Raspberry e
"sos48k-boot" no ZX Spectrum.
Se
tudo estive bem podemos começar a usar o programa do ZX
Spectrum. O sistema ZX-SOS tem os seguintes comandos
implementados:
-
DIR -
Mostra os ficheiros existentes no Raspberry.
- CLS - Limpa Ecrã.
Para executar um Programa/Jogo basta digitar o nome mostrado pelo
comando DIR. Para sair dum
Jogo é necessário desligar ou fazer o Reset do ZX
Spectrum, depois basta premir "RUN" e "ENTER" para voltar ao Sistema
ZX-SOS.
Chegamos
ao
fim de mais um tutorial, no próximo vamos abordar o ZX
Spectrum 128K, +2 e +3.
Até
à Próxima.
Chegou
finalmente o momento da acção,
vamos começar por ligar todos os cabos e equipamentos usados
no
nosso projecto. Observe a fig.4.1 para ter uma ideia, não se
esqueça que deve ligar a ficha DB9 Macho Cinzenta ao
Raspberry e a Preta ao ZX Spectrum.
O
protocolo RS232 usa um START BIT e um STOP BIT para sincronizar a
comunicação. É utilizada uma
lógica invertida, quer dizer, para representar o
nível lógico "0" usa-se uma tensão
alta (+15V) e para o nível lógico "1" uma
tensão baixa (-15V). Resumindo é o seguinte:
Start Bit =
+15Volts
Stop Bit = -15Volts
Nivel Lógico 0 = +15Volts
Nível Lógico 1 = -15Volts
A
sequência de
Transmissão/Recepção é a
seguinte:
StartBit,
Bit0, Bit1, Bit2, Bit3, Bit4, Bit5, Bit6, Bit7, StopBit.
A
norma RS232 usa ainda um
Parity Bit que é opcional, no
nosso projecto não vamos usar esse bit. Examine a fig.4.2
para ter uma visão concreta da sequência dos
dados.
Ligue
agora à corrente o Rasberry, o ZX Spectrum e o Monitor.
Neste momento o Rasberry apresenta uma tensão electrica de
+5,5Volts no pino TXD e o Spectrum
de +7Volts também no mesmo pino. Assim que usarmos a
Microdrive
a tensão do pino TXD do ZX Spectrum desce automaticamente
para -15Volts. O valor destas tensões não
é muito importante porque a margem de
variação é grande. Para o valor
lógico "0" a tensão pode estar compreendida entre
+3V e +15V. No caso do valor lógico "1" a tensão
pode variar entre -3V e -15V.
No ZX Spectrum é
usado o porto 247 para ler a linha RXD. O
valor da linha é dado no bit 7.
Digite este pequeno programa no Spectrum para ler a linha RXD.
10 LET d=IN
247
15 POKE 23692,0
20 PRINT d: GOTO 10
Se
a variável D for
menor que 128 significa que a tensão no
pino RXD
está na gama de -3V a -15V, caso contrário a
tensão tem um valor entre +3V e +15V.
No
Raspberry PI3 temos ainda que configurar a porta RS232, para isso
digite no programa Putty o comando:
sudo
raspi-config
e
siga os passos indicados nas
imagens seguintes:
Após
ter feito as configurações e reiniciado o
Raspberry vamos fazer novamente o Login no programa Putty e digitar o
comando:
echo
"dtoverlay=disable-bt" | sudo tee -a /boot/config.txt
Com este
último comando terminámos as
configurações
do sistema operativo do Raspberry. Vamos agora dedicar-nos ao
desenvolvimento dos programas para a comunicação
serial
entre os dois computadores. No Raspberry vamos usar uma linguagem de
programação chamada "Python". Escolhemos esta
linguagem
por ser a mais fácil e rápida de aprender e
também
por ser a mais utilizada para desenvolver pequenos programas para o
Raspberry.
Todas
as
linguagens de programação usam as chamadas
"Bibliotecas" para controlar o hardware instalado. Estas Bibliotecas
não são mais do que rotinas criadas
especificamente para a função pretendida, por
isso
temos que instalar a Biblioteca para controlar a porta Serial
do
Raspberry com o seguinte comando:
sudo apt-get
install python3-serial
e pronto
chegamos finalmente ao fim de todas as
configurações, vamos apenas apresentar o primeiro
programa para executar no Raspberry. Este programa tem como
objectivo testar a
comunição entre o Raspberry e o ZX Spectrum.
É
obrigatório respeitar as letras maiúsculas e
minúsculas no momento de escrever um programa porque o
sistema faz distinção entre elas. Por exemplo as
palavras "serial" e "Serial" são interpretadas de modo
diferente. Outra coisa importante consiste no alinhamento do texto,
cada bloco de código deve ficar alinhado na mesma coluna.
Posto isto eis o primeiro programa.
Use o editor NANO para
escrever o programa:
nano
p4.py
Este
programa recebe o byte da porta RS232 enviado pelo ZX Spectrum e envia
de volta o byte para o ZX Spectrum pela porta RS232, veja a
descrição do programa:
- Importa a
Biblioteca "serial" usada para controlar a porta RS232.
- Importa a Biblioteca "time" necessária para as
funções de temporização.
- Abre e configura a porta Serial a 9600 Bauds.
- Cria um ciclo infinito com a instrução "while
True:". As instruções seguintes são
executadas infinitamente.
- Lê um byte da porta RS232 "rxd = rs.read(1)".
- Faz uma pausa de 0,1 segundos.
- Escreve um byte na porta RS232 "rs.write(rxd)".
- Mostra no ecrã o byte recebido.
Para
o ZX Spectrum temos também um programa. Este programa usa
algumas rotinas em ASM "Código-Máquina" para se
conseguir uma velocidade suficientemente alta. Estas rotinas
estão colocadas
nas linhas DATA do programa BASIC. No programa criamos um ciclo
de contagem decrescente com a instrução FOR, essa
contagem começa no numero 63 e termina no 0.
Enviamos a contagem (Byte a Byte) para o Raspberry e
esperamos que o Raspberry nos envie esses valores de volta. Para que o
teste tenha
sucesso é necessário que os bytes recebidos sejam
iguais aos bytes enviados ao Raspberry.
Há
duas formas de
obter o programa, uma é escrever o programa que mostramos a
seguir directamente no ZX Spectrum, a outra é descarregar o
ficheiro WAV ou TAP e carrega-lo no ZX Spetrum através dum
leitor de audio
(Gravador de Cassetes ou Leitor de MP3).
Digite
este
programa no ZX Spectrum ou descarregue o ficheiro mais à
frente.
10 BORDER
0: PAPER 0: INK 6: GOSUB 1000
13 PRINT "Testando Comunicacao c/ RPI3!"
15 PRINT : PRINT "Aguarde um memento ...": PRINT
20 FOR t=63 TO 0 STEP -1
25 POKE 50000,t: POKE 65006,1
30 RANDOMIZE USR 65002
35 LET f=USR 65000
40 LET d=PEEK 50000
45 PRINT d: POKE 23692,0
50 IF f<>1 THEN PRINT : PRINT PAPER 2; FLASH 1;"Raspberry
PI3 nao encontrado!": STOP
55 IF d<>t THEN PRINT "Erro de Comunicacao!": STOP
60 NEXT t
65 PRINT : PRINT PAPER 1; INK 6; FLASH 1;"Cabo RS232 Testado C/
Sucesso!": PRINT : PRINT : PRINT
999 STOP
1000 CLEAR 29999: RESTORE 2000
1005 LET m=65000: LET s=0
1010 READ d: IF d>255 THEN GOTO 1050
1015 POKE m,d: LET m=m+1: LET s=s+d: GO TO 1010
1050 IF d<>s THEN PRINT "Data Error!": STOP
1060 RETURN
2000 DATA 24 ,5 ,24 ,45 ,80
2010 DATA 195,0 ,243,14 ,127
2020 DATA 6 ,100,42 ,236,253
2030 DATA 30 ,20 ,205,44 ,254
2040 DATA 56 ,5 ,16 ,247,72
2050 DATA 24 ,20 ,119,35 ,30
2060 DATA 20 ,205,44 ,254,48
2070 DATA 3 ,13 ,32 ,244,237
2080 DATA 75 ,236,253,237,66
2090 DATA 68 ,77 ,251,201,243
2100 DATA 42 ,236,253,58 ,238
2110 DATA 253,71 ,126,30 ,20
2120 DATA 205,105,254,35 ,16
2130 DATA 247,251,201,229,197
2140 DATA 14 ,247,22 ,128,33
2150 DATA 230,27 ,62 ,1 ,211
2160 DATA 254,237,120,162,32
2170 DATA 7 ,43 ,124,181,32
2180 DATA 246,24 ,27 ,46 ,128
2190 DATA 123,31 ,131,198,1
2200 DATA 87 ,21 ,32 ,253,167
2210 DATA 83 ,237,96 ,203,4
2220 DATA 203,29 ,48 ,243,203
2230 DATA 59 ,29 ,32 ,253,55
2240 DATA 62 ,0 ,211,254,125
2250 DATA 47 ,193,225,201,229
2260 DATA 47 ,103,62 ,2 ,211
2270 DATA 254,62 ,239,211,239
2280 DATA 46 ,10 ,62 ,1 ,14
2290 DATA 247,237,121,83 ,21
2300 DATA 32 ,253,175,203,28
2310 DATA 23 ,45 ,32 ,243,62
2320 DATA 0 ,211,254,225,201
2330 DATA 19710: REM SOMA TOTAL
9998 STOP
9999 SAVE "RS-TEST" LINE 10
Programa "RS-TEST" - Download
Depois
de ter os dois programas prontos, execute primeiro
o programa do Raspberry PI3 com o comando:
Python3
p4.py
A seguir
execute o programa do ZX Spectrum com RUN. Se tudo estiver
bem é mostrada a mensagem "Cabo RS232 testado c/ Sucesso!".
Por agora é tudo, no próximo tutorial vamos
apresentar os programas para executarem a nossa tarefa,
transformar o Raspberry num Servidor de ficheiros para o ZX Spectrum.
Até
à Próxima!
Anterior
Seguinte
|