Como codificar E / S bidirecional para MC6850 ACIA (680x Assembler)
Preciso de uma lista de códigos para 6802 (ou 6809) para inicializar e definir o 6850 ACIA no modo E / S serial bidirecional.
Tenho duas placas vintage e preciso fazer com que as portas funcionem e se conectem antes de fazer qualquer coisa com elas.
O Motorola App Note relevante está faltando em minha coleção (AN-754) e tudo o mais que eu tenho aponta para isso.
A maioria das referências fala sobre os registros, mas não como pesquisar / monitorar ou controlar o fluxo ... código
Respostas
inicialize e defina o 6850 ACIA no modo E / S serial bidirecional.
Pesquise "6850 ACIA" no Google e veja o pino. Há uma linha "Tx Data" e uma linha "Rx Data" no chip. Já é bidirecional.
Se você quiser unidirecional, você não precisa fazer nenhuma destas coisas:
Ao configurar o chip, você deve colocar 1 no bit 7 do Registro de controle para "Habilitar interrupção de recepção". Você precisa de uma rotina de IRQ que verificará o bit 0 do Registro de status para garantir que foi isso que causou o IRQ e, em seguida, obterá os dados do registro Receber dados e os colocará em um buffer.
Suponho que se você escrever um byte no Transmit Data Register, o ACIA começará a enviá-lo e gerar um IRQ quando terminar. Sua rotina de IRQ precisa verificar o bit 1 do Registro de status para garantir que é o que causou o IRQ e, em seguida, colocar novos dados de um buffer no Registro de transmissão de dados.
Parece que você tem que fazer um "Master Reset" no chip escrevendo 1s nos bits "Counter Divide" e então escrever 00, 10 ou 01 - sem ter certeza de qual é o valor correto para suas placas / aplicação.
mas não como pesquisar / monitorar ou controlar o fluxo ... código
Em uma CPU desse tipo, você basicamente precisa construir um pequeno sistema que alimenta / consome bytes de entrada / saída do ACIA a partir de um buffer que é preenchido separadamente usando outras rotinas. Isso é muito específico do aplicativo para fazer um código geral.
A maioria das referências fala sobre os registros,
porque isso é tudo que existe.
mas não como pesquisar / monitorar ou controlar o fluxo ... código
O polling é feito lendo o registro de status.
Para ver se os dados foram recebidos, lê-se o registro de status (Offset 0) e verifica o bit 0:
- Se definido, um caractere foi recebido, que agora pode ser lido do registro de dados (deslocamento 0).
Para ver se os dados podem ser enviados, novamente o registro de status deve ser lido, mas desta vez o bit 1 conta a história:
- Se definido, o resistor está vazio e um caractere pode ser escrito (para ser enviado).
Ou, como um código pseudo C:
while(1)
{
char status = read_status_port;
if(status & 1)
read_byte_from_ACIA();
if(status & 2)
write_byte_to_ACIA();
}
Sim, é simples assim. Claro que não posso dizer como lidar com seus buffers, detectar o fim da transmissão ou algo semelhante. este é apenas o manuseio serial. Todo o resto depende da estrutura e do objetivo do seu aplicativo ... como de costume.
E sim, é possível entrar em operação em segundo plano com interrupções e similares para operar em paralelo com algum programa e assim por diante, mas acho que isso está fora do escopo aqui.
Aqui está meu código para 6809/6850 para meu computador homebrew . Espero que ajude.
De qualquer forma, a comunicação é bidirecional "por natureza", o ACIA pode transmitir e receber dados ao mesmo tempo (mas apenas um byte de cada vez).
Você pode combinar ambas as rotinas em um "transmitir-e-ler-se-necessário" e chamá-lo com frequência ou por uma interrupção.
; serial
ACIA EQU $83fe ;base address ACIAC EQU ACIA ;control register ACIAS EQU ACIA ;status register ACIAD EQU ACIA+1 ;data register INIT: LDA #$15
STA ACIAC
ACIA_TDRE EQU 02h
ACIA_RDRF EQU 01h
; send one byte from A to serial
SEROUT:
PSHS a,b
SEROUTL:
LDB ACIAS
ANDB #ACIA_TDRE
BEQ seroutl
STA ACIAD
PULS a,b
RTS
; Wait for serial char to read
SERIN:
LDA ACIAS
ANDA #ACIA_RDRF
BEQ serin
LDA ACIAD
RTS