commit 816f64d0c97e9cb05a01be6bd5cfa63dd23064b7
parent e43c0ba9a8c944f2d62ec4358a198f8be363efd5
Author: Gerd Beuster <gerd@frombelow.net>
Date: Sun, 3 Jan 2021 13:46:09 +0100
Worked on interrupt handling
Diffstat:
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