Now I have the MC68901 MFP integrated and the UART is working, I spent a bit of time this weekend setting up Timer C of the MFP as a timer tick I can use in the OS for multitasking.
For testing purposes, I've set the timer up at about 18Hz and have the interrupt handler just flash an LED connected to MFP GPIO 0. That way, I can visually see that the handler is being run. The code that sets up the MFP now looks like this (I've also upped the UART to 19200 baud):
* Initialise MFP * * Trashes: D0 * Modifies: MFP Regs INITMFP: * GPIOs move.b #$FF, MFP_DDR ; All GPIOs are output * Timer setup - Timer D controls serial clock, C is kernel tick move.b #$00, MFP_TCDR ; Timer C count is 0 (equivalent to 255) for 18Hz move.b #$0C, MFP_TDDR ; Timer D count is 12 for 19.2KHz move.b #$71, MFP_TCDCR ; Enable timer C with /200 and D with /4 prescaler * USART setup move.b #$08, MFP_UCR ; Fundamental clock, async, 8N1 move.b #$05, MFP_TSR ; Set pin state high and enable transmitter * Interrupt setup - Enable timer C interrupt for kernel tick move.l #MFP_VECBASE, D0 move.b D0, MFP_VR or.b #$20, MFP_IERB ; Enable Timer C interrupt... move.b #$20, MFP_IMRB ; ... and unmask it. rts
The code for the handler is very simple:
TICK_HANDLER: bchg.b #0, MFP_GPDR rte
Because I'm using vectored interrupts, this should be on vector 0x45 (MFP_VECBASE is 0x40 and Timer C is at offset 5 in the MFP), but because of a limitation of my IO DTACK generation it's not actually working that way - the IO DTACK circuit doesn't take account of /IACK and so /DTACK is immediately asserted, presumably before the MFP can put the vector on the bus. This causes the vector to always be FF, so for now the handler is just mapped there for testing.
To actually fix this, I'll need to revisit the /IODTACK generator. I've not put anything down in EAGLE yet, but my plan is to build something like the following: