eris2010

Documentation: http://frombelow.net/projects/eris2010/
Clone: git clone https://git.frombelow.net/eris2010.git
Log | Files | Refs | Submodules | README | LICENSE

commit 816f64d0c97e9cb05a01be6bd5cfa63dd23064b7
parent e43c0ba9a8c944f2d62ec4358a198f8be363efd5
Author: Gerd Beuster <gerd@frombelow.net>
Date:   Sun,  3 Jan 2021 13:46:09 +0100

Worked on interrupt handling

Diffstat:
Mdoc/Documentation.txt | 15+++++++--------
Mroms/Makefile.common | 4++--
Mroms/boot/boot.asm | 24++++++++++++------------
Mroms/boot/boot.inc | 9+++------
Msw/interrupts/interrupts.asm | 107+++++++++++++++++++++++++++++++++----------------------------------------------
5 files changed, 69 insertions(+), 90 deletions(-)

diff --git a/doc/Documentation.txt b/doc/Documentation.txt @@ -30,8 +30,13 @@ AFT16V8B - which mainly provides the bus logic - as an inverter. ** Memory Map -Lowest 32K are RAM, highest 8K are ROM. ACAI and VIA are in -between. See hw/bus_logic/BUS_LOGIC.PLD for details. +Lowest 32K are RAM, highest 8K are ROM. Up to 4 I/O devices (ACAI or +VIA) can be accessed at addresses below the ROM. One ACAI and one VIA +are required to operate the computer, because they provide a serial +interface (ACIA) and an interface to the SD card reader (VIA). If a +third I/O device is connected, it can be selected by setting i3 to +high. If a fourth I/O device is connected, i4 distinguishes between +device 3 and 4. See hw/bus_logic/BUS_LOGIC.PLD for details. ** Booting @@ -178,16 +183,10 @@ replaced by a NE555 configured as a monostable multivibrator. ** TODOs -*** Wire interrupt lines - -- To VIA(s) and ACIA(s) -- Add reset button - *** Reset Logic - Add switch or jumper to enable/disable connection between DTR and reset - Change indicator LED to off-on-reset -- Reduce delay in NE555 reset circuit *** Write library functions diff --git a/roms/Makefile.common b/roms/Makefile.common @@ -1,6 +1,6 @@ CFLAGS=-C --line-numbers --tab-size=1 -Wall -c -b -LABELS=--labels-root=export -l $(TARGET).l \ +LABELS=--labels-root=os -l $(TARGET).l \ --labels-root=io -l io.l \ --labels-root=ds -l ds.l \ --labels-root=sd -l sd.l \ @@ -8,7 +8,7 @@ LABELS=--labels-root=export -l $(TARGET).l \ --labels-root=spi -l spi.l \ --labels-root=term -l term.l -LABELS_SYMON=--labels-root=export -l $(TARGET)_symon.l \ +LABELS_SYMON=--labels-root=os -l $(TARGET)_symon.l \ --labels-root=io -l io_symon.l \ --labels-root=ds -l ds_symon.l \ --labels-root=sd -l sd_symon.l \ diff --git a/roms/boot/boot.asm b/roms/boot/boot.asm @@ -18,7 +18,7 @@ .dsection rom .cerror * > $ffff, "ROM exhausted" -export .namespace +os .namespace ram_end = $7fff .endn @@ -27,9 +27,9 @@ ram_end = $7fff ;;; able to handle interrupts in RAM, the ROM isr routines jump to the ;;; addresses given here. After a reset, this RAM address is set to ;;; default_irq_handler. -.namespace export -nmi_vector = export.ram_end - $3 -irq_vector = export.ram_end - $1 +.namespace os +nmi_vector = os.ram_end - $3 +irq_vector = os.ram_end - $1 .endn .section rom @@ -42,12 +42,12 @@ irq_vector = export.ram_end - $1 boot: .block sei - #mem.STORE_WORD export.default_irq_handler, export.irq_vector - #mem.STORE_WORD export.default_nmi_handler, export.nmi_vector + #mem.STORE_WORD os.default_irq_handler, os.irq_vector + #mem.STORE_WORD os.default_nmi_handler, os.nmi_vector cld cli jsr io.init_acia - #ds.INIT_STACK export.ram_end-$206+$1 ;Minimal stack size to access SD card + #ds.INIT_STACK os.ram_end-$206+$1 ;Minimal stack size to access SD card jsr spi.init_via jsr check_for_program_download bcs no_program_download @@ -149,7 +149,7 @@ transmit_block: .include "sd.asm" .include "term.asm" -.namespace export +.namespace os .section zero_page rom_zero_page_end: .send zero_page @@ -157,7 +157,7 @@ rom_zero_page_end: ;;; Default IRQ handler. Unless the user program changes ;;; the irq_vector, IRQs are handled here. -.namespace export +.namespace os default_irq_handler: .endn rti @@ -165,11 +165,11 @@ default_irq_handler: derefer_ram_irq: ;; Jump to the address given in the IRQ vector ;; in RAM - jmp (export.irq_vector) + jmp (os.irq_vector) ;;; Default NMI handler. Unless the user program changes ;;; the nmi_vector, NMIs are handled here. -.namespace export +.namespace os default_nmi_handler: .endn rti @@ -177,7 +177,7 @@ default_nmi_handler: derefer_ram_nmi: ;; Jump to the address given in the NMI vector ;; in RAM - jmp (export.nmi_vector) + jmp (os.nmi_vector) default_program: ;; .include "../../sw/10print/10print.asm" diff --git a/roms/boot/boot.inc b/roms/boot/boot.inc @@ -1,10 +1,7 @@ ;;; -*- asm -*- ;;; This file may be included from boot.asm or from -;;; some userland program. If included from a -;;; boot.asm, external symbols are defined in -;;; namespace export. We define this namespace here -;;; in case this file is included from a userland program. +;;; some userland program. ;;; We use the definition of CLOCK_SPPED in boot.asm to ;;; check if we are compiling in the context of a userland ;;; program. @@ -19,7 +16,7 @@ filename_addition = "" start_address = $0200 .endif - export .namespace + os .namespace .include "boot" .. filename_addition .. ".l" .endn io .namespace @@ -43,7 +40,7 @@ BOOT_EMBEDDED = false ;; Set start addresses for program and ;; zero page variables - * = export.rom_zero_page_end + * = os.rom_zero_page_end .dsection zero_page * = start_address .else diff --git a/sw/interrupts/interrupts.asm b/sw/interrupts/interrupts.asm @@ -1,99 +1,80 @@ -.if SYMON - .include "boot_symon.l" -.else - .include "boot.l" -.endif - .include "boot_macros.inc" - * = $0300 + .include "boot.inc" - flag = $30 - tmp = $31 + .dsection code + +.section zero_page +interrupt_counter: .byte ? +.send zero_page + +.section code init: ;; jmp transmitter_interrupt ;; jmp receiver_interrupt - jmp manual_nmi_irq + jsr manual_nmi_irq + jmp receiver_interrupt manual_nmi_irq: ;; Expects NMI or IRQ triggered manually. ;; Prints a message when an interrupt is received .block - jsr init_acia - #STORE_WORD isr_print_message_irq, irq_vector - #STORE_WORD isr_print_message_nmi, nmi_vector - jsr getc - #PRINTSNL 'Please trigger an interrupt.' + jsr io.init_acia + #mem.STORE_WORD isr_print_message_irq, os.irq_vector + #mem.STORE_WORD isr_print_message_nmi, os.nmi_vector + jsr io.getc + lda #$00 + sta interrupt_counter + #io.PRINTSNL 'Please trigger an NMI.' wait: - jmp wait + lda interrupt_counter + cmp #10 + bne wait + rts isr_print_message_irq: - #PRINTSNL 'IRQ triggered.' + #io.PRINTSNL 'IRQ triggered.' rti isr_print_message_nmi: - #PRINTSNL 'NMI triggered.' + #io.PRINTS 'NMI triggered (' + inc interrupt_counter + lda interrupt_counter + jsr io.putd + #io.PRINTSNL ')' rti .bend -;;; Looks like interrupt controlled tranmission is buggy. -;;; The only way to transmit seems to be a delay loop. -transmitter_interrupt: - .block - jsr init_acia - #STORE_WORD isr_raise_flag, irq_vector - #PRINTSNL 'Push key to start.' - jsr getc -loop: - ;; Transmitter interrupt on - lda #%11000111 - sta acia_cmd_reg - ;; Send a byte - lda flag - jsr putc_irq - ;; Transmitter interrupt off - lda #%11001011 - sta acia_cmd_reg - jsr wait - jmp loop - -wait: - ldx #$7f -wait_loop: - dex - bne wait_loop - rts - .bend - receiver_interrupt: .block - jsr init_acia - #STORE_WORD isr_raise_flag, irq_vector + #io.PRINTSNL "Testing ACIA receiver interrupt." + jsr io.init_acia + lda #$00 + sta interrupt_counter + #mem.STORE_WORD isr_inc_interrupt_counter, os.irq_vector ;; Receiver interrupt on - lda acia_cmd_reg + lda io.acia_cmd_reg lda #%11001001 - sta acia_cmd_reg - #PRINTSNL "Start typing ..." + sta io.acia_cmd_reg + #io.PRINTSNL "Start typing ..." loop: - jsr getc - lda flag - jsr puth - #PRINTNL + wa jmp loop .bend -isr_raise_flag: - lda flag +isr_inc_interrupt_counter: + lda io.acia_status_reg + lda interrupt_counter inc a - sta flag - ldx #$00 ; Indicate end of transmission - lda acia_status_reg + sta interrupt_counter + jsr io.puth + #io.PRINTNL rti putc_irq: .block ldx #$ff - sta acia_data_reg + sta io.acia_data_reg wait_for_transmission_finish: ;; Interrupt upon successful transmission ;; sets X to $00 @@ -101,3 +82,5 @@ wait_for_transmission_finish: bne wait_for_transmission_finish rts .bend + +.send code