Asignación de E / S
"Algunos esquemas de asignación de memoria" es prácticamente la definición de E / S asignada en memoria.
Pruebe el truco de Commodore 64: los periféricos comparten el espacio de memoria con la RAM, y cualquier dirección que no sea tomada por un periférico va a la RAM.
O el truco de Intel x86: I / O obtiene su propio espacio de direcciones separado de la RAM. Esto hace que el uso de punteros con periféricos sea mucho más difícil.
Los periféricos en general tienen solo los pines de dirección para dirigir sus registros, un pin de selección de chip (CS) que dice cuándo está seleccionado, y un pin de Lectura / Escritura o un par de pines de Habilitar Lectura y Habilitar de Escritura.
Framebuffer
La forma más sencilla de generar una señal de video es hacer un circuito que lea direcciones consecutivas de la RAM y las convierta en una señal de video. La forma en que genera la señal depende de la señal que desea generar (NTSC, CGA, VGA, LVDS, etc.) Si ejecuta la CPU lo suficientemente lento, podría tener la RAM de acceso a la CPU en la mitad de un ciclo de reloj y luego deje que el framebuffer lea la RAM en el otro semiciclo (el Commodore 64 hizo esto). Alternativamente, si su bus de memoria maneja los estados de espera, puede darle a la memoria RAM acceso de prioridad de framebuffer.
La ventaja de este framebuffer es que es fácil de implementar y escribir. La desventaja es que toma una gran cantidad de RAM y empuja la generación de texto en la CPU (pero también te permite hacer fuentes de ancho y altura variables).
Lo triste es que estarás bastante solo aquí; el mercado para este tipo de chip de video de bajo nivel es prácticamente inexistente en estos días. Sin embargo, recuerde que Apple II hizo su generación de video en componentes discretos sin un chip dedicado, por lo que usted también puede. ^ _-
Interrupciones
Las interrupciones no deberían ser tan difíciles de implementar: si se controla una línea de interrupción y las interrupciones están habilitadas globalmente, y esa interrupción en particular no está deshabilitada, luego empuje la PC hacia la pila (al igual que para una llamada de subrutina), y, finalmente, cargue un nuevo valor de PC desde una dirección dependiendo del número de interrupción (el método de la tabla vectorial), o simplemente configure el PC en un valor fijo dependiendo del número de interrupción, esperando un GOTO en esa dirección para obtener el procesador donde lo necesita para ir (el método de la tabla de salto).
Interfaz de teclado
Stevenvh publicó su respuesta cuando estaba casi a la mitad con la mía, así que secundaré la recomendación de usar la interfaz PS / 2. Una cosa interesante a tener en cuenta es que la interfaz PS / 2 puede intercambiarse en caliente y puede detectar automáticamente si el teclado o el mouse están conectados. Estas características nunca llegaron a las placas base porque nadie quería pagar el $$$ $$$ extra o reescribirlo. sus controladores para admitirlo, pero lo he hecho en un FPGA, así que tú también puedes.
El truco, sin embargo, es que la interfaz PS / 2 es bidireccional, por lo que probablemente querrás usar un diseño de puerto serie basado en interrupciones para interactuar con él. Puedes usar chips llamados FIFOs (Cypress hace muchos) para aflojar los requisitos de latencia; necesitarás uno que vaya en cada dirección.