From 56ae2c7b25157e44c50ab982236fee8bbcca0463 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Fri, 20 Nov 2020 18:11:22 +0100 Subject: some more IRQ work --- LINKS | 10 +- README | 17 ++- roms/7seg_counter_irq_timer.asm | 2 +- roms/7seg_counter_irq_timer_smart_update.asm | 16 ++- roms/7seg_counter_irq_timer_start_stop.asm | 170 +++++++++++++++++++++++++++ roms/README | 1 + 6 files changed, 205 insertions(+), 11 deletions(-) create mode 100644 roms/7seg_counter_irq_timer_start_stop.asm diff --git a/LINKS b/LINKS index 9addc00..7a99468 100644 --- a/LINKS +++ b/LINKS @@ -37,10 +37,11 @@ https://www.jameco.com/z/6551-Major-Brands-IC-6551-Asynchronous-Communication-In assemblers for 6502: http://sun.hasenbraten.de/vasm/ -emulators for ben6502: +emulators for 6502: https://github.com/alimansfield2016/ATM65C02_EMU, nice idea, c++ code quite bad https://github.com/alimansfield2016/ATM65C02_EMU.git, sadly in Javascript https://github.com/chanmix51/soft65c02, sadly in rust +https://sbc.rictor.org/simulator.html other/todo: https://news.ycombinator.com/item?id=22077052 @@ -82,6 +83,8 @@ https://www.heiko-pruessing.de/projects/hbc65/ https://c74project.com/ (a full 6502 in 74xx logic gates on PCB) https://github.com/Klaus2m5/6502_65C02_functional_tests (format tests and verification) https://hgj.hu/live-migrating-a-virtual-machine-with-libvirt-without-a-shared-storage/ +https://hackaday.io/project/174128/logs +https://sbc.rictor.org/ delay/timers: https://gist.github.com/superjamie/fd80fabadf39199c97de400213f614e9 @@ -89,6 +92,7 @@ http://6502org.wikidot.com/software-delay http://wilsonminesco.com/6502primer/PgmTips.html http://6502.org/source/general/clockfreq.htm http://wilsonminesco.com/6502interrupts/ (use VIA and NMI to produce a 10ms timer) +https://apprize.best/programming/65816/16.html software archives: http://6502.org/source/ @@ -101,6 +105,7 @@ https://damian.pecke.tt/2015/04/06/turning-the-arduino-uno-into-an-apple-ii.html 6502 emulators: https://github.com/gianlucag/mos6502.git +https://github.com/skilldrick/6502js other emulators: https://github.com/pdewacht/oberon-risc-emu (RISC-5 Wirth Emulator, as inspiration) @@ -108,3 +113,6 @@ https://github.com/pdewacht/oberon-risc-emu (RISC-5 Wirth Emulator, as inspirati video: https://youtu.be/0QleiL-WdyM https://en.wikipedia.org/wiki/Texas_Instruments_TMS9918 + +SPI, serial, XModem: +https://coronax.wordpress.com/tag/6502/page/2/ diff --git a/README b/README index 25dc420..d208914 100644 --- a/README +++ b/README @@ -83,13 +83,24 @@ VGA kit arrived, some weird issues with payment (UPS, as usual) 17.11.2020: new RAM, same problems -VCC on counters stabilize the circuit on slow clock +resistors on VCC stabilize the circuit on slow clock. 18.11.2020: playing with some cli, sei, having a copy of the counter and optimizing display (refresh on change only) X and Y are not stored in the interrupt routine, why this is -extremely bad, is obious! :-) +extremely bad, is obvious! :-) + +19.11.2020: +distinguish IRQ from timer1 and CA1 source, button should stop +and restart the counter. + +20.11.2020: +fixed wrong IFR address in interrupt handler +some problems in IER and IFR mismatch (though I don't enable +certain interrupts, I get a match in the status register). +Button press trigers two events (on press and release) effectively +switching off/on the counter. commands -------- @@ -102,5 +113,5 @@ minipro -r x -p AT28C16@DIP24 cmp x rom.bin # -wdc02 for extensions -vasm6502_oldstyle -wdc02 -x -wfail -chklabels -dotdir -o rom.bin -Fbin rom.asm +vasm6502_oldstyle -x -wfail -chklabels -dotdir -o rom.bin -Fbin rom.asm diff --git a/roms/7seg_counter_irq_timer.asm b/roms/7seg_counter_irq_timer.asm index 8326762..b031886 100644 --- a/roms/7seg_counter_irq_timer.asm +++ b/roms/7seg_counter_irq_timer.asm @@ -4,8 +4,8 @@ T1LCL = $6004 T1LCH = $6005 ACR = $600b PCR = $600c +IFR = $600d IER = $600e -IFR = $600f SER = %00000001 RCLK = %00000010 diff --git a/roms/7seg_counter_irq_timer_smart_update.asm b/roms/7seg_counter_irq_timer_smart_update.asm index 2b009de..e18bfc7 100644 --- a/roms/7seg_counter_irq_timer_smart_update.asm +++ b/roms/7seg_counter_irq_timer_smart_update.asm @@ -4,8 +4,8 @@ T1LCL = $6004 T1LCH = $6005 ACR = $600b PCR = $600c +IFR = $600d IER = $600e -IFR = $600f SER = %00000001 RCLK = %00000010 @@ -106,8 +106,10 @@ nmi: irq: pha - phx - phy + txa + pha + tya + pha bit T1LCL ; clear timer1 interrupt bit PORTA ; clear CA1 interrupt dec TICKS @@ -115,9 +117,11 @@ irq: lda #INTERVAL sta TICKS inc CURRENT ; increment internal counter -irq_done: - ply - plx +irq_done: + pla + tay + pla + tax pla cli rti diff --git a/roms/7seg_counter_irq_timer_start_stop.asm b/roms/7seg_counter_irq_timer_start_stop.asm new file mode 100644 index 0000000..3c7aed5 --- /dev/null +++ b/roms/7seg_counter_irq_timer_start_stop.asm @@ -0,0 +1,170 @@ +PORTA = $6001 +DDRA = $6003 +T1LCL = $6004 +T1LCH = $6005 +ACR = $600b +PCR = $600c +IFR = $600d +IER = $600e + +SER = %00000001 +RCLK = %00000010 +SRCLK = %00000100 + +INTERVAL = 33 ; increase counter 3 times per scond +WAIT_INTERVAL = 99 ; wait one second on button press + +CURRENT = $0 ; current counter +VISIBLE = $1 ; visible counter (as last printed to the 7-segment display) +TICKS = $2 ; internal ticks counter (on overflow increment counter) +RUNNING = $3 ; if counter is running or stopped +COUNTER = $4 ; counter, increment on button press, show only shortly when button pressed + + .org #$f800 + +reset: + sei ; disallow interrupts during initialization + + ldx #$FF ; initialize call stack to $1FF + txs + + lda #%11000010 ; enable CA1 and timer1 interrupts + sta IER + lda #$0 ; negative edge triggering + sta PCR + + lda ACR + and #$7F + ora #%01000000 ; setup timer for free running timer1, no PB7 + sta ACR + + lda #%00000111 ; set output on 7seg control pins of PORTA + sta DDRA + + lda #$0 ; initialize 8-bit counter and tick counter + sta CURRENT + lda #$FF ; the visible counter is different at init, so we force + sta VISIBLE ; the drawing of the initial value + lda #INTERVAL + sta TICKS + lda #$FF + sta RUNNING + + lda #$0 ; initialize button press counter + sta COUNTER + + lda #$0F ; initialize counter of VIA timer1 ($270f = 9999 at 1MHz) + sta T1LCL + lda #$27 + sta T1LCH + + cli ; allow interrupts now + +mainloop: ; main loop, just print value of counter + sei + lda CURRENT + cmp VISIBLE + cli + beq mainloop + jsr print7seg ; update value + sei + lda CURRENT + sta VISIBLE + cli + jmp mainloop + +print7seg: + ldy #$8 ; 8 bits to shift +loop7seg: + rol a + bcc zerobit ; C=0, bang a zero to SER +onebit: + ldx #(SER) ; C=1, bang a one to SER + stx PORTA + ldx #(SER | SRCLK) + stx PORTA + ldx #(SER) + stx PORTA + jmp next +zerobit: + ldx #$0 ; C=0, bang a zero to SER + stx PORTA + ldx #SRCLK + stx PORTA + ldx #$0 + stx PORTA + jmp next +next: + dey + bne loop7seg + rol a ; restore A register +output: + ldx #0 ; bang RCLK to store output in latch + stx PORTA + ldx #RCLK + stx PORTA + ldx #0 + stx PORTA + rts + +nmi: + rti + +irq: + pha ; save state + txa + pha + tya + pha + lda IFR ; check interrupt register of VIA + bpl irq_done ; bit 7 set? if not, not an interrupt of the VIA + asl ; bit 6 in sign (timer1) + bmi timer1 + asl ; bit 5 in sign (timer2, unused) + asl ; bit 4 in sign (cb1, unused) + asl ; bit 3 in sign (cb2, unused) + asl ; bit 2 in sign (shift, unused) + asl ; bit 1 in sign (CA1) + bmi ca1 + asl ; bit 0 in sign (CA2, unused) + jmp irq_done ; no more interrupt to handle from VIA + +timer1: + bit T1LCL ; clear timer1 interrupt + lda #$FF + cmp RUNNING + bne irq_done + +tick: + dec TICKS + bne irq_done + lda #INTERVAL + sta TICKS + inc CURRENT ; increment internal counter + jmp irq_done + +ca1: + lda RUNNING ; toggle running flag + eor #$FF + sta RUNNING + inc COUNTER + lda COUNTER + sta CURRENT + lda #WAIT_INTERVAL + sta TICKS + bit PORTA ; clear CA1 interrupt (button press) + jmp irq_done + +irq_done: + pla + tay + pla + tax + pla + cli + rti + + .org #$fffa + .word nmi + .word reset + .word irq diff --git a/roms/README b/roms/README index d19afae..9e2c72c 100644 --- a/roms/README +++ b/roms/README @@ -23,3 +23,4 @@ wait.hex - test 65C02 WAI special opcode 7seg_counter_reset_on_irq.asm - counter, reset on IRQ (usable at 1 KHz) 7seg_counter_reset_on_irq_delay.asm - counter, reset on IRQ (usable at 1 MHz) 7seg_counter_irq_timer_smart_update.asm - counter, working version, update when needed, proper interrupt handling +7seg_counter_irq_timer_start_stop.asm - counter, allow stopping/starting, distinguish kind of interrupts -- cgit v1.2.3-54-g00ecf