Close

Debugging

A project log for 8 Bit TTA Interpreter

TTA (Transport Triggered Architecture) is very simple CPU type.

agp.cooperagp.cooper 02/01/2019 at 06:330 Comments

Debugging

Need to get this project working.

One problem is that the Nano does not have enough pins.

So I have used a Meduino (a Mega2560 Pro Mini).

Here is the schematic:

Here is the PCB:

The ports (P1 & P2) match the TTA8 bus.

A problem with the Meduino is that pins do not align with the ports (unlike the  Nano).

So it is awkward to go fast. Awkward just means more coding. But do I really need to go fast? This time I have coded using pinMode, digitalRead and digitalWrite.

Here is the Mother Board I/O test code:

/*
  Front Panel Board Test
  ======================
REGISTERS:
  Hex  Address Write   Read      Comment
  FF   255     JMP     INTR      Jump/Intr
  FE   254     JC      Reserved  Jump on Carry
  FD   253     ROM     Reserved  ROM PAGE
  FC   252     RAM     Reserved  RAM PAGE
  FB   251     REGD    REGD      DATA REG
  FA   250     REGA    REGA      DATA REG ADDR
  F9   249     REGQ    NAND      ALU
  F8   248     REGP    ADD       ALU
  
SYSTEM (Pointer to Pointer Copy):
  Hex  Address Write   Read      Comment
  F7   247     JUMP    JUMP
  F6   246     POINTER POINTER 
  F5   245     DEPOSIT DEPOSIT 
  F4   244     FETCH   FETCH 
  F3   243     DATA    DATA      
  F2   242     ADDR    ADDR      
  F1   241     RETURN  RETURN  
  F0   240     PAGE    PAGE  
  
CPU MODEL:
  Hex  Address Write   Read      Comment
  EF   239     TEMP    TEMP      
  EE   238     DELAY   DELAY     
  ED   237     INTR    INTR      
  EC   236     MASK    MASK      
  EB   235     PP      PP        Page Pointer
  EA   234     IP      IP        Instruction Pointer
  E9   233     SP      SP        Return Stack Pointer
  E8   232     DX      DX        (Monitor Data I/O)
  E7   231     CX      CX        (Monitor Addr I/O)
  E6   230     BX      BX  
  E5   229     AX      AX  
  E4   228     TX      TX        Temp Register
  E3   STACK
  E2   STACK
  E1   STACK
  E0   STACK
  ...

  0xF8-0xFF REGISTERS  (8 registers)
  0xC0-0xF7 STATIC RAM (56 bytes at page 0xFF)
  0x80-0xBF PAGED RAM  (64 bytes)
  0x00-0x7F PAGED ROM  (128 bytes)
    
  CPU Emulation:
    This CPU has no actual opcodes.
    All instructions are MOVE from [PC] to [PC+1]
    i.e. Move DATA from source ADDRess to destination ADDRess.

    The 4 cycles are:
    1 Fetch the destination ADDRess pointed to by the program counter and put in the ADDR register
    2 Fetch destination DATA pointed to by the ADDR register and put and the DATA register
    2A  Increment the program counter (PC)
    3 Fetch destination ADDRess pointed to by the program counter and put in the ADDR register
    4 Deposit the DATA register into the destination pointed to by the ADDR register
    4A  Increment the program counter (PC)

    All hardware (PC,IO and ALU) is memory mapped.
*/    

// Board Connections:
//       Bus       Meduino Pin
//       VCC 
//       GND       Gnd
#define  RST       2
#define  CLR       3
#define  PC_OUT    4
#define  PC_CLK    5
#define  ADDR_OUT  6
#define  ADDR_CLK  7
#define  DATA_OUT  8
#define  DATA_CLK  9
#define  RD        10
#define  WR        11
#define  REGS      12
#define  CARRY     13
#define  LOAD      14
#define  SCLK      15
#define  Data0     16
#define  Data1     17
#define  Data2     18
#define  Data3     19
#define  Data4     20
#define  Data5     21
#define  Data6     22
#define  Data7     23
#define  Addr0     24
#define  Addr1     25
#define  Addr2     26
#define  Addr3     27
#define  Addr4     28
#define  Addr5     29
#define  Addr6     30
#define  Addr7     31
#define  Intr0     32
#define  Intr1     33
#define  Intr2     34
#define  Intr3     35
#define  Intr4     36
#define  Intr5     37
#define  Intr6     38
#define  Spare     39

