sexta-feira, 18 de janeiro de 2008

Recepção RS-232 na porta de Joystick

Tenho uma estratégia para poder fazer a parte de recepção, utilizando os sinais RTS e CTS.

O Sinal RTS serve para indicar ao dispositivo de recepção, que o dispositivo de transmissão quer enviar dados. Já o sinal CTS diz é a resposta que o dispositivo de recepção dá ao dispositivo de transmissão de que já pode receber os dados.

Pois bem, utilizando estes sinais é possível sincronizar o MSX com o PC criando assim uma rotina de recepção mais inteligente, de forma a sinalizar ao PC quando este deve aguardar antes de enviar os dados. Desta maneira pode-se perder um tempo salvando o caractere, ou mesmo movendo um buffer.

É possível, por exemplo redirecionar a entrada (de teclado) para ler a partir da RS232 (como no apple) utilizando o hook da interrupção externa do Z80, gerada pelo VDP, que ocorre a 60Hz. O funcionamento é o seguinte:

Quando o VDP gera uma interrupção, a BIOS chama o Hook HTIMI no endereço 0FD9Fh. Neste momento pode-se checar a entrada de joystick para ver se o PC ativou o sinal RTS. Se o sinal RTS não estiver ativo, então não há caracteres a serem enviados e a rotina termina, devolvendo o controle à BIOS.

Mas se o sinal RTS estiver ativo, as interrupções são desabilitadas, e a rotina de recepção de um caractere é chamada. Esta rotina ativa o sinal CTS para indicar ao PC que o MSX está pronto para receber os dados.

O MSX então aguarda pelo start bit, e em seguida recebe os 8 bits do dado, e o stop bit. Depois ela desativa novamente o sinal CTS e vai processar o caractere recebido.

O Stop bit é checado para garantir que é válido. Se for inválido (“0”), então o caractere recebido é ignorado, caso contrário, ele é colocado no buffer do teclado, que é incrementado. Se o buffer estiver cheio, então a rotina termina. Se não estiver, o MSX checa se o sinal RTS ainda está ativo, e se estiver, ele recebe o próximo caractere, caso contrário, retorna

segunda-feira, 14 de janeiro de 2008

Conversor TTL-232 testado

Acabei de testar com sucesso o circuito de conversão TTL para RS-232 do post anterior. Agora o projeto está completo.

LPRINT na porta de Joystick - Código em BASIC

Acabei de testar a impressão via 'hook' na porta de joystick. O código tinha um pequeno erro mas já corrigi.

O programa ocupa apenas 83 na memória e é carregado a partir do endereço &HE000

A listagem abaixo foi capturada utilizando o lprint para o PC, após o programa ter sido executado:


5 '
10 ' Imprime na porta de Joystick B
20 ' via protocolo rs-232, 9600,N,8,1
30 '
40 ' danjovic@hotmail.com
50 '
60 FOR E=0 TO 82
70 READ B$:POKE &HE000+E,VAL("&H"+B$)
80 NEXT E
90 '
100 DEFUSR=&HE047: B=USR(0)
110 '
200 DATA F3,F5,C5,E5,4F,26,12,3E
210 DATA 0F,D3,A0,DB,A2,CB,F7,D3
220 DATA A1,CD,1C,E0,E1,C1,F1,A7
230 DATA FB,33,33,C9,6C,CD,34,E0
240 DATA 06,08,6C,CB,09,DC,3D,E0
250 DATA D4,34,E0,10,F5,2E,12,CD
260 DATA 3D,E0,47,C9,CB,97,D3,A1
270 DATA 2D,C2,38,E0,C9,CB,D7,D3
280 DATA A1,2D,C2,41,E0,C9,00,21
290 DATA 00,E0,22,B7,FF,3E,C3,32
300 DATA B6,FF,C9

domingo, 13 de janeiro de 2008

Conversor TTL-RS232

Fiz o layout de um conversor de nível RS232 para TTL a partir de um esquema que encontrei. Aproveitei apenas a parte de transmissão, que resultou no circuito abaixo.


Fiz o "layout" de uma placa de circuito impresso em face simples, de forma que ficasse o menor possível. Segue abaixo uma imagem em 300 dpi




