Here is an example that makes use of VIA#2, and then responding to that interrupt using an ISR.
It's a working baseline reference for those interested. Done in a text file intended to be loaded by BASLOAD, but the PRG is tokenized BASIC also.
In the emulator you'll need to run it with the -via2 command line argument.
The online emulator seems to default to the 512K and only VIA#1 configuration, so TryItNow won't work on this for now. In the command startup of the emulator you can add "-via2" to model the second VIA.
REM V* 2023 - PUBLIC DOMAIN
REM PURPOSE OF EXAMPLE:
REM SET VIA#2 COUNTER (THAT COUNTS DOWN) TO TRIGGER AN ISR THAT COUNTS UP
REM (NOTE FOR PC EMULATOR REMEMBER TO USE -VIA2 COMMAND LINE ARGUMENT)
REM ADDRESSES USED:
REM $4000 MAIN PROGRAM TO SETUP VIA AND ISR STARTS HERE
REM $2000 USER-DEFINED ISR PROGRAMMED HERE
REM $1000 LOCATION OF ISR DATA COUNTER (16-BIT)
REM $1002 USED TO STORE PRIOR ISR ADDR (16-BIT)
REM THIS PROGRAM "EXITS" TO THE SYSTEM MONITOR TO HELP VIEW
REM MEMORY STATE CHANGES CAUSED BY THE ISR (USE "M 1000" COMMAND)
REM (IT COULD EXIT BACK TO BASIC... THERE IS A KERNAL CALL FOR THAT)
PRINT "RUN ONCE TO INIT COUNTER ISR."
PRINT "THIS PROGRAM WILL ACTIVATE THE MONITOR."
PRINT "USE 'M 1000' COMMAND (THEN PRESS"
PRINT "ENTER-ENTER-ENTER) TO OBSERVE"
PRINT "COUNTER VAUES TO VERIFY ISR IS"
PRINT "ACTIVE. MUST [RESET] TO CLEAR THE ISR."
PRINT
REM ************************************************
REM LOAD UP THE "MAIN PROGRAM"...
AD=$4000
RESTORE BLOB4000
GOSUB LOADBLOB
REM LOAD UP THE USER-DEFINED ISR...
AD=$2000
RESTORE BLOB2000
GOSUB LOADBLOB
REM HAND OFF EXECUTION TO THE "MAIN PROGRAM"...
SYS $4000
END:REM NOT REALLY NECESSARY, UNLIKELY THE MAIN-PROGRAM WILL COME BACK HERE.
REM ************************************************
REM ************************************************
REM RE-USABLE "FUNCTION" TO LOAD DATA VALUES AS MACHINE CODE SEQUENCES
LOADBLOB:
PRINT "LOADING ";HEX$(AD);
LOADBLOBNEXT:
READ DV
REM USING 999 INSTEAD OF -1 DUE TO BUG IN BASLOAD 0.2.3 RELATED TO INITIAL PARSING OF DATA-1
IF DV = 999 THEN PRINT" DONE":RETURN
POKE AD,DV
AD=AD+1
GOTO LOADBLOBNEXT
REM ************************************************
REM ************************************************
REM MAIN PROGRAM...
BLOB4000:REM EXPECTED TO BE LOADED INTO $4000
REM CLEAR/INIT TIMER_COUNT TO 0 (NOT REALLY NECESSARY, BUT JUST A "CLEAN START" IS GOOD PRACTICE)
REM THIS IS THE COUNTER THAT WILL BE USED IN THE ISR
DATA $A9,$00 :REM LDA #$00
DATA $8D,$00,$10:REM STA $1000 ; CAN USE STZ FOR 65C02
DATA $8D,$01,$10:REM STA $1001
REM PERFORM VIA#2 SETUP
DATA $A9,$C0 :REM LDA #$C0 ; SET BIT 7 SETS INTERRUPTS, BIT 6 ENABLE TIMER 1 (%11000000)
DATA $8D,$1E,$9F:REM STA $9F1E STA VIA_IER
DATA $A9,$40 :REM LDA #$40 ; CONTINUOUS INTERRUPTS, NO TOGGLE OF PORT B/A
DATA $8D,$1B,$9F:REM STA $9F1B STA VIA_ACL
DATA $A9,$34 :REM LDA #$34 ; LOAD LOW BYTE OF THE INITIAL 16-BIT VALUE
DATA $8D,$14,$9F:REM STA $9F14 STA VIA_T1CL (L FOR LOW)
DATA $A9,$12 :REM LDA #$12 ; LOAD HIGH BYTE OF THE INITIAL 16-BIT VALUE
DATA $8D,$15,$9F:REM STA $9F15 ; STA VIA_T1CH (H FOR HIGH) [STARTS TIMER RUNNING]
REM ABOVE EXAMPLE USES TIMER VALUE OF $1234, THIS IMPACTS HOW OFTEN
REM THE INTERRUPT WILL FIRE. CAN TRY OUT DIFFERENT VALUES AS DESIRED.
:REM ; SAVE ADDRESS OF THE CURRENT INTERRUPT HANDLER (WILL THEN BE REFERRED TO AS "THE PRIOR" ISR)
DATA $AD,$14,$03:REM LDA $0314 LDA IRQVECTOR
DATA $8D,$02,$10:REM STA $1002 STA PRIOR_IRQ
DATA $AD,$15,$03:REM LDA $0315 LDA IRQVECTOR+1
DATA $8D,$03,$10:REM STA $1003 STA PRIOR_IRQ+1
:REM ; INSERT "MY_ISR" AS NEW INTERRUPT HANDLER
DATA $78 :REM SEI ; DISABLE INTERRUPTS
DATA $A9,$00 :REM LDA #$00 ; WRITE LO ADDRESS OF CUSTOM INTERRUPT MY_ISR
DATA $8D,$14,$03:REM STA $0314 STA IRQVECTOR
DATA $A9,$20 :REM LDA #$20 ; Write HI ADDRESS OF CUSTOM INTERRUPT MY_ISR
DATA $8D,$15,$03:REM STA $0315 STA IRQVECTOR+1
DATA $58 :REM CLI ; ENABLE INTERRUPTS
:REM ; PROCEED WITH APPLICATION... (ISR IS NOW ACTIVE)
DATA $4C,$CC,$FE:REM JMP $FECC ; JUMP TO MONITOR
DATA 999 :REM END OF THIS BLOB OF CODE
REM ************************************************
REM ************************************************
REM USER ISR (AKA "MY_ISR"): INTERRUPT SERVICE ROUTINE
REM (THE FOLLOWING REGISTER-PUSH IS NOT NECESSARY, THIS IS DONE VIA ENTRY INTO IRQ)
REM DATA $48 :REM PHA ; PUSH A REGISTER TO STACK
REM DATA $DA :REM PHX ; PUSH X REGISTER TO STACK
REM DATA $5A :REM PHY ; PUSH Y REGISTER TO STACK
BLOB2000:REM EXPECTED TO BE LOADED INTO $2000
DATA $2C,$1D,$9F:REM BIT $9F1D ; BIT 6 COPIED TO OVERFLOW FLAG
DATA $50,$0F :REM BVC ISR_PRIOR ; OVERFLOW CLEAR, SO ISR NOT INVOKED DUE TO THIS INTERRUPT...
DATA $AD,$14,$9F:REM LDA $9F14 ; CLEARS THE INTERRUPT
DATA $EE,$00,$10:REM INC $1000 ; INCREMET LOW BYTE
DATA $D0,$03 :REM BNE ISR_END ; LOW BYTE DIDN'T ROLL OVER = DONE
DATA $EE,$01,$10:REM INC $1001 ; PREVIOUS BYTE ROLLED OVER --> INCREMENT THE HIGH BYTE
REM ISR_END:
DATA $7A :REM PLY ; PULL Y FROM STACK
DATA $FA :REM PLX ; PULL X FROM STACK
DATA $68 :REM PLA ; PULL A FROM STACK
DATA $40 :REM RTI:REM RETURN FROM THIS INTERRUPT
REM ISR_PRIOR:
DATA $6C,$02,$10:REM JMP ($1002) JUMP TO PRIOR ISR THAT WAS STORED AT $1002 EARLIER (PRIOR_IRQ)
DATA 999 :REM END OF THIS BLOB OF CODE
REM ************************************************
VIA usage + ISR + "asm blobs" BASLOAD example
VIA usage + ISR + "asm blobs" BASLOAD example
- Attachments
-
- ISR-VIA-SAMPLE.BAS
- (5.38 KiB) Downloaded 363 times
-
- ISR-VIA-SAMPLE.PRG
- (4.97 KiB) Downloaded 337 times