Que tal realizar algumas
experiências com a porta paralela do seu MSX? O que eu proponho nesse
artigo é justamente isso. Você só vai precisar de um cabo e uma
plaquinha montada com poucos componentes (LEDs e resistores). Construíndo um cabo para a porta paralela do MSX Acredito que quem conhece o MSX sabe que aqui no Brasil o Hotbit da Sharp seguiu o padrão estabelecido lá fora, mas o Expert da Gradiente não (estou falando da parte física da porta paralela ok). De qualquer maneira, prevendo que alguns podem não conhecer, coloquei algumas informações importantes logo abaixo:
Note que os conectores na saída de cada máquina é diferente, e sendo assim você precisará de um cabo especifico para cada uma delas. E hoje eles são raros e bem caros. Por isso optei por montar o meu. Precisei apenas de um pedaço de cabo flat com 15 vias, um conector Centronics 14 vias macho e outro Centronic 36 vias macho. Se o seu MSX é um Expert Gradiente você vai precisar de um cabo flat com um número maior de vias. O ideal é que ele tenha o mesmo número de vias do conector IDC presente na traseira do seu Expert. Ai é só montar o cabo respeitando a "tabela" com a pinagem da porta LPT do seu MSX (acima) e a tabela mais abaixo: Pinagem na para o conector Centronics 36 vias macho
As minhas máquinas atuais são um Hotbit Sharp Branco (MSX1) e também um Panasonic A1-WSX (MSX2+). E para ambos os casos o conector é o mesmo. Abaixo uma imagem do meu cabo junto com uma das revistas Clube MSX! Revista fantática! Clique aqui para saber mais a respeito! Obs.: O conector Centronics 14 vias macho é bastante díficil de ser encontrado. Eu comprei o mesmo via eBay. Tenha cuidado para não confundir esse conector com o "mini Centronics" utilizado no padrão SCSI(esse último não serve!!!)Preparando uma pequena placa de testes A placa que você pode usar nessa experiência é bem fácil de se montar e eu sequer desenhei um circuito para a mesma no Eagle CAD. Simplesmente desenhei a mesma em meu caderno de anotações (sim eu uso isso, afinal sou velho!!! rsrsrsr) e em seguida a montei. Veja a imagem abaixo e se precisar clique na mesma para ampliar e obter as informações necessárias. Eu fiz a minha montagem
usando uma placa padrão. Os resistores são de 390R e os LEDs redondos
de 5mm difusos. Não use aqui LEDs de alto-brilho, LEDs azuis ou outros.
Como não existe um "buffer" a corrente sobre cada LED aceso é retirada
diretamente da porta LPT do MSX. Os "números" presentes no lado
esquerdo da imagem são do conector Centronics 36 vias fêmea que foi
montado na placa.
Claro que você pode, se quiser, montar um cabo que vai da saída do seu MSX direto para a placa (para quem possui um Expert Gradiente essa parece ser a solução mais barata e simples). Tudo é possível. Apenas tenha cuidado para não ligar nada invertido, evitando queimar seu lindo e raro MSX (é em 2020 eles agora são exatamente isso, raros!!!) Antes de seguir em frente, que tal um pouco de teoria?!?! A prática sem a teoria fica sem base! Então vamos entender um pouco sobre a lógica envolvida na porta LPT do MSX. A primeira coisa a "aprender" é que tudo no MSX é endereçado, assim como em qualquer outro computador. Sem um endereço, você não se comunica!!! A porta paralela do MSX está nos endereços de I/O 90H e 91H. Em 90H temos no bit 1 a leitura do Busy ou Printer Read e no bit 0 temos a escrita do Strobe. Veja abaixo:
Já no endereço de I/O 91H temos os dados que podem ser acessados individualmente. Veja abaixo:
Assim, usando uma simples lógica podemos controlar através de um programa escrito em BASIC, por exemplo, os bits da porta LPT do MSX. Um programa de exemplo - controle das "saídas" Abaixo mostro um pequeno programa que fiz em BASIC e que usei em meus primeiros testes. Esse programa testa apenas as "saídas" ok. 5 REM ******************************** 10 CLS:PRINT "PROGRAMA DE TESTE PARA LPT" 20 PRINT "MARCIO JOSE SOARES" 30 PRINT "14/06/2019" 35 REM ******************************* 40 PRINT "ENVIANDO DADOS:" 50 I=&H1:J=&H2:OUT &H91,0: OUT &H90,0 55 M=0 60 GOSUB 170 70 GOSUB 220 80 I=I*J 90 IF I<=&H80 THEN GOTO 60 100 I=I/2:REM APENAS PARA EVITAR 2 128 110 I=I/J 120 GOSUB 170 130 GOSUB 220 140 IF I=1 THEN GOTO 270 ELSE 110 150 REM ****************************** 160 REM SUBROTINA DE TEMPORIZACAO 170 FOR K=0 TO 10:FOR L=0 TO 30 180 NEXT L: NEXT K 190 RETURN 200 REM ****************************** 210 REM SUBROTINA PARA ENVIO DE DADOS 220 PRINT HEX$(I);"H" 230 M=M XOR 1:OUT &H90,M:OUT &H91,I 240 RETURN 250 REM ****************************** 260 REM FIM DO PROGRAMA 270 PRINT "FIM" 280 GOSUB 170:OUT &H90,0:OUT &H91,0 Um outro exemplo - controle da "entrada" Abaixo segue um outro programa que usei para testar o pino Busy (entrada da LPT do MSX). 10 '**********************************
20 'TESTE ENTRADA BUSY DA LPT 30 'BY MARCIO JOSE SOARES - ARNE 40 '20/11/2019 50 '********************************** 55 KEY OFF: CLS 60 A=INP(&H90) 70 A$="00000000"+BIN$(A AND &B00000010) 80 PRINT RIGHT$(A$,8) 90 GOTO 60 Um exemplo em Assembly Abaixo um pequeno programa em Assembly que permite testar também as saídas, usando a mesma plaquinha descrita neste artigo: ;------------------------------------------------------------------------------- ; Project: lpt_t1.zdsp ; Main File: lpt_t1.asm ; Date: 12/07/2019 16:09:46 ; ; Created with zDevStudio - Z80 Development Studio. ; Eng. Marcio Jose Soares ; Faz um vai e vem via LPT usando linguagem ASM - compilador PASMO v0.53 ;------------------------------------------------------------------------------- org 0C100H ;endereco inicial para o programa ;------------------------------------------------------------------------------- ; Declara enderecos das rotinas do MSX CHPUT: equ 00A2H ;rotina que permite escrever na tela LPTOUT: equ 00A5H ;rotina que permite enviar um char para LPT LPTDT: equ 0091H ;endereco para out na linha de dados para LPT LPTST: equ 0090H ;endereco do strob na linha de dados para LPT STROBE: equ 0001H ;bit para ativar o STROB - bit0 ;------------------------------------------------------------------------------- ; Declara constantes CR: equ 0DH ;ENTER LF: equ 0AH ;Line Feed valinit: equ 01H ;valor inicial a ser inserido na LPT valend: equ 80H ;valor de retorno asciizero equ 30H ;valor ASCII para zero ascii7 equ 37H ;valor ASCII para 7 ;------------------------------------------------------------------------------- ; Declara espaco para vars valor DB 0 ;vars myout DB 0 myxor DB 0 ;------------------------------------------------------------------------------- ; Subrotina principal ld hl,myxor ;carrega endereço em hl ld a, 00H ld (hl),a ;guarda zero em myxor ld hl,msgini ;carrega mensagem /inicial call wrmsg ;escreve mensagem inicial ld hl,msgCRLF ;carrega CR/LF call wrmsg ;escreve ld hl,valor ;carrega HL com endereco da pos valor ld a, asciizero ;carrega valor em a ld (hl),a ;carrega posicao HL com a ld hl,myout ;carrega HL com endereco myout ld a, valinit ;carrega valor ld (hl),a ;carrega posicao de memoria com a ld hl,msgsend ;carrega msg enviando call wrmsg ;escreve call giraEsq ;gira valores a esquerda e envia para LPT ld hl,valor ;carrega HL com endereco da pos valor ld a, ascii7 ;carrega valor em a ld (hl),a ;carrega posicao HL com a ld hl,myout ;carrega HL com endereco myout ld a, valend ;carrega valor ld (hl),a ;carrega posicao de memoria com a ld hl,msgCRLF ;carrega CR/LF call wrmsg ;escreve ld hl,msgsend ;carrega msg enviando call wrmsg ;escreve call giraDir ;gira valores a direita e envia para LPT ret ;retorna para o BASIC ;------------------------------------------------------------------------------- ; Subrotina Gira valores a esquerda e envia para LPT giraEsq: call sndVDLPT ;envia dados para vÃÂdeo e LPT ld hl,valor ;carrega endereco da var ld a,(hl) ;pega conteudo inc a ;incrementa ld (hl),a ;guarda ld hl,myout ;carrega endereco da var ld a,(hl) ;pega conteudo rla ;gira acumulador a esquerda ld (hl),a ;guarda cp 00H ;compara com zero jr nz, giraEsq ;desvia se resultado nao for zero ret ;retorna para subrotina inicial ;------------------------------------------------------------------------------- ; Subrotina Gira valores a direita e envia para LPT giraDir: call sndVDLPT ;envia dados para vÃÂdeo e LPT ld hl,valor ;carrega endereco da var ld a,(hl) ;pega conteudo dec a ;incrementa ld (hl),a ;guarda ld hl,myout ;carrega endereco da var ld a,(hl) ;pega conteudo rra ;gira acumulador a direita ld (hl),a ;guarda cp 00H ;compara com zero jr nz, giraDir ;desvia se resultado nao for zero ret ;retorna para subrotina inicial ;------------------------------------------------------------------------------- ; Subrotina para enviar dados para tela e impressora sndVDLPT: ld hl,valor ;carrega endereco da var em hl ld a,(hl) ;pega o conteudo call CHPUT ;envia char ld hl,myout ;carrega endereco da var ld a,(hl) ;pega o conteudo out (LPTDT),a ;envia dados para LPT via OUT direto ld hl,myxor ;carrega endereço ld a,(hl) ;pega o conteúdo de myxor xor STROBE ;faz xor com valor guardado out (LPTST),a ;envia dado para pino de STROBE ld hl,myxor ;guarda resultado para próximo xor ld (hl),a ;valor agora está salvo call _500ms ;aguarda ret ;------------------------------------------------------------------------------- ; Subrotina para aguardar aproximadamente 50ms ; ; T = 1/F => T = 1/3,57MHz => T = 0,280us ; DEC consome 4 ciclos ; JRNZ consome 12 ciclos ; DEC + JRNZ consomente juntos 16 ciclos ; ; 175 x 16 x 0,280us = 784us (DEC L + JR NZ loop1_1) ; 50 x 16 x 0,280us = 224us (DEC H + JR NZ loop1) ; ; (784us + 224us) x 50 = 50.4ms ; _50ms: ld h,032H ;carrega H com 50 loop1: ld l,0AFH ;carrega L com 175 loop1_1: dec l ;decrementa L jr nz, loop1_1 ;continua ate ser zero dec h ;decrementa h jr nz, loop1 ;continua ate H ser zero ret ;retorna para subrotina de chamada ;------------------------------------------------------------------------------- ; Subrotina para aguardar aproximadamente 500ms ; ; T = 1/F => T = 1/3,57MHz => T = 0,280us ; DEC consome 4 ciclos ; JRNZ consome 12 ciclos ; DEC + JRNZ consomente juntos 16 ciclos ; ; 165 x 16 x 0,280us = 739,20us (DEC L + JR NZ loop2_3) ; 50 x 16 x 0,280us = 224us (DEC H + JR NZ loop_2_2) ; 10 x 16 x 0,280us = 44,8us (DEC E + JR NZ loop2) ; ; (739,2us + 224us + 44,8us) x 500 ~= 504ms ; _500ms: ld e,0AH ;carregqa e com 10 loop2: ld h,032H ;carrega h com 50 loop2_2: ld l,0A5H ;carrega l com 165 loop2_3: dec l ;decrementa l jr nz, loop2_3 ;continua ate ser zero dec h ;decrementa h jr nz, loop2_2 ;recarrega l e faz até h ser zero dec e ;decrementa e jr nz, loop2 ret ;retorna para subrotina de chamada ;------------------------------------------------------------------------------- ; Subrotina para escrever na tela wrmsg: ld a,(hl) ;carrega no acumulador o conteudo and a ;faz um AND ret z ;retorna se flag z estiver setado, senao pula call CHPUT ;chama rotina para escrever char inc hl ;incrementa HL (ponteiro) jr wrmsg ;continua ate o final da string ;------------------------------------------------------------------------------- ; Mensagens a serem escritas na tela msgini: db 'TESTE CONTROLE PORTA PARALELA EM ASM!' ;texto para primeira linha db CR, LF ;muda linha db 'by ARNE ;) - compilador PASMO v0.53' ;texto para segunda linha db 0 ;fim da string! msgsend: db 'ENVIANDO -> ' db 0 msgCRLF: db CR db LF db 0 ;------------------------------------------------------------------------------- ; Fim do programa end Conclusão Muitas são as possibilidades para o uso da porta paralela do MSX com a adição de circuitos relativamente simples. É possível, por exemplo, controlar diversos tipos de cargas desde que tomadas as devidas providências para que os pinos sejam "protegidos" e recebam "drivers" de corrente adequados. Espero, de alguma forma, ter contribuído com o seu aprendizado sobre o MSX! Até a proxima!!! |
Copyright deste conteúdo reservado para Márcio José Soares e protegido pela Lei de Direitos Autorais LEI N° 9.610, de 19 de Fevereiro de 1998. É estritamente proibida a reprodução total ou parcial do conteúdo desta página em outros pontos da internet, livros ou outros tipos de publicações comerciais ou não, sem a prévia autorização por escrito do autor. |