// Program to perform functions of Altair front panel with 8085 // Compiler Microchip C18 #include #include #include #include #pragma config WDT = OFF, OSC = INTIO2, LVP = OFF, MCLRE = OFF void main (void); void Stop(void); void Jump(const char, const char); void Deposit(const char); void Next(void); void Run(void); #define S0 PORTCbits.RC0 //S0 8085 status line #define S1 PORTCbits.RC1 //S1 8085 status line #define RAMRDDIS PORTAbits.RA5 //notRAMRDDIS disable RAM read #define nRAMWROUT PORTAbits.RA6 //notRAMWROUT force RAM write #define nCSOUT PORTAbits.RA7 //notCSOUT force chip select line for PIC parallel slave port #define STEP PORTBbits.RB4 //STEP step one 8085 machine cycle #define nRUNSTOP PORTBbits.RB5 //notRUN/STOP put 8085 into wait states #define nRESET PORTCbits.RC7 //notRESET 8085 reset line //echo program: /* const rom char buf[] = {076, 03, 0323, 020, 076, 021, 0323, 020, 0333, 020, 017, 0322, 010, 020, 0333, 021, 0323, 021, 0303, 010, 020}; const char NumBytes = 21; const char PL = 000; //PC low const char PH = 020; //PC high //4k basic bootloader: const rom char buf[] = {076, 03, 0323, 020, 076, 021, 0323, 020, 041, 0302, 077, 061, 032, 00, 0333, 020, 017, 0320, 0333, 021, 0275, 0310, 055, 0167, 0300, 0351, 013, 00 }; const char NumBytes = 28; const char PL = 000; //PC low const char PH = 00; //PC high */ //Turnkey monitor const rom char buf[] = {0x3E, 0x03, 0xD3, 0x10, 0x3E, 0x11, 0xD3, 0x10, 0x31, 0x00, 0x7C, 0xCD, 0x4A, 0x7D, 0x3E, 0x2E, 0xCD, 0x9F, 0x7D, 0xCD, 0x95, 0x7D, 0xFE, 0x4D, 0xCA, 0x24, 0x7D, 0xFE, 0x4A, 0xC2, 0x08, 0x7D, 0xCD, 0x54, 0x7D, 0xE9, 0xCD, 0x54, 0x7D, 0x3E, 0x23, 0xCD, 0x4A, 0x7D, 0x54, 0x5D, 0xCD, 0x76, 0x7D, 0x1A, 0x67, 0xCD, 0x7C, 0x7D, 0xCD, 0x55, 0x7D, 0xEB, 0xDA, 0x28, 0x7D, 0x77, 0xBE, 0xCA, 0x28, 0x7D, 0x3E, 0x3F, 0xCD, 0x9F, 0x7D, 0xC3, 0x08, 0x7D, 0x3E, 0x0D, 0xCD, 0x9F, 0x7D, 0x3E, 0x0A, 0xC3, 0x9F, 0x7D, 0x06, 0x06, 0x03, 0x21, 0x00, 0x00, 0xCD, 0x95, 0x7D, 0x4F, 0xFE, 0x20, 0x37, 0xC8, 0xE6, 0xB8, 0xEE, 0x30, 0xC2, 0x42, 0x7D, 0x79, 0xE6, 0x07, 0x29, 0x29, 0x29, 0x85, 0x6F, 0x05, 0xC2, 0x5A, 0x7D, 0xC9, 0x06, 0x06, 0xAF, 0xC3, 0x83, 0x7D, 0x06, 0x03, 0xE6, 0x29, 0x17, 0x29, 0x17, 0x29, 0x17, 0xE6, 0x07, 0xF6, 0x30, 0xCD, 0x9F, 0x7D, 0x05, 0xC2, 0x7F, 0x7D, 0x3E, 0x20, 0xC3, 0x9F, 0x7D, 0xDB, 0x10, 0x0F, 0xD2, 0x95, 0x7D, 0xDB, 0x11, 0xE6, 0x7F, 0xF5, 0xDB, 0x10, 0x0F, 0x0F, 0xD2, 0xA0, 0x7D, 0xF1, 0xD3, 0x11, 0xC9}; const int NumBytes = 171; const char PL = 0x00; //PC low const char PH = 0x7D; //PC high //---------------------------------------------------------------------------- void main (void) { int i; // OSC settings OSCCONbits.IRCF2 = 1; //Set osc to be 8 MHZ OSCCONbits.IRCF1 = 1; //OSCCON<2:0> = 111; OSCCONbits.IRCF0 = 1; // PORTC = 0x00; //notRESET = 0 TRISC = 0x03; //all outputs except S0, S1 PORTA = 0xE0; //RAMRDDIS = 1, notRAMWROUT = 1, notCSOUT = 1 TRISA = 0x0F; //A11:A8 inputs, rest outputs PORTB = 0x20; //notRUN/STOP = 1, STEP = 0 TRISB = 0xCF; //notRUN/STOP outputs, rest inputs PORTD = 0; TRISD = 0xFF; //All inputs TRISE = 0x17; //enable PSP, port E all inputs //turn off analog ADCON1 = 0x0F; //all digital I/O // set up PWM for 9600 Baud rate clock output OpenTimer2(TIMER_INT_OFF & T2_PS_1_1); OpenPWM1(12); SetDCPWM1(26); Delay100TCYx(100); //10000 cycles = 5 milliseconds nRESET = 1; //release reset Stop(); Jump(PL, PH); for (i = 0; i < NumBytes; ++i) { Deposit(buf[i]); Next(); } Jump(PL, PH); PORTD = 0; //sense switch setting Run(); while(1); } // Stop 8085 - put into wait state cycles - at next instruction fetch cycle void Stop(void) { nRUNSTOP = 1; //stop Delay10TCYx(1); //delay for 5 micro seconds while (!(S0 && S1)) //if S0 and S1 not both high (instruction fetch) { STEP = 1; STEP = 0; //pulse STEP to go to next cycle Delay10TCYx(1); //delay for 5 micro seconds } } //Jump to memory location (PL,PH) by jamming a JMP instruction void Jump(const char PL, const char PH) { PORTD = 0303; //JMP instruction RAMRDDIS = 1; //disable RAM nCSOUT = 0; //force PSP select so value will be read from PSP STEP = 1; STEP = 0; //pulse STEP to go to next cycle Delay10TCYx(1); //delay for 5 micro seconds PORTD = PL; //low byte of address STEP = 1; STEP = 0; //pulse STEP to go to next cycle Delay10TCYx(1); //delay for 5 micro seconds PORTD = PH; //high byte of address STEP = 1; STEP = 0; //pulse STEP to go to next cycle Delay10TCYx(1); //delay for 5 micro seconds nCSOUT = 1; //don't force PSP select RAMRDDIS = 0; //re-enable RAM } //Write value Data to current memory location void Deposit(const char Data) { PORTD = Data; RAMRDDIS = 1; //disable RAM RD nCSOUT = 0; //force PSP select - reading value from PSP nRAMWROUT = 0; //pulse nRAMWROUT - writing to RAM nRAMWROUT = 1; nCSOUT = 1; RAMRDDIS = 0; } //Advance address to next location by jamming a NOP instruction void Next(void) { PORTD = 0; //NOP instruction RAMRDDIS = 1; //disable RAM nCSOUT = 0; //force PSP select STEP = 1; STEP = 0; //pulse STEP to go to next cycle Delay10TCYx(1); //delay for 5 micro seconds nCSOUT = 1; //don't force PSP select RAMRDDIS = 0; //re-enable RAM } //Take 8085 out of wait states and start running void Run(void) { nRUNSTOP = 0; //run }