; ; Disk Emulator ; ; Created: 23.10.2021 16:20:20 ; Author : peter ; ; ; Excerpt: 21.01.2022 to Test Level1 Interrupt ; .listmac .dseg lv0status: .byte 1 lv1status: .byte 1 ;-------------------------------------------------------------------------- ; ; CPU Clock ; .equ CLKCTRL_FREQSEL_28M_gc = (0x0a<<2) ; 28 MHz system clock -> ok .equ CLKCTRL_FREQSEL_32M_gc = (0x0b<<2) ; 32 MHz system clock -> ok .equ F_CLK = CLKCTRL_FREQSEL_16M_gc .equ F_CPU = 16000000 .equ BAUD1 = (64 * F_CPU) / (16 * 115200) .def zero = r1 ;-------------------------------------------------------------------------- ; ; Special characters ; .equ NULL = 0 .equ CR = 015 .equ LF = 012 .equ BELL = 07 .equ BKSP = 010 .equ TAB = 011 .equ EOF = 032 .equ ESC = 033 .equ SPACE = 040 .equ DEL = 0177 .equ DELIM = 0x2f ; Directory Delimiter 0x2f = / and 0x5c = \ ;============================================================================= ; ; ; ;============================================================================= ; ; Flash Begin ; ; ; Interrupt Vector Table ; .cseg .org 0 jmp start .org PORTB_PORT_vect ; Software Interrupt Controller GO jmp go_ ; Module rlv12-v2-0.asm .org PORTE_PORT_vect ; External Level 1 Q-Bus Interrupt jmp qbus_ ; Module qbus-v2-0.asm .org INT_VECTORS_SIZE ;============================================================================= ; ; Support routines ; seroutcrlf: ldi r24, CR rcall serout ldi r24, LF serout: push r24 ; Else proceed with polled IO serout100: lds r24, USART1_STATUS sbrs r24, USART_DREIF_bp rjmp serout100 pop r24 sts USART1_TXDATAL, r24 ret serin: serin100: ; Else proceed with polled IO lds r24, USART1_STATUS sbrs r24, USART_RXCIF_bp rjmp serin100 lds r24, USART1_RXDATAL ret ;============================================================================= ; ; start: ; ; Init ; ldi r18, low(RAMEND) out CPU_SPL, r18 ldi r18, high(RAMEND) ; AVR128DA does this during RESET out CPU_SPH, r18 ; ; Set CPU Clock Frequency ; ldi r18, CPU_CCP_IOREG_gc sts CPU_CCP, r18 ldi r18, F_CLK sts CLKCTRL_OSCHFCTRLA, r18 ; ; Constants ; clr zero ;============================================================================= ; ; Port Settings ; ;----------------------------------------------------------------------------- ; ; PORT A ; .equ DMR = 1 ; DMA Request .equ DMG = 2 ; DMA Granted .equ ABO = 3 ; Abort Cycle .equ ACK = 4 ; Acknowledge Cycle .equ RTOS = 6 ; RTOS Software Interrupt .equ CLK = 7 ; CPDL Clock output #define b_DMR VPORTA_OUT, DMR #define i_DMG VPORTA_IN, DMG #define b_ABO VPORTA_OUT, ABO #define b_ACK VPORTA_OUT, ACK #define b_RTOS VPORTA_OUT, RTOS #define f_RTOS VPORTA_INTFLAGS, RTOS #define c_RTOS PORTA_PIN6CTRL #define b_CLK VPORTA_OUT, CLK sbi VPORTA_DIR, DMR cbi VPORTA_DIR, DMG sbi VPORTA_DIR, ABO sbi VPORTA_DIR, ACK sbi VPORTA_DIR, RTOS sbi VPORTA_DIR, CLK cbi b_DMR ; No DMA request sbi b_ABO cbi b_ABO ; Abort any pending DMA sbi b_ACK cbi b_ACK ; Unlock Bus sbi b_RTOS ; Set Level = High sbi f_RTOS ; Acknowledge any pending interrupt ldi r18, PORT_ISC_LEVEL_gc ; Level Sense Interrupt sts c_RTOS, r18 ; Pin Control ldi r18, CPU_CCP_IOREG_gc sts CPU_CCP, r18 ldi r18, CLKCTRL_CLKOUT_bm ; Clock Out sts CLKCTRL_MCLKCTRLA, r18 ;----------------------------------------------------------------------------- ; ; PORT B ; .equ RS0 = 0 ; Register Select 0 .equ RS1 = 1 ; Register Select 1 .equ RS2 = 2 ; Register Select 2 .equ LV0 = 4 ; LV0 Level0 -> Level1 test .equ GO = 5 ; GO Level1 -> Level0 signalling #define b_RS0 VPORTB_OUT, RS0 #define b_RS1 VPORTB_OUT, RS1 #define b_RS2 VPORTB_OUT, RS2 #define b_LV0 VPORTB_OUT, LV0 #define f_LV0 VPORTB_INTFLAGS, LV0 #define c_LV0 PORTB_PIN4CTRL #define b_GO VPORTB_OUT, GO #define f_GO VPORTB_INTFLAGS, GO #define c_GO PORTB_PIN5CTRL sbi VPORTB_DIR, RS0 sbi VPORTB_DIR, RS1 sbi VPORTB_DIR, RS2 sbi VPORTB_DIR, LV0 sbi VPORTB_DIR, GO sbi b_GO ; Set Level = High sbi f_GO ; Acknowledge any pending interrupt ldi r18, PORT_ISC_LEVEL_gc ; Level Sense Interrupt sts c_GO, r18 ; Pin Control sbi b_LV0 ; Set Level = High sbi f_LV0 ; Acknowledge any pending interrupt ldi r18, PORT_ISC_LEVEL_gc ; Level Sense Interrupt sts c_LV0, r18 ; Pin Control ;----------------------------------------------------------------------------- ; ; PORT C MVIO ; .equ TXD = 0 ; USART 1 Transmit .equ RXD = 1 ; USART 1 Receive .equ CD = 2 ; Card Detect .equ WP = 3 ; Write Protect .equ MOSI = 4 ; SPI .equ MISO = 5 .equ SCK = 6 .equ SS = 7 #define i_CD VPORTC_IN, CD #define i_WP VPORTC_IN, WP #define b_SS VPORTC_OUT, SS sbi b_SS ; Disable SD-Card sbi VPORTC_DIR, TXD ; UART Transmit cbi VPORTC_DIR, RXD ; UART Receive cbi VPORTC_DIR, CD ; SD-Card Card Detect cbi VPORTC_DIR, WP ; SD-Card Write Protect sbi VPORTC_DIR, MOSI ; SD-Card cbi VPORTC_DIR, MISO ; SD-Card sbi VPORTC_DIR, SCK ; SD-Card sbi VPORTC_DIR, SS ; SD-Card ; ; Activate Pull-Up for CD and WP of SD-Card slot ; ldi r18, PORT_PULLUPEN_bm sts PORTC_PIN2CTRL, r18 sts PORTC_PIN3CTRL, r18 ; ; Alternate PINs for SPI1 ; ldi r18, PORTMUX_SPI1_ALT1_gc; SPI1 on PC4..7 sts PORTMUX_SPIROUTEA, r18 ;----------------------------------------------------------------------------- ; ; PORT D ; ; Data Port used as debug port, initialised as output ; #define dataportout VPORTD_OUT #define dataportin VPORTD_IN #define dataportdir VPORTD_DIR #define b_Level0 VPORTD_OUT, 0 #define b_Level1 VPORTD_OUT, 1 #define b_Level0a VPORTD_OUT, 2 #define b_Level1a VPORTD_OUT, 3 ldi r18, 0xff out VPORTD_DIR, r18 ;----------------------------------------------------------------------------- ; ; PORT E ; .equ INTI = 0 ; IACK cycle interrupt .equ INTQ = 1 ; DATI/DATO cycle interrupt .equ LED = 4 ; Activity LED .equ INTL = 2 .equ INIT = 3 ; Bus INIT interrupt #define i_INTI VPORTE_IN, INTI #define f_INTI VPORTE_INTFLAGS, INTI #define c_INTI PORTE_PIN0CTRL #define i_INTQ VPORTE_IN, INTQ #define f_INTQ VPORTE_INTFLAGS, INTQ #define c_INTQ PORTE_PIN1CTRL #define b_LED VPORTE_OUT, LED ; ; use LED output to test level1 feature with new name! ; #define b_INTL VPORTE_OUT, INTL #define f_INTL VPORTE_INTFLAGS, INTL #define c_INTL PORTE_PIN2CTRL #define i_INIT VPORTE_IN, INIT #define f_INIT VPORTE_INTFLAGS, INIT #define c_INIT PORTE_PIN3CTRL cbi VPORTE_DIR, INTI cbi VPORTE_DIR, INTQ sbi VPORTE_DIR, INTL cbi VPORTE_DIR, INIT sbi VPORTE_DIR, LED cbi VPORTE_OUT, INTI cbi VPORTE_OUT, INTQ sbi VPORTE_OUT, INTL cbi VPORTE_OUT, INIT cbi VPORTE_OUT, LED sbi b_INTL sbi f_INTL ldi r18, PORT_ISC_LEVEL_gc ; Level Sense Interrupt sts c_INTL, r18 sbi f_INTI ; Acknowledge any pending interrupt ldi r18, PORT_ISC_LEVEL_gc ; Level Sense Interrupt ldi r18, PORT_ISC_FALLING_gc sts c_INTI, r18 ; Pin Control sbi f_INTQ ; Acknowledge any pending interrupt ldi r18, PORT_ISC_LEVEL_gc ; Level Sense Interrupt ldi r18, PORT_ISC_FALLING_gc sts c_INTQ, r18 ; Pin Control sbi f_INIT ; Acknowledge any pending interrupt ldi r18, PORT_ISC_BOTHEDGES_gc ; Level Sense Interrupt sts c_INIT, r18 ; Pin Control ldi r18, CPU_CCP_IOREG_gc sts CPU_CCP, r18 ldi r18, PORTE_PORT_vect sts CPUINT_LVL1VEC, r18 ;----------------------------------------------------------------------------- ; ; PORT F ; .equ MEM = 0 ; Malloc Interrupt .equ ALT = 1 ; Alternate Controller Address .equ CRDY = 2 ; Controller Ready .equ IRQ = 3 ; Interrupt Request .equ RD = 4 ; Register Read .equ WR = 5 ; Register Write #define b_ALT VPORTF_OUT, ALT #define b_CRDY VPORTF_OUT, CRDY #define b_IRQ VPORTF_OUT, IRQ #define b_RD VPORTF_OUT, RD #define b_WR VPORTF_OUT, WR #define b_MEM VPORTF_OUT, MEM #define f_MEM VPORTF_INTFLAGS, MEM #define c_MEM PORTF_PIN0CTRL sbi VPORTF_DIR, MEM sbi VPORTF_DIR, ALT sbi VPORTF_DIR, CRDY sbi VPORTF_DIR, IRQ sbi VPORTF_DIR, RD sbi VPORTF_DIR, WR cbi b_ALT sbi b_CRDY cbi b_IRQ cbi b_RD cbi b_WR sbi b_MEM ; Set Level = High sbi f_MEM ; Acknowledge any pending interrupt ldi r18, PORT_ISC_LEVEL_gc ; Level Sense Interrupt sts c_MEM, r18 ; Pin Control ;============================================================================= ; ; USART 1 ; ldi r18, low(BAUD1) sts USART1_BAUDL, r18 ldi r18, high(BAUD1) sts USART1_BAUDH, r18 ldi r18, USART_NORMAL_CHSIZE_8BIT_gc sts USART1_CTRLC, r18 sbi VPORTB_OUT, TXD ; TXD1 sbi VPORTB_DIR, TXD ; TXD1 ldi r18, USART_RXEN_bm | USART_TXEN_bm | USART_SFDEN_bm sts USART1_CTRLB, r18 ldi r18, 0x00 sts USART1_CTRLA, r18 sei level000: ldi zl, low(2*hello) ldi zh, high(2*hello) level010: lpm r24, Z+ tst r24 breq level020 rcall serout rjmp level010 level020: rcall serin cpi r24, '?' breq level000 ; Still Working cpi r24, 't' breq level030 cbi b_LV0 rjmp level020 level030: sbi b_Level0 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 cbi b_Level0 sbi b_Level1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 cbi b_Level1 sbi b_Level0a rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 cbi b_Level0a sbi b_Level1a rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 cbi b_Level1a rjmp level020 hello: .db CR, LF .db "Level 1 Interrupt Test" .db CR, LF .db "Enter ? for this message" .db CR, LF .db "Enter t for toggle test " .db CR, LF .db "Any other key start interrupt test" .db CR, LF, 0, 0 ;-------------------------------------------------------------------------- ; ; Pin Change Interrupt ; ; go_: sbis f_LV0 ; is it a GO from the controller? reti ; sbi b_Level0a ; Mark Level0 Interrupt active push zh push zl push r8 in r8, CPU_SREG ldi zl, 4 ; create 4 pulses on b_Level0 lv0_010: sbi b_Level0 rjmp PC+1 rjmp PC+1 rjmp PC+1 cbi b_Level0 rjmp PC+1 rjmp PC+1 dec zl brne lv0_010 lds zl, CPUINT_STATUS sts lv0status, zl cbi b_INTL ; Trigger Level 1 Interrupt in nop nop nop nop ; Give it some time sbi b_LV0 ; remove interrupt ldi zl, -1 ldi zl, 6 ; create 6 larger pulses on b_Level0 lv0_020: sbi b_Level0 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 cbi b_Level0 rjmp PC+1 rjmp PC+1 rjmp PC+1 rjmp PC+1 dec zl brne lv0_020 out CPU_SREG, r8 pop r8 pop zl pop zh sbi f_LV0 ; Acknowledge interrupt cbi b_Level0a reti ;-------------------------------------------------------------------------- ; ; Register Convetion ; Y Register Value ; Z Pointer, Temporary Register ; ; qbus_: ; 4-5 sbis f_INTL ; Is it INTLevel1 test reti intl_: sbi b_Level1a push zh push zl push r8 in r8, CPU_SREG lds zl, CPUINT_STATUS sts lv1status, zl sbi b_Level1 cbi b_Level1 sbi b_Level1 cbi b_Level1 sbi b_Level1 cbi b_Level1 sbi b_Level1 cbi b_Level1 sbi b_Level1 cbi b_Level1 sbi b_Level1 cbi b_Level1 sbi b_Level1 cbi b_Level1 sbi b_Level1 cbi b_Level1 sbi b_Level1 cbi b_Level1 sbi b_INTL out CPU_SREG, r8 pop r8 pop zl pop zh sbi f_INTL cbi b_Level1a reti