ca65 V2.13.3 - (C) Copyright 1998-2012 Ullrich von Bassewitz Main file : main.s Current file: main.s 000000r 1 ;------------------------------------------------------------------------- 000000r 1 ; APPLE ][ SERIES ANNUNCIATOR MIDI DRIVER 000000r 1 ; Copyright © 1998-2018 Eric Rangell. MIT License. 000000r 1 ;-------------------------------------------------------------------------; 000000r 1 ; main.s 000000r 1 ; A2NoSlotMidi 000000r 1 ; Created by Eric Rangell on 17 JULY 2018. 000000r 1 ; VERSION 1.0.1 released 26 JULY 2018 000000r 1 ; VERSION 1.0.2 released 29 JULY 2018 000000r 1 ;------------------------------------------------------------------------- 000000r 1 ; THIS DRIVER IMPLEMENTS ASYNCHRONOUS SERIAL DATA TRANSMISSION 000000r 1 ; THROUGH AN APPLE ][ ANNUNCIATOR OUTPUT PORT OF THE GAME CONNECTOR 000000r 1 ; USING 32 CYCLES PER BIT TO ACHIEVE A 31.25K MIDI BAUD RATE. 000000r 1 ; 000000r 1 ; APPLE //GS USERS NEED TO RUN THIS PROGRAM IN NORMAL SPEED MODE (1MHZ) 000000r 1 ; 000000r 1 ; THE OUTPUT IS INITIALIZED TO A HIGH LOGIC VOLTAGE. WHEN IT GOES 000000r 1 ; LOW FOR 32 MICROSECONDS, THAT INDICATES THE START BIT OF A MIDI BYTE. 000000r 1 ; THEN 8 BYTES OF DATA ARE TRANSMITTED, FOLLOWED BY A HIGH STOP BIT. 000000r 1 ; THE DATA BYTES REPRESENT MIDI MESSAGES WHICH CAN BE INTERPRETED BY 000000r 1 ; ANY MUSICAL INSTRUMENT THAT IMPLEMENTS MIDI. 000000r 1 ; 000000r 1 ; ENTRY POINTS: (Note: Origin must be set in Makefile) 000000r 1 ; 000000r 1 ; $9000 = INITIALIZE - TURNS ON ANNUNCIATOR 0 - MUST BE CALLED ONCE 000000r 1 ; $9003 = APPLESOFT CALL TO SEND ONE MIDI BYTE. POKE THE BYTE IN $9004. 000000r 1 ; $9005 = ASSEMBLY CALL TO SEND ONE MIDI BYTE FROM ACCUMULATOR 000000r 1 ; $9008 = APPLESOFT OR ASSEMBLY CALL TO SEND SEVERAL BYTES AT ONCE: 000000r 1 ; THE CALLER POPULATES LOCATION $D7 WITH THE NUMBER OF BYTES TO BE 000000r 1 ; TRANSMITTED, AND A POINTER IN $CE,CF (LO,HI) WITH THE ADDRESS OF 000000r 1 ; THE DATA BYTES, THEN CALLS THE ENTRY POINT "SENDMSG" TO TRANSMIT 000000r 1 ; THE MESSAGE. 000000r 1 ; $900B = TURN ALL NOTES OFF 000000r 1 ; $900E = SEND A TEST MESSAGE - C MAJOR CHORD NOTE ONS 000000r 1 ; $9011 = SEND A TEST MESSAGE - C MAJOR CHORD NOTE OFFS 000000r 1 ; 000000r 1 ; IF THE FOLLOWING ROUTINE IS USED, IT SHOULD BE CALLED IMMEDIATELY AFTER BLOADING 000000r 1 ; THE BINARY. AT THE END, IT WILL CALL THE INIT ROUTINE FOR THE SELECTED ANNUNCIATOR. 000000r 1 ; 000000r 1 ; $9014 = CHANGE ANNUNCIATOR - MODIFIES CODE TO USE DIFFERENT ANNUNCIATOR 000000r 1 ; $9017 = ANNUNCIATOR TO USE: 0-3 - only looks at least significant 2 bits 000000r 1 ; 000000r 1 ; $9018 = SET TO 1 TO USE NEGATIVE LOGIC (ONLY ONE INVERTER IN THE MIDI CIRCUIT) 000000r 1 ;------------------------------------------------------------------------- 000000r 1 ; Enhancements for 2018: 000000r 1 ; 1. Disable interrupts during critical timing sections, preserve interrupt status 000000r 1 ; 2. Entry point to reconfigure program to use a different annunciator pair 000000r 1 ; 3. Entry point to reconfigure program for hardware interface using inverters only (not buffers) 000000r 1 ;------------------------------------------------------------------------- 000000r 1 ; CALLER MUST POPULATE THE FOLLOWING TWO ZERO PAGE LOCATIONS FOR SENDMSG: 000000r 1 NUMBYTES = $D7 ;NUMBER OF BYTES TO BE TRANSMITTED NOW (1-256) 000000r 1 ; ;THE VALUE 0 WILL TRANSMIT 256 BYTES. 000000r 1 DATAPTR = $CE ;POINTER TO THE BYTES TO BE TRANSMITTED NOW 000000r 1 ;------------------------------------------------------------------------- 000000r 1 AN0OFF = $C058 ;APPLE ADDRESSES THAT CONTROL ANNUNCIATOR OUTPUTS 000000r 1 AN0ON = $C059 ;PROGRAM REFERNCES ARE RELATIVE TO AN0 000000r 1 ;AN1OFF = $C05A 000000r 1 ;AN1ON = $C05B 000000r 1 ;AN2OFF = $C05C 000000r 1 ;AN2ON = $C05D 000000r 1 ;AN3OFF = $C05E 000000r 1 ;AN3ON = $C05F 000000r 1 ;------------------------------------------------------------------------- 000000r 1 .proc main 000000r 1 ;--------------------------------------------------------------------------- 000000r 1 START: 000000r 1 4C rr rr JMP INIT ;MAIN ENTRY POINT - INITIALIZES ANNUNCIATORS 000003r 1 SENDFP: 000003r 1 A9 90 LDA #$90 ;ENTRY POINT FOR APPLESOFT: POKE BYTE AND CALL 000005r 1 SENDONE: 000005r 1 4C rr rr JMP XMITONE ;ENTRY POINT FOR TRANSMITTING ONE BYTE FROM ACCUM 000008r 1 SENDMSG: 000008r 1 4C rr rr JMP XMITMSG ;ENTRY POINT FOR TRANSMITTING A MIDI MESSAGE 00000Br 1 ALLNOFF: 00000Br 1 4C rr rr JMP QUIET ;TURN ALL NOTES OFF 00000Er 1 TEST1: 00000Er 1 4C rr rr JMP TESTMSG1 ;SEND TEST MESSAGE 1 - C MAJOR CHORD ON 000011r 1 TEST2: 000011r 1 4C rr rr JMP TESTMSG2 ;SEND TEST MESSAGE 2 - C MAJOR CHORD OFF 000014r 1 CHNGANNC: 000014r 1 4C rr rr JMP CHGANNC ;RECONFIGURE PROGRAM TO USE ANNUNCIATOR NUMBER IN NEXT BYTE 000017r 1 ANNC2USE: 000017r 1 00 .byte $00 ;ONLY LEAST SIGNIFICANT 2 BITS ARE USED 000018r 1 NEGLOGIC: 000018r 1 00 .byte $00 ;SET TO 1 TO USE NEGATIVE LOGIC, OTHERWISE LEAVE 0 FOR POSITIVE LOGIC (DEFAULT). DO NOT USE ANY OTHER VALUES! 000019r 1 ;--------------------------------------------------------------------------- 000019r 1 01 MAJVER: .byte $01 ;BYTES USED TO TRACK VERSION OF RELEASED EXECUTABLES 00001Ar 1 02 MINVER: .byte $02 ;NIBBLES ARE USED FOR THE VERSION NUMBER ($0102 = VERSION 1.0.2) 00001Br 1 00 ASAVE: .byte $00 ;SAVE AREA FOR ACCUMULATOR 00001Cr 1 00 SAVENBYT: .byte $00 ;SAVE AREA FOR NUMBYTES 00001Dr 1 ;--------------------------------------------------------------------------- 00001Dr 1 AD rr rr INIT: LDA NEGLOGIC 000020r 1 29 FE AND #$FE 000022r 1 F0 01 BEQ OK2INIT 000024r 1 00 BRK ;ABEND IF NEGLOGIC NOT 0 OR 1 000025r 1 OK2INIT: 000025r 1 A9 59 LDA #TESTDAT1 000136r 1 85 CF STA DATAPTR+1 000138r 1 20 rr rr JSR SENDMSG 00013Br 1 60 RTS 00013Cr 1 ;----------------------------------------------------------------------- 00013Cr 1 TESTMSG2: 00013Cr 1 A9 07 LDA #7 00013Er 1 85 D7 STA NUMBYTES 000140r 1 A9 rr LDA #TESTDAT2 000146r 1 85 CF STA DATAPTR+1 000148r 1 20 rr rr JSR SENDMSG 00014Br 1 60 RTS 00014Cr 1 ;----------------------------------------------------------------------- 00014Cr 1 QUIET: 00014Cr 1 A9 90 LDA #$90 00014Er 1 85 D7 STA NUMBYTES 000150r 1 A9 rr LDA #QUIETMSG 000156r 1 85 CF STA DATAPTR+1 000158r 1 20 rr rr JSR SENDMSG 00015Br 1 60 RTS 00015Cr 1 ;----------------------------------------------------------------------- 00015Cr 1 CHGANNC: 00015Cr 1 AD rr rr LDA ANNC2USE 00015Fr 1 29 03 AND #$03 ;KEEP ONLY 2 LEAST SIGNIFICANT BITS 000161r 1 0A ASL ;MULTIPLY BY 2 000162r 1 48 PHA ;SAVE THIS VALUE FOR EACH MOD BEING DONE BELOW 000163r 1 18 CLC 000164r 1 69 58 ADC #