E a disposiçao dos componentes na placa fica como a figura abaixo:




Os dois conectores são do tipo para cabo (solda) mas são soldados diretamente na placa, um virado para cima e outro virado para baixo. Assim só foi necessário um Jumper para ligar o pino 5 do conector de joystick do MSX (Vcc) ao circuito.

LPRINT na porta de Joystick

Estou trabalhando numa rotina para capturar o Hook de impressão e redirecionar o caractere à porta de joystick. O código, até o presente momento, consome 86 bytes.



;
; Impressao serial via
; porta de Joystick do MSX
;
; danjovic@hotmail.com
; http://hotbit.blogspot.com
;
; Versao 1.0 14/01/2008
;
; Licenca de uso: GNU GPL
;
;
; Compilado no ASMSX
; http://www.robsy.net/asmsx.htm


ORG 0E000H

.BASIC
.START INSTALA



; Bits do Registro 15 do PSG
BTXD EQU 2
ABSEL EQU 6

; Registros do PSG
PSGAD EQU 0A0H
PSGWR EQU 0A1H
PSGRD EQU 0A2H


; BaudRates
;BAUD EQU 6 ; 19200 Bauds, (6)
;BAUD EQU 10 ; 14400 Bauds, (10)
BAUD EQU 18 ; 9600 Bauds, (17-19)
;BAUD EQU 42 ; 4800 Bauds, (41-43)
;BAUD EQU 92 ; 2400 Bauds, (90-93)
;BAUD EQU 190 ; 1200 Bauds, (188-191)



;
; Envia o Caractere no reg A
; para a porta de B (Joystick)
; 9600,8,n,1

PRNTJ232:
;CALL 0a2h
DI
PUSH AF
PUSH BC
PUSH HL

LD C,A ; Caractere a ser impresso
LD H,BAUD ; define taxa Baud

LD A,15 ; Registro 15
OUT [PSGAD],A
IN A,[PSGRD]
;LD [PSGSAV],A
SET ABSEL,A ; Porta Joystick B
OUT [PSGWR],A
;LD B,A ; salva conteudo reg 15

CALL SND232
;LD A,[PSGSAV]
;OUT [PSGWR],A

POP HL
POP BC
POP AF
AND A
EI
INC SP ; descarta stack
INC SP
RET




SND232:
; Entradas:
; C: Byte a ser transmitido
; A: Estado atual do registrador 15 do PSG
; H: Constante para Baud Rate
;

;
; Envia Start bit (txd=0)
;
LD L,H ; 4+1
CALL SND0 ; 17+1 + (SEND0)

;
; 8 bits do dado, LSbit primeiro
;
LD B,08H ; 7+1
S20:
LD L,H ; 4+1
RRC C ; 8+2
CALL C,SND1 ; 17+1 + (SEND0)/ 10+1 F
CALL NC,SND0 ; 17+1 + (SEND0)/ 10+1 F
DJNZ S20 ; 13+1 b


;
; Stopbit - retorna linha txd para IDLE
;
LD L,BAUD ; 8
CALL SND1 ; 17+1 + (SEND1)
LD B,A ; 4+1
RET ; 10+1


;
; Envia um bit 0
;
SND0:
RES BTXD,A ; txd=0 8+2
OUT [PSGWR],A ; 11+1
S01: DEC L ; 4+1
JP NZ,S01 ; 10+1 ;
RET ; 10+1

;
; Envia um bit 1
;
SND1:
SET BTXD,A ; txd=1 8+2
OUT [PSGWR],A ; 11+1
S11: DEC L ; 4+1
JP NZ,S11 ; 10+1 ;
RET ; 10+1


PSGSAV:
DS 1


;
; Instala subrotina no
; HOOK da impressora
;
; Do livro +50 dicas para o MSX
;
HLPT EQU 0FFB6H
;
INSTALA:
LD HL,PRNTJ232
LD [HLPT+1],HL
LD A,0C3H
LD [HLPT],A
RET

sábado, 12 de janeiro de 2008

Serial Bitbang a 19200 bauds na porta de Joystick