void InitialiseBoard(void)
{ // Reset State
  pinMode(RST,INPUT_PULLUP);   // Dont care 
  pinMode(CLR,OUTPUT);         digitalWrite(CLR,LOW);
  pinMode(PC_OUT,OUTPUT);      digitalWrite(PC_OUT,LOW);
  pinMode(PC_CLK,OUTPUT);      digitalWrite(PC_CLK,LOW);
  pinMode(ADDR_OUT,OUTPUT);    digitalWrite(ADDR_OUT,HIGH);
  pinMode(ADDR_CLK,OUTPUT);    digitalWrite(ADDR_CLK,LOW);
  pinMode(DATA_OUT,OUTPUT);    digitalWrite(DATA_OUT,HIGH);
  pinMode(DATA_CLK,OUTPUT);    digitalWrite(DATA_CLK,LOW);
  pinMode(RD,OUTPUT);          digitalWrite(RD,HIGH);
  pinMode(WR,OUTPUT);          digitalWrite(WR,HIGH);
  pinMode(REGS,OUTPUT);        digitalWrite(REGS,HIGH);
  pinMode(CARRY,OUTPUT);       digitalWrite(CARRY,LOW);
  pinMode(LOAD,OUTPUT);        digitalWrite(LOAD,HIGH);
  pinMode(SCLK,OUTPUT);        digitalWrite(SCLK,HIGH);
  pinMode(Data0,INPUT_PULLUP);
  pinMode(Data1,INPUT_PULLUP);
  pinMode(Data2,INPUT_PULLUP);
  pinMode(Data3,INPUT_PULLUP);
  pinMode(Data4,INPUT_PULLUP);
  pinMode(Data5,INPUT_PULLUP);
  pinMode(Data6,INPUT_PULLUP);
  pinMode(Data7,INPUT_PULLUP);
  pinMode(Addr0,OUTPUT);       digitalWrite(Addr0,LOW);
  pinMode(Addr1,OUTPUT);       digitalWrite(Addr1,LOW);
  pinMode(Addr2,OUTPUT);       digitalWrite(Addr2,LOW);
  pinMode(Addr3,OUTPUT);       digitalWrite(Addr3,LOW);
  pinMode(Addr4,OUTPUT);       digitalWrite(Addr4,LOW);
  pinMode(Addr5,OUTPUT);       digitalWrite(Addr5,LOW);
  pinMode(Addr6,OUTPUT);       digitalWrite(Addr6,LOW);
  pinMode(Addr7,OUTPUT);       digitalWrite(Addr7,LOW);
  pinMode(Intr0,INPUT_PULLUP);
  pinMode(Intr1,INPUT_PULLUP);
  pinMode(Intr2,INPUT_PULLUP);
  pinMode(Intr3,INPUT_PULLUP);
  pinMode(Intr4,INPUT_PULLUP);
  pinMode(Intr5,INPUT_PULLUP);
  pinMode(Intr6,INPUT_PULLUP);
  pinMode(Spare,INPUT_PULLUP);
}

bool Reset(void)
{
  byte data;
  
  data=digitalRead(RST);
  if (data==0) {
    digitalWrite(CLR,LOW);
    return true;
  } else {
    digitalWrite(CLR,HIGH);
    return false;
  }
}

byte ReadAddr(byte addr)
{
  byte data;
  
  // SET DATABUS TO INPUT
  pinMode(Data0,INPUT_PULLUP);
  pinMode(Data1,INPUT_PULLUP);
  pinMode(Data2,INPUT_PULLUP);
  pinMode(Data3,INPUT_PULLUP);
  pinMode(Data4,INPUT_PULLUP);
  pinMode(Data5,INPUT_PULLUP);
  pinMode(Data6,INPUT_PULLUP);
  pinMode(Data7,INPUT_PULLUP);
    
  // SELECT ADDRESS
  digitalWrite(Addr0,addr&1);
  digitalWrite(Addr1,(addr>>1)&1);
  digitalWrite(Addr2,(addr>>2)&1);
  digitalWrite(Addr3,(addr>>3)&1);
  digitalWrite(Addr4,(addr>>4)&1);
  digitalWrite(Addr5,(addr>>5)&1);
  digitalWrite(Addr6,(addr>>6)&1);
  digitalWrite(Addr7,(addr>>7)&1);
  
  // READ DATA
  if (addr>=248) digitalWrite(REGS,LOW);
  digitalWrite(RD,LOW);
  delayMicroseconds(10);
  data=digitalRead(Data0);
  data|=digitalRead(Data1)<<1;
  data|=digitalRead(Data2)<<2;
  data|=digitalRead(Data3)<<3;
  data|=digitalRead(Data4)<<4;
  data|=digitalRead(Data5)<<5;
  data|=digitalRead(Data6)<<6;
  data|=digitalRead(Data7)<<7;
  digitalWrite(RD,HIGH);
  if (addr>=248) digitalWrite(REGS,HIGH);  
  return(data);
}

