It's big so I hoped it can be avoided. It's a work in progress obviously.
Some parts are speed-sensitive (everything around mute()).
The program is split onto three separate files:
main:
//multiplexer PD4-PD7
//#define MULTI_A 4
//#define MULTI_B 5
//#define MULTI_C 6
//#define MULTI_D 7
//befor milis -> micros:
//Memtest 32k, noisy - 38 min
//Memtest 32k silent - 4:15 min
//milis -> micros:
#define MULTI_OUT 3
#define MULTI_MASK B00001000
//This will show how long takes to do one loop
// It may be needed to lower FLASH_SIZE while using it.
//#define TIME_TWEAK
#define Z80_DATA_READ PINB
#define Z80_DATA_WRITE PORTB
#define Z80_DATA_DIR DDRB
#define Z80_DATA_DIR_OUT DDRB = 255;
#define Z80_DATA_DIR_IN DDRB = 0;
#define Z80_CTRL_READ PINC
#define Z80_CTRL_WRITE PORTB
#define Z80_CTRL_DIR DDRC
#define Z80_MASK_CLK B00000001
#define Z80_MASK_RESET B00000010
#define Z80_MASK_WR B00000100
#define Z80_MASK_RD B00001000
#define Z80_MASK_MREQ B00010000
#define Z80_MASK_IRQ B00100000
#define Z80_MASK_MREQ_RD B00011000
#define MAX_CLK 20000
#define Z80_PIN_CLK A0
#define Z80_ROM_END 32767
//Serial input buffer size in bytes (not char number). 255 max
#define COMMAND_MAX_LENGHT 32
#define FLASH_SIZE 512
#define SERIAL_BUFFER_SIZE 128
#define HEADER_COUNT 64
#define FLASHDUMP_COLS 32
bool dataReadOnly = 1;
bool clkInternal = 0;
//bool prevClk = 0;
bool oldRead = 0;
bool ctrlClk = 0;
bool ctrlRst = 0;
bool ctrlWr = 0;
bool ctrlRd = 0;
bool ctrlMreq = 0;
bool ctrlIrq = 0;
unsigned long currentAdress = 0;
//unsigned long prevAdress = 0;
byte currentData = 0;
unsigned long tClock = 100000; //1000000/(tClock) = Hz
unsigned long nextTick = 0;
unsigned long nextHalfTick = 0;
byte cnt = 0;
//unsigned char memoryFake[COMMAND_MAX_LENGHT];
unsigned char serialFlash[COMMAND_MAX_LENGHT];
//unsigned byte serialFlashCount = 0;
unsigned char flash[FLASH_SIZE];
unsigned char sfCount = 0;
bool written = 0;
//byte debug = 0;
//byte dt;
bool simulation = 0;
bool mute = 0;
bool showMicros = 0;
char serialBuffer[SERIAL_BUFFER_SIZE];
int serialStringLength = 0;
//unsigned long lastTickMicros = 0;
#ifdef TIME_TWEAK
//for time tweak
unsigned long time_loopStart, time_loopEnd, time_sum;
byte timeNo = 0;
#define TTLENGHT 12
unsigned long time_table[TTLENGHT];
#endif
void setup() {
//TODO:
//avrdude -c usbasp -p m8 -U cal:r:-:h (values for 1, 2, 4 and 8 MHz)
//https://www.mexchip.com/en/2018/05/using-atmega8a-oscillator-calibration-byte/
OSCCAL = 0xaa; // apply calibration value for 8 MHz
Serial.begin(115200);
Serial.print(F("External clock: "));
DDRD = DDRD | B11110000;
flashErase();
setDataOutput(0);
readControlPort();
//prevClk = ctrlClk;
//doReset();
delay(1000);
if(externalClock()){
setInternalClk(0);
}else{
Serial.print(F("not "));
setInternalClk(1);
}
Serial.println(F("available"));
doReset();
printHelp();
printHead();
}
void loop() {
//Needed for LCD?
__builtin_avr_delay_cycles (4);
if(clkInternal){
while(micros() < nextHalfTick){;}
//TODO: port mnipulation
digitalWrite(Z80_PIN_CLK, LOW);
//readSerialInput(); //read Serial only between ticks
while(Serial.available()){
//Serial.println();
char c = Serial.read();
//Serial.println(c);
cumulateSerial(c);
delayMicroseconds(150);
}
while(micros() < nextTick){;}
//TODO: port mnipulation
digitalWrite(Z80_PIN_CLK, HIGH);
nextTick = micros() + tClock;
nextHalfTick = nextTick - tClock/2;
}else{
//TODO
}
//maybe "fullSpeed" variable?
if(simulation && mute){
//CTRL Port is read in muteFlash function
muteFlash();
}else{
//TODO: check for faster
readControlPort();
if(showMicros){
Serial.print(micros());
if(mute){
Serial.println();
}else{
Serial.print(F(" "));
}
}
noisy();
}
}
flash
//######### flash ###########
void flashErase(){
for(int i = 0; i < FLASH_SIZE; i++){
flash[i] = 0x00;
}
}
void flashWrite(){
int bytesNo, checksum;
int adress = 0;
unsigned char hn, ln, cmd;
//Get bytes number
bytesNo = convChar(serialBuffer[1]) * 16;
bytesNo += convChar(serialBuffer[2]);
Serial.print(F("Bytes no: "));
if(bytesNo < 10){
Serial.print(F("0"));
}
Serial.print(bytesNo);
if(bytesNo > 32){
Serial.println(F(". To many bytes - ignore"));
return;
}
//TODO:
//Check if bytes number corresponds with accumulated rs
//Read starting adress
for(int i = 0; i < 4; i++){
adress = adress * 16 + convChar(serialBuffer[3+i]);
}
Serial.print(F(". Start adress: "));
Serial.print(adress);
Serial.print(F("\t:xxXXXXxx"));
//TODO
//if adress + bytesNo > flash_SIZE, dont...
//Data type check
if(serialBuffer[7] != '0' || serialBuffer[8] != '0'){
Serial.println(F(" Not data. OK"));
return;
}
//Data receive
for(int i = 0; i < bytesNo; i++){
hn = convChar(serialBuffer[9+i*2]);
ln = convChar(serialBuffer[10+i*2]);
cmd = (hn << 4 ) | ln;
flash[adress + i] = cmd;
if(cmd < 16){
Serial.print(F("0"));
}
Serial.print(cmd, HEX);
}
Serial.println(F("xx"));
//Ignore checksum
//TODO?
}
void flashDumpHex(){
byte cs = 0;
Serial.print(F("\t "));
for(int i = 0; i < FLASHDUMP_COLS; i++){
Serial.print(i%10);
Serial.print(F(" "));
}
Serial.print(F("CS"));
for(int i = 0; i < FLASH_SIZE; i++){
if (i%FLASHDUMP_COLS == 0){
Serial.println();
Serial.print(F(":"));
Serial.print(FLASHDUMP_COLS, HEX);
if(i < 0x10){
Serial.print(F("000"));
}else if(i < 0x100){
Serial.print(F("00"));
}else if(i < 0x1000){
Serial.print(F("0"));
}
Serial.print(i, HEX);
Serial.print(F("00"));
//Serial.print(":\t");
//Serial.print(":");
cs = FLASHDUMP_COLS + i + (i>>8);
}
if(flash[i] < 0x10){
Serial.print(F("0"));
}
Serial.print(flash[i], HEX);
cs += flash[i];
if((i+1)%FLASHDUMP_COLS == 0){
//Serial.print(F(" "));
if((byte)(256 - cs) < 0x10){
Serial.print(F("0"));
}
Serial.print((byte)(256 - cs), HEX);
}
}
Serial.println(F("\n:00000001FF"));
}
void readSerialFlash(){
//writeToSerialFlash(c, convChar(Serial.read()));
while(Serial.available() > 1){
writeToSerialFlash(convChar(Serial.read()), convChar(Serial.read()));
}
}
void writeToSerialFlash(unsigned char ln, unsigned char hn){
unsigned char cmd;
if(hn < 16 && ln < 16){
cmd = (hn << 4 ) | ln;
serialFlash[sfCount++] = cmd;
// Serial.print("Got: ");
// Serial.println(cmd, HEX);
}
}
void printSerialFlash(){
// Serial.print(F("Serial flash: "));
for (int i = 0; i < sfCount; i++){
Serial.print(serialFlash[i], HEX);
}
//Serial.println();
}
byte serialFlashByte(){
byte zero;
zero = serialFlash[0];
for(int i = 1; i < sfCount; i++){
serialFlash[i-1] = serialFlash[i];
}
sfCount--;
return zero;
}
serial
//######### serial input ###########
void cumulateSerial(char c){
//char c = Serial.read();
// Serial.println();
// Serial.print(F("Got new sign: "));
Serial.print(c);
// Serial.print(F(" 0x"));
// Serial.println(c, HEX);
//return;
//TODO : convChar()
// On carriage return, process the received data.
if (c == '\r' || c == '\n' || c == ' ') {
// Properly terminate the string.
serialBuffer[serialStringLength] = '\0';
if(serialStringLength > 0){
Serial.print(F("serialBuffer: "));
Serial.println(serialBuffer);
readSerialInput();
}
serialStringLength = 0;
//Serial.println(F("End of string."));
}
// Otherwise buffer the incoming byte.
else if (c > ' ' && c < 127) {
if(serialStringLength < SERIAL_BUFFER_SIZE - 1){
Serial.print(F("Add to string: "));
Serial.println(c);
serialBuffer[serialStringLength++] = c;
}else{
Serial.println(F("sSL overload!"));
}
//Serial.println(F("Cumulate."));
}
}
inline void readSerialInput(){
char c = serialBuffer[0];
if(c == '?'){
printHelp();
}
if(c == 'R'){
doReset();
}else if (c == '$'){
setConfig(serialBuffer[1]);
/*}else if(c != '\n' && c != '\r'){
memoryFake[mfCount++] = c;
}*/
//TODO serial flash
// }else if(Serial.available() > 1 &&
// convChar(c) < 16){
// readSerialFlash();
// //printSerialFlash();
// //Serial.println();
}else if(c == ':'){
flashWrite();
}else if(convChar(c) >= 16){
Serial.read();
}else{
Serial.print(F("Error serial command: "));
Serial.println(c);
Serial.read();
}
}
//void readSerialInput(){
// while(Serial.available()){
// char c = Serial.peek();
// Serial.print(F("Command received: "));
// Serial.println(c);
//
// if(c == ':'){
// Serial.read();
// flashWrite();
// }else{
// Serial.read();
// }
// }
//}
//inline void readSerialInput(){
// int flines = 0;
// //delay(2); //delay to allow byte to arrive in input buffer
// while (Serial.available()) {
// delay(2);
// char c = Serial.peek();
//
// if(c == '?'){
// Serial.read();
// printHelp();
// }
// if(c == 'R'){
// Serial.read();
// doReset();
// }else if (c == '$'){
// Serial.read();
// setConfig(Serial.read());
// /*}else if(c != '\n' && c != '\r'){
// memoryFake[mfCount++] = c;
// }*/
// }else if(Serial.available() > 1 &&
// convChar(c) < 16){
// readSerialFlash();
// //printSerialFlash();
// //Serial.println();
// }else if(c == ':'){
// //nextTick = millis() + 200;
// while(Serial.peek() == ':'){
// flines++;
// Serial.read();
// flashWrite();
// }
// Serial.print(F("Flash lines: "));
// Serial.println(flines);
// }else if(convChar(c) >= 16){
// Serial.read();
// }else{
// Serial.print(F("Error serial command: "));
// Serial.println(c);
// Serial.read();
// }
// }
//}
void setConfig(char mode){
/*if(mode == 'o' || mode == 'O'){
dataReadOnly = 1;
}else*/
if(mode == 'w' || mode == 'W'){
dataReadOnly = !dataReadOnly;
// }else if(mode == 'd' || mode == 'D'){
// debug = !debug;
}else if(mode == 'r' || mode == 'R'){
doReset();
}else if(mode == 's' || mode == 'S'){
Serial.println(F("TODO"));
//setClkHz();
}else if(mode == 'f' || mode == 'F'){
flashDumpHex();
}else if(mode == 'e' || mode == 'E'){
flashErase();
}else if(mode == 'a' || mode == 'A'){
//flashErase();
dataReadOnly = 0;
simulation = !simulation;
doReset();
}else if(mode == 'x' || mode == 'X'){
simulation = 0;
}else if(mode == 'u' || mode == 'U'){
showMicros = !showMicros;
}else if(mode == 'm' || mode == 'M'){
mute = !mute;
Serial.print(F("Mute mode is: "));
Serial.println(mute);
}
}
void setClkHz(){
int readVal = 0;
int newVal = 0;
while (Serial.available()) {
delay(2); //delay to allow byte to arrive in input buffer
char c = Serial.read();
if(c >= '0' && c <= '9'){
readVal = readVal * 10 + c - '0';
}else{
break;
}
}
if(readVal <= MAX_CLK && readVal > 0){
tClock = 1000000/readVal;
Serial.print(F("New clock value [Hz]: "));
Serial.println(readVal);
Serial.print(F("tClock: "));
Serial.print(tClock);
Serial.println(F(" uS."));
}else{
Serial.println(F("Wrong clock value."));
}
}
byte convChar(char ch){
if(ch >= '0' && ch <= '9'){
return ch - '0';
}
if(ch >= 'A' && ch <= 'F'){
return ch - 'A' + 10;
}
if(ch >= 'a' && ch <= 'f'){
return ch - 'a' + 10;
}
}
//################# Serial info #############
void printHelp(){
Serial.println(F("\nHelp (?):"));
Serial.println(F("$r|$R|R - reset Z80"));
Serial.println(F("$[w|W] - swich write mode"));
//Serial.println(F("$[d|D] - swich debug mode"));
//Serial.println(F("$[t|T] - swich internal/external clock"));
Serial.print(F("$[s|S]{val} - set clck to val in Hz (1 to MAX_CLKHz)"));
Serial.println(MAX_CLK);
Serial.println(F("$[f|F] - dump FLASH in HEX"));
Serial.println(F("$[e|E] - erase flash"));
Serial.println(F("$[a|A] - start simulation"));
Serial.println(F("$[x|X] - stop simulation"));
Serial.println(F("$[m|M] - mute mode"));
Serial.println(F("$[u|U] - show/hide micros"));
Serial.println(F(": ... - put Intel HEX into flash memory"));
Serial.println();
}
void printHead(){
//Serial.println(F("RO Sim | Clk Rst Wr Rd MRq IRq| Adress\t| Comment\t\t\t\t| BIN\t\tHEX\tDEC"));
//Serial.print(F("RO Sim | Wr Rd MRq IRq | Adress\t| Comment\t\t\t\t| BIN\t HEX ASCII"));
Serial.print(F("RO Sim | Adress\t| Comment\t\t| BIN\t HEX ASCII"));
if(sfCount){
Serial.print(F("\t| SerialFlash"));
}
Serial.println();
}
void printInfo(){
Serial.print(F(" "));
Serial.print(dataReadOnly);
Serial.print(F(" "));
Serial.print(simulation);
Serial.print(F(" | "));
// Serial.print(ctrlClk);
// Serial.print(F(" "));
// Serial.print(ctrlRst);
// Serial.print(F(" "));
/* Serial.print(ctrlWr);
Serial.print(F(" "));
Serial.print(ctrlRd);
Serial.print(F(" "));
Serial.print(ctrlMreq);
Serial.print(F(" "));
Serial.print(ctrlIrq);
Serial.print(F(" | "));*/
Serial.print(currentAdress, HEX);
Serial.print(F("\t| "));
}
void printData(){
Serial.print(F("\t| B"));
for(int i = 7; i >= 0; i--){
Serial.print(bitRead(currentData,i));
}
Serial.print(F(" 0x"));
//Serial.print(currentData, HEX);
if (currentData<0x10) {
Serial.print(F("0"));
}
Serial.print(currentData, HEX);
Serial.print(F(" "));
Serial.print((char)currentData);
}
simulate
//######### simulate ###########
inline void muteFlash(){
if(Z80_CTRL_READ&Z80_MASK_MREQ_RD){
//NOT read from any memory
Z80_DATA_DIR_IN
Z80_DATA_WRITE = 0;
}else{
//MREQ = 0 AND RD = 0 -> read from memory
//read current adress
readSilentSimulationAdress();
if(currentAdress < FLASH_SIZE){
//put current flash byte to DATA port
Z80_DATA_DIR_OUT
Z80_DATA_WRITE = flash[currentAdress];
}else if(currentAdress <= Z80_ROM_END){
//if adress does not lay between flash and ram, exit simulation
simulationOff();
Z80_DATA_DIR_OUT
Z80_DATA_WRITE = 0;
}
}
}
void noisy(){
//read current adress
readAdress();
//Print header info from time to time
if(cnt++ == HEADER_COUNT){
printHead();
cnt = 0;
}
if(ctrlMreq == 0 && ctrlRd == 0 && ctrlIrq == 1 && ctrlWr == 1){
if(written == 0){
//if it is new read cycle
printInfo();
Serial.print(F("Z80 <- MEM ("));
if(currentAdress > Z80_ROM_END){
//we are outside of ROM, probably in RAM
readData();
Serial.print(F("RAM)"));
}else if(dataReadOnly == 0){
if(simulation == 1){
currentData = flash[currentAdress];
Serial.print(F("Sim.)"));
}else if(sfCount){
currentData = serialFlashByte();
Serial.print(F("Serial)"));
}else{
currentData = 0;
Serial.print(F("NOP)"));
}
Z80_DATA_DIR_OUT
Z80_DATA_WRITE = currentData;
}else{
//Serial.print(" | Read-only mode: ");
if(sfCount > 0){
currentData = serialFlashByte();
}else{
currentData = 0;
}
Serial.print(F("R/O)"));
}
printData();
if(sfCount){
Serial.print(F("\t| "));
printSerialFlash();
}
Serial.println();
written = 1;
}
}else{
Z80_DATA_DIR_IN
Z80_DATA_WRITE = 0;
}
if(ctrlMreq == 1 && ctrlRd == 1 && ctrlIrq == 1 && ctrlWr == 1){
oldRead = 0;
written = 0;
}
if(oldRead == 0){
if(ctrlMreq == 0 && ctrlRd == 1 && ctrlIrq == 1 && ctrlWr == 0){
//Z80 writes to memory
printInfo();
Serial.print(F("Z80 -> MEM"));
if(currentAdress > Z80_ROM_END){
//we are outside of ROM, probably in RAM
Serial.print(F(" (RAM)"));
}else{
Serial.print(F("\t"));
}
readData();
printData();
Serial.println();
oldRead = 1;
}else if(ctrlMreq == 1 && ctrlRd == 0 && ctrlIrq == 0 && ctrlWr == 1){
printInfo();
Serial.print(F("Z80 <- IO\t"));
readData();
printData();
Serial.println();
oldRead = 1;
}else if(ctrlMreq == 1 && ctrlRd == 1 && ctrlIrq == 0 && ctrlWr == 0){
printInfo();
Serial.print(F("Z80 -> IO\t"));
readData();
printData();
Serial.println();
oldRead = 1;
}
}
}
inline void checkSimulationAdress(){
if(
simulation
&& currentAdress > FLASH_SIZE
&& currentAdress <= Z80_ROM_END
&& ctrlRd == 0
&& ctrlMreq == 0
){
simulationOff();
}
}
void simulationOff(){
simulation = 0;
Serial.println();
Serial.print(currentAdress);
Serial.println(F(": Simulation off"));
}
z80
//######### z80 read ###########
void readControlPort(){
byte ctrl;
ctrl = Z80_CTRL_READ;
ctrlClk = ctrl & Z80_MASK_CLK;
ctrlRst = ctrl & Z80_MASK_RESET;
ctrlWr = ctrl & Z80_MASK_WR;
ctrlRd = ctrl & Z80_MASK_RD;
ctrlMreq = ctrl & Z80_MASK_MREQ;
ctrlIrq = ctrl & Z80_MASK_IRQ;
}
void readAdress(){
//MULTI OUT 3
currentAdress = 0;
for(int i = 15; i>=0; i--){
setMultiplexer(i);
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){
currentAdress++;
}
}
checkSimulationAdress();
}
inline void readSilentSimulationAdress(){
//MULTI OUT 3
currentAdress = 0;
// for(char i = 15; i>=0; i--){
// //setMultiplexer(i);
// PORTD = i << 4;
//
// currentAdress = currentAdress << 1;
//
// if(PIND&MULTI_MASK){
// currentAdress++;
// }
// }
PORTD = B11110000; //15
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B11100000; //14
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B11010000; //13
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B11000000; //12
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B10110000; //11
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B10100000; //10
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B10010000; //09
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B10000000; //08
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B01110000; //07
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B01100000; //06
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B01010000; //05
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B01000000; //04
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B00110000; //03
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B00100000; //02
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B00010000; //01
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
PORTD = B00000000; //00
currentAdress = currentAdress << 1;
if(PIND&MULTI_MASK){currentAdress++;}
// if(currentAdress > FLASH_SIZE){
// simulation = 0;
// Serial.println();
// Serial.print(currentAdress);
// Serial.println(F(": Simulation off"));
// }
}
inline void readData(){
currentData = Z80_DATA_READ;
}
//######### z80 drive/set ###########
void doReset(){
//TODO: check if there is a clock source on!
Serial.print(F("Reset"));
setReset(0);
if(clkInternal){
for(int i = 0; i < 7; i++){
digitalWrite(Z80_PIN_CLK, !digitalRead(Z80_PIN_CLK));
delay(10);
}
}else{
byte clkCnt=0;
bool clkLastState=0;
bool clk = 0;
//wait for clk LOW
while(Z80_CTRL_READ & Z80_MASK_CLK){;}
while(clkCnt < 7){
clk = Z80_CTRL_READ & Z80_MASK_CLK;
//Serial.print(clk);
if(clkLastState != clk){
clkCnt++;
clkLastState = clk;
//Serial.println("...");
}
}
}
setReset(1);
Serial.println(F("."));
}
//Check if there is external clock source
bool externalClock(){
unsigned long stopTime = millis() + 2000;
bool on=0;
//TODO: convert to port manipulation?
pinMode(Z80_PIN_CLK , INPUT_PULLUP);
while(millis() < stopTime){
if((Z80_CTRL_READ & Z80_MASK_CLK) == 0){
//if something pulls down clk down then there is
// external clock source.
on = 1;
break;
}
}
return on;
}
//enable A8 internal clock
void setInternalClk(bool setClk){
if(setClk){
clkInternal = 1;
//TODO: convert to port manipulation?
pinMode(Z80_PIN_CLK, OUTPUT);
digitalWrite(Z80_PIN_CLK, LOW);
nextTick = millis() + tClock;
}else{
clkInternal = 0;
//TODO: convert to port manipulation?
pinMode(Z80_PIN_CLK, INPUT);
}
}
void setMultiplexer(int val){
//PORTD = PORTD | (B11110000 & (val << 4));
PORTD = val << 4;
//}
}
void setReset(bool r){
//TODO: convert to Port Manipulation
if(r){
pinMode(15, INPUT_PULLUP);
}else{
pinMode(15, OUTPUT);
digitalWrite(15, LOW);
}
}
void setDataOutput(bool en){
if(en && !dataReadOnly){
DDRB = B11111111; // sets Arduino pins 8 to 15 as outputs
}else{
DDRB = B00000000; // sets as inputs
}
}