Como codificar E / S bidirecional para MC6850 ACIA (680x Assembler)

Sep 01 2020

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

2 LawrenceC Sep 01 2020 at 01:00

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.

2 Raffzahn Sep 01 2020 at 01:21

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.

MartinMaly Sep 02 2020 at 14:57

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