Fiz funcionar a rotina de transmissão serial na porta de joystick. Removidos alguns erros de lógica, consegui transmitir para o PC nas seguintes velocidades:

19200 Bauds, (6)
14400 Bauds, (10)
9600 Bauds, (17-19)
4800 Bauds, (41-43)
2400 Bauds, (90-93)
1200 Bauds, (188-191)

Toda a temporização é feita por software. Os números em parênteses são o parâmetro de temporização. As velocidades de 14400 e 19200 são meio críticas, mas funcionam bem.

A conexão com o PC é através do pino 6 da porta de Joystick B. Eu utilizei um MAX232, alimentado pelo pino 5 (Vcc), mas há outras alternativas[1], [2], embora eu ainda não as tenha testado.

O código fonte encontra-se abaixo.

;
; Rotinas de impressão na porta
; de Joystick do MSX
;
; danjovic@hotmail.com
; http://hotbit.blogspot.com
;
; Versao 0.5 12/01/2008
;
; Licenca de uso: GNU GPL
;
;


ORG 09000H

; Compilado no ASMSX
; http://www.robsy.net/asmsx.htm
.BASIC
.START PRNTJ232

;
; Bits do Registro 15 do PSG
;
BTXD EQU 2
BPLS EQU 5
ABSEL EQU 6

;
; Registros do PSG
;
PSGAD EQU 0A0H
PSGWR EQU 0A1H
PSGRD EQU 0A2H


;
; Constantes

; BaudRates
;BAUD EQU 6 ; 19200 Bauds, (6)
;BAUD EQU 10 ; 14400 Bauds, (10)
BAUD EQU 18 ; 9600 Bauds, (17-19)
;BAUD EQU 42 ; 4800 Bauds, (41-43)
;BAUD EQU 92 ; 2400 Bauds, (90-93)
;BAUD EQU 190 ; 1200 Bauds, (188-191)


;
; Rotina de teste de impressão
; na porta de Joystick
;



PRNTJ232:
DI
LD A,15
OUT [PSGAD],A
IN A,[PSGRD]
LD [PSGSAV],A

SET ABSEL,A ; JOY B
SET BTXD,A ; SDA=1

SYNC:
SET BPLS,A ; start sync
OUT [PSGWR],A
NOP
NOP
NOP
NOP
RES BPLS,A ; stop sync
OUT [PSGWR],A
LD B,A ; B=conteudo reg 15

MUDABAUD:
LD H,BAUD
LD DE,MENSAGEM
REPETE:
LD A,[DE]
INC DE
OR A
JR Z,FIM
LD C,A
CALL SND232
JR REPETE

FIM:
EI
RET


MENSAGEM:
DB "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG 0123456789 ",0

PSGSAV:
DS 1


SND232:
; Entradas:
; C: Byte a ser transmitido
; B: Estado atual do registrador 15 do PSG
; H: Constante para Baud Rate
;
; Modifica A,F,B,C,L

LD A,B ; B=Estado registro 15 PSG

;
; Start bit (txd=0)
;
LD L,H ; 4+1
CALL SND0 ; 17+1 + (SEND0)

;
; 8 bits do dado, LSbit primeiro
;
LD B,08H ; 7+1
S20:
LD L,H ; 4+1
RRC C ; 8+2
CALL C,SND1 ; 17+1 + (SEND0)/ 10+1 F
CALL NC,SND0 ; 17+1 + (SEND0)/ 10+1 F
DJNZ S20 ; 13+1 b<>0/ 8+1 b=0

;
; Stopbit - retorna linha txd para IDLE
;
LD L,BAUD ; 8
CALL SND1 ; 17+1 + (SEND1)
LD B,A ; 4+1
RET ; 10+1


;
; Envia um bit 0
;
SND0:
RES BTXD,A ; txd=0 8+2
OUT [PSGWR],A ; 11+1
S01: DEC L ; 4+1
JP NZ,S01 ; 10+1 ;
RET ; 10+1

;
; Envia um bit 1
;
SND1:
SET BTXD,A ; txd=1 8+2
OUT [PSGWR],A ; 11+1
S11: DEC L ; 4+1
JP NZ,S11 ; 10+1 ;
RET ; 10+1