Top secrets sources NedoPC pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

#include <util/delay.h>

#include "mytypes.h"
#include "depacker_dirty.h"
#include "getfaraddress.h"
#include "pins.h"
#include "main.h"
#include "ps2.h"
#include "zx.h"
#include "spi.h"
#include "rs232.h"
#include "rtc.h"
#include "atx.h"
#include "joystick.h"
#include "tape.h"
#include "kbmap.h"

/** FPGA data pointer [far address] (linker symbol). */
extern ULONG fpga PROGMEM;

// FPGA data index..
volatile ULONG curFpga;

// Common flag register.
volatile UBYTE flags_register;

// Common modes register.
volatile UBYTE modes_register;

// Buffer for depacking FPGA configuration.
// You can USED for other purposed after setup FPGA.
UBYTE dbuf[DBSIZE];

void put_buffer(UWORD size)
{
        // writes specified length of buffer to the output
        UBYTE * ptr = dbuf;

        do
        {
                spi_send( *(ptr++) );

        } while(--size);
}

void hardware_init(void)
{
        //Initialized AVR pins

        cli(); // disable interrupts

        // configure pins

        PORTG = 0b11111111;
        DDRG  = 0b00000000;

//      PORTF = 0b11110000; // ATX off (zero output), fpga config/etc inputs
        DDRF  = 0b00001000;

        PORTE = 0b11110011;
        DDRE  = 0b00000000; // inputs pulled up, exclude PLL-control pins

        PORTD = 0b11111111;
        DDRD  = 0b00000000; // same

        PORTC = 0b11011111;
        DDRC  = 0b00000000; // PWRGOOD input, other pulled up

        PORTB = 0b11110001;
        DDRB  = 0b10000111; // LED off, spi outs inactive

        PORTA = 0b11111111;
        DDRA  = 0b00000000; // pulled up

        ACSR = 0x80; // DISABLE analog comparator
}

int main()
{
start:

        hardware_init();

        rs232_init();
#ifdef LOGENABLE
        to_log("VER:");
        {
                UBYTE b,i;
                ULONG version = 0x1DFF0;
                char VER[]="..";
                for( i=0; i<12; i++)
                {
                        dbuf[i] = pgm_read_byte_far(version+i);
                }
                dbuf[i]=0;
                to_log((char*)dbuf);
                to_log(" ");
                UBYTE b1 = pgm_read_byte_far(version+12);
                UBYTE b2 = pgm_read_byte_far(version+13);
                UBYTE day = b1&0x1F;
                UBYTE mon = ((b2<<3)+(b1>>5))&0x0F;
                UBYTE year = (b2>>1)&0x3F;
                VER[0] = '0'+(day/10);
                VER[1] = '0'+(day%10);
        to_log(VER);
        to_log(".");
                VER[0] = '0'+(mon/10);
                VER[1] = '0'+(mon%10);
        to_log(VER);
        to_log(".");
                VER[0] = '0'+(year/10);
                VER[1] = '0'+(year%10);
        to_log(VER);
        to_log("\r\n");
                //
                for( i=0; i<16; i++)
                {
                        b = pgm_read_byte_far(version+i);
                        VER[0] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
                        VER[1] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
                        to_log(VER);
                }
                to_log("\r\n");
        }
#endif

        wait_for_atx_power();

        spi_init();

        DDRF |= (1<<nCONFIG); // pull low for a time
        _delay_us(40);
        DDRF &= ~(1<<nCONFIG);
        while( !(PINF & (1<<nSTATUS)) ); // wait ready

        curFpga = GET_FAR_ADDRESS(fpga); // prepare for data fetching
#ifdef LOGENABLE
        {
        char log_fpga[]="F........\r\n";
        UBYTE b = (UBYTE)((curFpga>>24)&0xFF);
        log_fpga[1] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
        log_fpga[2] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
        b = (UBYTE)((curFpga>>16)&0xFF);
        log_fpga[3] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
        log_fpga[4] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
        b = (UBYTE)((curFpga>>8)&0xFF);
        log_fpga[5] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
        log_fpga[6] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
        b = (UBYTE)(curFpga&0xFF);
        log_fpga[7] = ((b >> 4) <= 9 )?'0'+(b >> 4):'A'+(b >> 4)-10;
        log_fpga[8] = ((b & 0x0F) <= 9 )?'0'+(b & 0x0F):'A'+(b & 0x0F)-10;
        to_log(log_fpga);
        }
#endif
        depacker_dirty();
#ifdef LOGENABLE
        to_log("depacker_dirty OK\r\n");
#endif

        //power led OFF
        LED_PORT |= 1<<LED;

        // start timer (led dimming and timeouts for ps/2)
        TCCR2 = 0b01110011; // FOC2=0, {WGM21,WGM20}=01, {COM21,COM20}=11, {CS22,CS21,CS20}=011
                            // clk/64 clocking,
                            // 1/512 overflow rate, total 11.059/32768 = 337.5 Hz interrupt rate
        TIFR = (1<<TOV2);
        TIMSK = (1<<TOIE2);


        //init some counters and registers
    ps2keyboard_count = 12;
        ps2keyboard_cmd_count = 0;
        ps2keyboard_cmd = 0;
        ps2mouse_count = 12;
        ps2mouse_initstep = 0;
        ps2mouse_resp_count = 0;
        flags_register = 0;
        modes_register = 0;

        //enable mouse
        zx_mouse_reset(1);

        //set external interrupt
        //INT4 - PS2 Keyboard  (falling edge)
        //INT5 - PS2 Mouse     (falling edge)
        //INT6 - SPI  (falling edge)
        //INT7 - RTC  (falling edge)
        EICRB = (1<<ISC41)+(0<<ISC40) + (1<<ISC51)+(0<<ISC50) + (1<<ISC61)+(0<<ISC60) + (1<<ISC71)+(0<<ISC70); // set condition for interrupt
        EIFR = (1<<INTF4)|(1<<INTF5)|(1<<INTF6)|(1<<INTF7); // clear spurious ints there
        EIMSK |= (1<<INT4)|(1<<INT5)|(1<<INT6)|(1<<INT7); // enable

        kbmap_init();
        zx_init();
        rtc_init();

#ifdef LOGENABLE
        to_log("zx_init OK\r\n");
#endif

        sei(); // globally go interrupting

        //set led on keyboard
        ps2keyboard_send_cmd(PS2KEYBOARD_CMD_SETLED);

        //main loop
        do
    {
            tape_task();
                ps2mouse_task();
        ps2keyboard_task();
        zx_task(ZX_TASK_WORK);
                zx_mouse_task();
                joystick_task();

                //event from SPI
                if ( flags_register&FLAG_SPI_INT )
                {
                        //get status byte
                        UBYTE status;
                        nSPICS_PORT &= ~(1<<nSPICS);
                        nSPICS_PORT |= (1<<nSPICS);
                        status = spi_send(0);
                        zx_wait_task( status );
                }

                atx_power_task();
    }
        while( (flags_register&FLAG_HARD_RESET) == 0 );

        goto start;
}