void WriteAddr(byte addr,byte data)
{
  // SELECT ADDRESS
  digitalWrite(Addr0,addr&1);
  digitalWrite(Addr1,(addr>>1)&1);
  digitalWrite(Addr2,(addr>>2)&1);
  digitalWrite(Addr3,(addr>>3)&1);
  digitalWrite(Addr4,(addr>>4)&1);
  digitalWrite(Addr5,(addr>>5)&1);
  digitalWrite(Addr6,(addr>>6)&1);
  digitalWrite(Addr7,(addr>>7)&1);

  // WRITE DATA
  if (addr>=248) digitalWrite(REGS,LOW);
  pinMode(Data0,OUTPUT);
  pinMode(Data1,OUTPUT);
  pinMode(Data2,OUTPUT);
  pinMode(Data3,OUTPUT);
  pinMode(Data4,OUTPUT);
  pinMode(Data5,OUTPUT);
  pinMode(Data6,OUTPUT);
  pinMode(Data7,OUTPUT);
  digitalWrite(Data0,data&1);
  digitalWrite(Data1,(data>>1)&1);
  digitalWrite(Data2,(data>>2)&1);
  digitalWrite(Data3,(data>>3)&1);
  digitalWrite(Data4,(data>>4)&1);
  digitalWrite(Data5,(data>>5)&1);
  digitalWrite(Data6,(data>>6)&1);
  digitalWrite(Data7,(data>>7)&1);
  digitalWrite(WR,LOW);
  delayMicroseconds(10);
  digitalWrite(WR,HIGH);
  if (addr>=248) digitalWrite(REGS,HIGH);

  // RESET DATABUS
  pinMode(Data0,INPUT_PULLUP);
  pinMode(Data1,INPUT_PULLUP);
  pinMode(Data2,INPUT_PULLUP);
  pinMode(Data3,INPUT_PULLUP);
  pinMode(Data4,INPUT_PULLUP);
  pinMode(Data5,INPUT_PULLUP);
  pinMode(Data6,INPUT_PULLUP);
  pinMode(Data7,INPUT_PULLUP);
}

void setup() {
  // Fire up the board
  InitialiseBoard();
  
  // Serial.begin(9600);
  // while (!Serial);
  // Serial.println();
}

void loop() {
  byte A=0;  
   
  // Check reset button
  if (!Reset()) {
    // ADDR LEDs and Switches
    WriteAddr(0XFA,0X00);
    A=ReadAddr(0XFB);
    WriteAddr(0XFB,A);
    // DATA LEDs and Switches
    WriteAddr(0XFA,0X01);
    A=ReadAddr(0XFB);
    WriteAddr(0XFB,A);
  } else {
    // RESET State
    // ADDR LEDs
    WriteAddr(0XFA,0X00);
    WriteAddr(0XFB,0xFF);
    // DATA LEDs
    WriteAddr(0XFA,0X01);
    WriteAddr(0XFB,0xFF);    
  }
  delay(100);
}

Testing

Fired up first time! Wow! Okay, I know the Mother Board works.

Here is the reset:

Here is A7:

And D7:

Trust me the rest work.

ALU Board

Next is the ALU Board. It works, no surprise as it tested out before.

ROM/RAM/StaticRAM Board

No it does not work. So far I have found two errors. The ROM page and RAM page are swapped, and the Static RAM (Addresses 192 to 247) are latched (wrong).

I forgot that the ROM/RAM pages are latched by a jump (i.e. JC or JMP).

For testing purposes I can fix these in software but still I cannot read the ROM or RAM data. I have to rework the code to make it easier to log the bus (i.e with a bus analyser).

Still no life out of the board. So the it is a chip select problem. Yes, U4 expects REGS high  but I design REGS low.

Fix. I can't fix this in software so time for a new board.

Interrupt Board

This board generates SCLK which is 38400 Hz. It uses the WR signal from the Controller Board. There is always a WR (and a RD) every 8 clock cycles (no more and no less).

Interrupts Intr0 through to Intr6 are external while Intr7 is connected to a 2400 Hz clock (SCLK/16). The interrupt address is 0xFF (read only). Reading the interrupt address clears Intr7. Intr& is used to control the serial card (along with SCLK).

Anyway, my tests tell me the Interrupt/Timing Board is working.

Program Counter Board

This board is controlled by the Controller Board (which previously tested okay (at least by the logic analyzer)).

Other than the Serial Board, this is the last board to test.

New Paged Memory Board

Populated the new Paged Memory Board.

Plug in Mother Board - Fail.

Test the Paged Memory Card:

Check FRAM in programmer:

Recheck Paged Memory Card:

Plug in Mother Board - Fail.

Test the Paged Memory Card:

This means something is writing to the FRAM as the WR signal is exposed.

Could be code or hardware responsible.

Something to look at tomorrow, otherwise progress has been made.
---

I set Software Data Protection (SDP) mode on the AT29C256 FRAM.

At least I think I have? I will find out shortly.

Anyway should not have to reprogram the FRAM after each test.

Now to find out why, is it the Monitor code or a hardware problem?

AlanX

Discussions