/***************************************************************************/ /* */ /* library of functions for Mini Board rev 1.5 */ /* (C) 1992 Fred Martin */ /* for Dave Dunfield */ /* last updated 4/9/92 */ /* */ /* Adapted for the Coactive Aestethics GNU gcc port */ /* by Serge Boentges */ /* Departement of Physical Chemistry, */ /* ETH Zurich, Switzerland, */ /* sebo@nmr.lpc.ethz.ch */ /* version from March, 1993 */ /* */ /* Please note, that the parameter lists is reversed compared to the */ /* description in Fred's MB Manual. */ /* The following functions are defined: */ /* ----------------------------------------------------------------------- */ /* */ /* int analog(int port) Returns analog reading from port. */ /* Ports are numbered 0 to 7. */ /* Ports 0 to 3 default as motor feedback */ /* for motors 1 to 4, respectively. */ /* */ /* int digital(int port) Returns 1 or 0 (true or false) value */ /* from Port C. */ /* */ /* void motor(int s, int m) Sets motor m at speed s. Motors are */ /* numbered from 1 to 4; speeds are numbered */ /* from -16 (full backward) to +16 (full */ /* forward). */ /* */ /* void off(int m) Turns off motor m. */ /* */ /* int button(void) Returns 1 (true) when IRQ button is depressed. */ /* System will hang while button is held */ /* down, so effectively, returns true */ /* when button is released. */ /* */ /* Button presses are automatically debounced,*/ /* but a press will get queued if it happens */ /* before you ask for it. */ /* */ /* int dipsw(int sw) Returns state of DIP switch plugged into */ /* Port D. Port D2 is switch #1; D5 is sw #4.*/ /* Open (NC) position is true, closed is false.*/ /* */ /* void msleep(int msec) Wastes time for msec milliseconds. */ /* */ /* void tone(int freq, Generates a beep of frequency "freq" for */ /* int duration) "duration" milliseconds. */ /***************************************************************************/ asm("*"); asm("*"); asm("* file of standard 6811 register declarations"); asm("*"); asm("*********************************************************************"); asm("* Control Registers"); asm("*"); asm("BASE EQU $1000"); asm("*"); asm("PORTA EQU $1000 ; Port A data register"); asm("RESV1 EQU $1001 ; Reserved"); asm("PIOC EQU $1002 ; Parallel I/O Control register"); asm("PORTC EQU $1003 ; Port C latched data register"); asm("PORTB EQU $1004 ; Port B data register"); asm("PORTCL EQU $1005 ;"); asm("DDRC EQU $1007 ; Data Direction register for port C"); asm("PORTD EQU $1008 ; Port D data register"); asm("DDRD EQU $1009 ; Data Direction register for port D"); asm("PORTE EQU $100A ; Port E data register"); asm("CFORC EQU $100B ; Timer Compare Force Register"); asm("OC1M EQU $100C ; Output Compare 1 Mask register"); asm("OC1D EQU $100D ; Output Compare 1 Data register"); asm("*"); asm("* Two-Byte Registers (High,Low -- Use Load & Store Double to access)"); asm("TCNT EQU $100E ; Timer Count Register"); asm("TIC1 EQU $1010 ; Timer Input Capture register 1"); asm("TIC2 EQU $1012 ; Timer Input Capture register 2"); asm("TIC3 EQU $1014 ; Timer Input Capture register 3"); asm("TOC1 EQU $1016 ; Timer Output Compare register 1"); asm("TOC2 EQU $1018 ; Timer Output Compare register 2"); asm("TOC3 EQU $101A ; Timer Output Compare register 3"); asm("TOC4 EQU $101C ; Timer Output Compare register 4"); asm("TI4O5 EQU $101E ; Timer Input compare 4 or Output compare 5 register"); asm("*"); asm("TCTL1 EQU $1020 ; Timer Control register 1"); asm("TCTL2 EQU $1021 ; Timer Control register 2"); asm("TMSK1 EQU $1022 ; main Timer interrupt Mask register 1"); asm("TFLG1 EQU $1023 ; main Timer interrupt Flag register 1"); asm("TMSK2 EQU $1024 ; misc Timer interrupt Mask register 2"); asm("TFLG2 EQU $1025 ; misc Timer interrupt Flag register 2"); asm("PACTL EQU $1026 ; Pulse Accumulator Control register"); asm("PACNT EQU $1027 ; Pulse Accumulator Count register"); asm("SPCR EQU $1028 ; SPI Control Register"); asm("SPSR EQU $1029 ; SPI Status Register"); asm("SPDR EQU $102A ; SPI Data Register"); asm("BAUD EQU $102B ; SCI Baud Rate Control Register"); asm("SCCR1 EQU $102C ; SCI Control Register 1"); asm("SCCR2 EQU $102D ; SCI Control Register 2"); asm("SCSR EQU $102E ; SCI Status Register"); asm("SCDR EQU $102F ; SCI Data Register"); asm("ADCTL EQU $1030 ; A/D Control/status Register"); asm("ADR1 EQU $1031 ; A/D Result Register 1"); asm("ADR2 EQU $1032 ; A/D Result Register 2"); asm("ADR3 EQU $1033 ; A/D Result Register 3"); asm("ADR4 EQU $1034 ; A/D Result Register 4"); asm("BPROT EQU $1035 ; Block Protect register"); asm("RESV2 EQU $1036 ; Reserved"); asm("RESV3 EQU $1037 ; Reserved"); asm("RESV4 EQU $1038 ; Reserved"); asm("OPTION EQU $1039 ; system configuration Options"); asm("COPRST EQU $103A ; Arm/Reset COP timer circuitry"); asm("PPROG EQU $103B ; EEPROM Programming register"); asm("HPRIO EQU $103C ; Highest Priority Interrupt and misc."); asm("INIT EQU $103D ; RAM and I/O Mapping Register"); asm("TEST1 EQU $103E ; factory Test register"); asm("CONFIG EQU $103F ; Configuration Control Register"); asm("*"); asm("*"); asm("* Interrupt Vector locations"); asm("*"); asm("SCIINT EQU $D6 ; SCI serial system"); asm("SPIINT EQU $D8 ; SPI serial system"); asm("PAIINT EQU $DA ; Pulse Accumulator Input Edge"); asm("PAOVINT EQU $DC ; Pulse Accumulator Overflow"); asm("TOINT EQU $DE ; Timer Overflow"); asm("TOC5INT EQU $E0 ; Timer Output Compare 5"); asm("TOC4INT EQU $E2 ; Timer Output Compare 4"); asm("TOC3INT EQU $E4 ; Timer Output Compare 3"); asm("TOC2INT EQU $E6 ; Timer Output Compare 2"); asm("TOC1INT EQU $E8 ; Timer Output Compare 1"); asm("TIC3INT EQU $EA ; Timer Input Capture 3"); asm("TIC2INT EQU $EC ; Timer Input Capture 2"); asm("TIC1INT EQU $EE ; Timer Input Capture 1"); asm("RTIINT EQU $F0 ; Real Time Interrupt"); asm("IRQINT EQU $F2 ; IRQ External Interrupt"); asm("XIRQINT EQU $F4 ; XIRQ External Interrupt"); asm("SWIINT EQU $F6 ; Software Interrupt"); asm("BADOPINT EQU $F8 ; Illegal Opcode Trap Interrupt"); asm("NOCOPINT EQU $FA ; COP Failure (Reset)"); asm("CMEINT EQU $FC ; COP Clock Monitor Fail (Reset)"); asm("RESETINT EQU $FE ; RESET Interrupt"); asm("*"); asm("* Masks for serial port"); asm("PORTDWOM EQU $20"); asm("BAUD1200 EQU $B3"); asm("BAUD9600 EQU $B0"); asm("TRENA EQU $0C ; Transmit, Receive ENAble"); asm("RDRF EQU $20 ; Receive Data Register Full"); asm("TDRE EQU $80 ; Transmit Data Register Empty"); asm("*"); asm("***** start of 6811ZP.ASM *****"); asm("*"); asm(" ORG $00"); asm("*"); asm("*"); asm("* button variables"); asm("irqval RMB 1"); asm("buttime RMB 2"); asm("*"); asm("* system time: 4 bytes"); asm("st_hi RMB 2 ; high word"); asm("*"); asm("time EQU * ; reference to low time for C"); asm("st_lo RMB 2 ; low word"); asm("*"); asm("* motor control"); asm("motctrl RMB 1 * high nybble=on/off; low nybble=dir"); asm("speed1 RMB 2"); asm("speed2 RMB 2"); asm("speed3 RMB 2"); asm("speed4 RMB 2"); asm("*"); asm("* beeper period"); asm("beeptone RMB 2"); asm("*"); asm("*"); asm("***** end of 6811ZP.asm *****"); asm("*"); asm("*"); asm("*"); asm("; Pseudo regs"); asm(";"); asm("ZD0 RMB 2"); asm("ZD1 RMB 2"); asm("ZD2 RMB 2"); asm("ZD3 RMB 2"); asm("ZD4 RMB 2"); asm("ZX1 RMB 2"); asm("ZX2 RMB 2"); asm("ZX3 RMB 2"); asm("ZX4 RMB 2"); asm("ZA0 RMB 1"); asm("ZB0 RMB 1"); asm("ZB1 RMB 1"); asm("ZB2 RMB 1"); asm("ZB3 RMB 1"); asm("ZB4 RMB 1"); asm("*"); asm("temp RMB 1"); asm("*"); asm("*"); asm("* 6811rst.asm:"); asm("*"); asm("* interrupt vector definitions"); asm("*"); asm("*"); asm(" ORG $FF00+IRQINT"); asm(" FDB irqi * defined in 6811st.asm"); asm("*"); asm(" ORG $FF00+TOC4INT"); asm(" FDB systemi * defined in 6811st.asm"); asm("*"); asm(" ORG $FF00+TOC5INT"); asm(" FDB beepi"); asm("*"); asm(" ORG $FF00+RESETINT"); asm(" FDB $F800"); asm("*"); asm("***********************************************************************"); asm("* 6811st.src"); asm("*"); asm("*"); asm("*"); asm("***********************************************************************"); asm("*"); asm("* start of code"); asm("*"); asm("* (1) perform initialization of stack, interrupts, system"); asm("* (2) code for system interrupt"); asm("*"); asm("*"); asm("*"); asm(" ORG $F800"); asm(" LDS #$FF"); asm("*"); asm(" LDX #$1000"); asm("*"); asm("* initialize serial port"); asm(" LDAA #$30 ; 9600 baud"); asm(" STAA BAUD,X"); asm(" BSET SCCR2,X,$0C ; transmit, receive enable"); asm("*"); asm("* turn on analog subsystem"); asm(" BSET OPTION,X $80"); asm("*"); asm("* set up interrupts"); asm("* OC4: 1 kHz system interrupt"); asm(" LDAA #%00010000"); asm(" STAA TFLG1,X"); asm(" STAA TMSK1,X"); asm("*"); asm(" CLRA"); asm(" CLRB"); asm("*"); asm("* initialize system time"); asm(" STD st_hi"); asm(" STD st_lo"); asm("*"); asm("* initialize button variables"); asm(" STAA irqval"); asm(" STD buttime"); asm("*"); asm("*"); asm("*"); asm("* initialize motor control"); asm(" STAA motctrl * default == OFF"); asm(" LDD #$FFFF"); asm(" STD speed1 * full speed"); asm(" STD speed2"); asm(" STD speed3"); asm(" STD speed4"); asm("*"); asm("* initialize beeper"); asm(" BSET PACTL,X;%00001000 ; set PA3 for output"); asm("*"); asm("* enable interrupts"); asm(" CLI"); asm("*"); asm(" JSR _main"); asm("exit bra exit"); asm("___main:"); asm(" RTS"); asm("*"); asm("*"); asm("*"); asm("*"); asm("*"); asm("*"); asm("* 1 KHz driver routine"); asm("*"); asm("*"); asm("*"); asm("systemi EQU *"); asm(" LDX #BASE * point to register base"); asm("*"); asm("* setup for next interrupt"); asm(" LDD #2000 ; 2000 cycles = 1 millisec."); asm(" ADDD TOC4,X * add TOC5 to D"); asm(" STD TOC4,X * store back"); asm(" BCLR TFLG1,X,%11101111 * clear OC4 for next compare"); asm("*"); asm("* enable beeper to interrupt us"); asm(" BSET TMSK1,X,%00001000"); asm(" CLI"); asm("*"); asm("* increment system time"); asm(" LDX st_lo"); asm(" INX"); asm(" STX st_lo"); asm(" BNE si_noinc"); asm(" LDX st_hi"); asm(" INX"); asm(" STX st_hi"); asm("*"); asm("si_noinc EQU *"); asm("*"); asm("*"); asm("*"); asm("*"); asm("* do pulse width modulation, 4 motors"); asm("* motor 1 (ls bit of low nybble is dir, ls bit of high nybble is on/off"); asm("pwm LDX motctrl * upper nybble is on/off; lower is dir"); asm("*"); asm(" LDD speed1"); asm(" LSLD"); asm(" BCC pwmoff1"); asm(" ADDD #1"); asm(" XGDX * get output byte into D; save new speed in X"); asm(" EORA #%00010000 * toggle motor 1 ctrl bit"); asm(" BRA pwmset1"); asm("pwmoff1 XGDX"); asm(" ORAA #%00010000 * set motor 1 ctrl bit"); asm("pwmset1 XGDX"); asm(" STD speed1"); asm("*"); asm(" LDD speed2"); asm(" LSLD"); asm(" BCC pwmoff2"); asm(" ADDD #1"); asm(" XGDX * get output byte into D; save new speed in X"); asm(" EORA #%00100000 * toggle motor 2 ctrl bit"); asm(" BRA pwmset2"); asm("pwmoff2 XGDX"); asm(" ORAA #%00100000 * set motor 2 ctrl bit"); asm("pwmset2 XGDX"); asm(" STD speed2"); asm("*"); asm(" LDD speed3"); asm(" LSLD"); asm(" BCC pwmoff3"); asm(" ADDD #1"); asm(" XGDX * get output byte into D; save new speed in X"); asm(" EORA #%01000000 * toggle motor 3 ctrl bit"); asm(" BRA pwmset3"); asm("pwmoff3 XGDX"); asm(" ORAA #%01000000 * set motor 3 ctrl bit"); asm("pwmset3 XGDX"); asm(" STD speed3"); asm("*"); asm("*"); asm(" LDD speed4"); asm(" LSLD"); asm(" BCC pwmoff4"); asm(" ADDD #1"); asm(" XGDX * get output byte into D; save new speed in X"); asm(" EORA #%10000000 * toggle motor 4 ctrl bit"); asm(" BRA pwmset4"); asm("pwmoff4 XGDX"); asm(" ORAA #%10000000 * set motor 4 ctrl bit"); asm("pwmset4 XGDX"); asm(" STD speed4"); asm("*"); asm("*"); asm(" XGDX * get control bits into A"); asm(" EORA #$F0 * toggle speed bits"); asm("*"); asm(" STAA PORTB * do it"); asm("*"); asm(" RTI"); asm("*"); asm("*"); asm("* PA3: beeper interrupt"); asm("beepi EQU *"); asm(" LDX #BASE"); asm(" LDD beeptone"); asm(" ADDD TI4O5,X"); asm(" STD TI4O5,X"); asm(" BCLR TFLG1,X,%11110111"); asm(" RTI"); asm("*"); asm("*"); asm("* IRQ interrupt: sets irqval to one when interrupt occurs"); asm("irqi EQU *"); asm(" LDD st_lo"); asm(" SUBD buttime"); asm(" CPD #60"); asm(" BLO irqdone"); asm(" LDAA #1"); asm(" STAA irqval"); asm(" LDD st_lo"); asm(" STD buttime"); asm("irqdone RTI"); asm("*"); asm(";-----------------------------------------"); asm("; end startup code"); asm(";-----------------------------------------"); asm("*"); asm("*"); asm("* library of functions for Mini Board rev 1.5"); asm("* (C) 1992 Fred Martin"); asm("*"); asm("* for Dave Dunfield"); asm("* last updated 4/9/92"); asm("*"); asm("*"); asm("*"); asm("* The following functions are defined:"); asm("* -----------------------------------------------------------------------"); asm("*"); asm("* int analog(int port) Returns analog reading from port."); asm("* Ports are numbered 0 to 7."); asm("* Ports 0 to 3 default as motor feedback"); asm("* for motors 1 to 4, respectively."); asm("*"); asm("* int digital(int port) Returns 1 or 0 (true or false) value"); asm("* from Port C."); asm("*"); asm("* void motor(int s, int m) Sets motor m at speed s. Motors are"); asm("* numbered from 1 to 4; speeds are numbered"); asm("* from -16 (full backward) to +16 (full"); asm("* forward)."); asm("*"); asm("* void off(int m) Turns off motor m."); asm("*"); asm("* int button(void) Returns 1 (true) when IRQ button is depressed."); asm("* System will hang while button is held"); asm("* down, so effectively, returns true"); asm("* when button is released."); asm("*"); asm("* Button presses are automatically debounced,"); asm("* but a press will get queued if it happens"); asm("* before you ask for it."); asm("*"); asm("* int dipsw(int sw) Returns state of DIP switch plugged into"); asm("* Port D. Port D2 is switch #1; D5 is sw #4."); asm("* Open (NC) position is true, closed is false."); asm("*"); asm("* void msleep(int msec) Wastes time for msec milliseconds."); asm("*"); asm("* void tone(int freq, Generates a beep of frequency \"freq\" for"); asm("* int duration) \"duration\" milliseconds."); asm("*"); asm("*"); asm("_digital EQU *"); asm(" TSX"); asm(" LDAB PORTC * get PORTC into B"); asm(" LDAA 3,X * get port # into A"); asm("*"); asm("digloop BEQ digdone"); asm(" LSRB * shift B bits down"); asm(" DECA"); asm(" BRA digloop"); asm("*"); asm("digdone ANDB #1 * mask off all but low bit"); asm(" EORB #1 * invert logical sense due to hardware"); asm("* A is already zero"); asm(" STD ZD0 * store return value in ZD0 for GNU's sake"); asm(" RTS"); asm("*"); asm("_analog EQU *"); asm(" TSX"); asm(" LDAA 3,X * get port # into A"); asm(" SEI * disable interrupts"); asm(" STAA ADCTL"); asm("analoop LDAA ADCTL"); asm(" ANDA #$80"); asm(" BEQ analoop"); asm(" CLI * re-enable them"); asm(" LDAB ADR1"); asm(" CLRA"); asm(" STD ZD0 * store return value in ZD0 for GNU's sake"); asm(" RTS"); asm("*"); asm("_dipsw EQU *"); asm(" TSX"); asm(" LDAB PORTD"); asm(" LSRB * desired bits in pos"); asm(" LDAA 3,X * switch number (1 to 4) in A"); asm("*"); asm("diploop LSRB * shift B bits down"); asm(" DECA"); asm(" BNE diploop"); asm("*"); asm(" ANDB #1"); asm("* *A is already zero; B has 1 or 0"); asm(" STD ZD0 * store return value in ZD0 for GNU's sake"); asm(" RTS * A is already zero; B has 1 or 0"); asm("*"); asm("*"); asm("*"); asm("* motor(int s, int m)"); asm("* m= 1, 2, 3, or 4"); asm("* s= -16 (full on backward) to +16 (full on forward)"); asm("*"); asm("_motor EQU *"); asm(" TSX"); asm(" LDAB 5,X * motor number"); asm(" PSHB * save for later"); asm(" LDAA #$08 * bit mask"); asm(" SEC * set carry, will be rotated into A"); asm("msloop ROLA"); asm(" DECB"); asm(" BNE msloop"); asm("* A now has motor enable mask"); asm(" PSHA"); asm(" ORAA motctrl"); asm(" STAA temp"); asm(" PULA"); asm(" ANDA #$0F * keep dir bit only"); asm(" TST 2,X * high byte of speed"); asm(" BPL mset2"); asm("* negative speed => clear direction bit"); asm(" COMA"); asm(" ANDA temp"); asm(" BRA mset1"); asm("mset2 LDAA temp"); asm("mset1 STAA motctrl"); asm("*"); asm(" LDD 2,X * speed word"); asm(" BPL speedok"); asm(" LDD #0"); asm(" SUBD 2,X"); asm("*"); asm("* number from 0 to 16 now in B"); asm("speedok ASLB * double it"); asm(" LDX #mtable"); asm(" ABX * index into speed table"); asm(" LDY 0,X * get speed bits"); asm(" PULB * get motor number from 1 to 4"); asm(" ASLB"); asm(" LDX #speed1-2"); asm(" ABX * ptr to speed entry"); asm(" STY 0,X * store speed bits"); asm("* done!"); asm(" RTS"); asm("*"); asm("* table of motor speeds"); asm("mtable"); asm(" FDB %0000000000000000 * 0/16"); asm(" FDB %0000000000000001 * 1/16"); asm(" FDB %0000000100000001 * 2/16"); asm(" FDB %0000100001000010 * 3/16"); asm(" FDB %0001000100010001 * 4/16"); asm(" FDB %0010001001001001 * 5/16"); asm(" FDB %0100100100101001 * 6/16"); asm(" FDB %0101001010101010 * 7/16"); asm(" FDB %0101010101010101 * 8/16"); asm(" FDB %1010101010101011 * 9/16"); asm(" FDB %0101011010101011 * 10/16"); asm(" FDB %1101110110110110 * 11/16"); asm(" FDB %1110111011101110 * 12/16"); asm(" FDB %1110111011101111 * 13/16"); asm(" FDB %1110111111101111 * 14/16"); asm(" FDB %1111111011111111 * 15/16"); asm(" FDB %1111111111111111 * 16/16"); asm("*"); asm("*"); asm("* void off(int m)"); asm("*"); asm("_off TSX"); asm(" LDAB 3,X * motor number"); asm(" LDAA #$08 * bit mask"); asm("offloop ROLA"); asm(" DECB"); asm(" BNE offloop"); asm("* A now has motor enable mask"); asm(" COMA"); asm(" ANDA motctrl"); asm(" STAA motctrl"); asm(" RTS"); asm("*"); asm("*"); asm("* delay for nn,nnn milliseconds"); asm("*"); asm("_msleep EQU *"); asm(" TSX"); asm("sleepsub SEI * halt interrupts until we perform calculation"); asm(" LDD st_lo"); asm(" ADDD 2,X"); asm(" CLI * okay again"); asm("sleeplp CPD st_lo"); asm(" BNE sleeplp"); asm(" RTS"); asm("*"); asm("*"); asm("* button(void)"); asm("* returns 1 if irqval is one (sets irqval to zero in this case)"); asm("* else returns 0"); asm("*"); asm("_button EQU *"); asm(" CLRA"); asm(" LDAB irqval"); asm(" BEQ butndone"); asm(" CLR irqval"); asm(" STD ZD0 * store return value in ZD0 for GNU's sake"); asm("butndone RTS"); asm("*"); asm("*"); asm("* tone( int duration, int freq)"); asm("*"); asm("_tone EQU *"); asm(" TSX"); asm(" LDD 4,X ; frequency"); asm(" LSRD"); asm(" LSRD"); asm(" LSRD"); asm(" LSRD ; divide by 16"); asm(" PSHX"); asm(" LDX #62500 ; 1E6 divided by 16"); asm(" XGDX"); asm(" IDIV ; answer in X"); asm(" STX beeptone"); asm(" LDX #BASE"); asm(" BSET TCTL1,X;$01 ; set beeper pin to toggle"); asm(" BSET TMSK1,X;$08 ; turn on beeper interrupt"); asm(" BSET PORTB,X;$80 ; enable motor 4"); asm(" PULX"); asm(" BSR sleepsub ; sleep for desired duration"); asm(" LDX #BASE"); asm(" BCLR TMSK1,X;$08 ; turn off beeper interrupt"); asm(" BCLR TCTL1,X;$01 ; set beeper pin to do nothing"); asm(" BCLR PORTA,X;$08 ; turn off beeper"); asm(" BCLR PORTB,X;$80 ; disable motor 4"); asm(" LDX #0"); asm(" STX beeptone"); asm(" RTS"); asm("**********************************************************************"); asm("* End of Library and Startup Code *"); asm("**********************************************************************");