cdunku
cdunku

Reputation: 31

LHLD doesn't assign a value to register HL

so I'm in the stages of finishing my Intel 8080 emulator and encountered a problem with the LHLD mnemonic. So, whenever I run the Altair Clone CPU Test Files I encounter a bug. So I have a sequence of 4 files being executed at a time and they are:

TST8080.COM

CPUTEST.COM

8080PRE.COM

8080EXM.COM

They all run and execute accordingly until the last file which bugs. (LHLD is ran in the TST8080.COM and no problem seems to occur). I've experienced this problem only in the last file, the nextWord and readWord function mostly well in the previous files. I've tried testing and debugging. Here is the code and output:

Functions used in the LHLD function:

void set_pair(i8080* const s, uint8_t pair, uint16_t value)
{
  uint8_t high = (value >> 8) & 0xFF;
  uint8_t low = value & 0xFF;
  switch(pair)
  {
    case 0:
      s->b = high;
      s->c = low;
      break;
    case 1:
      s->d = high;
      s->e = low;
      break;
    case 2:
      s->h = high;
      s->l = low;
      break;
    case 3:
      s->sp = (high << 8) | (low & 0xFF);
      break;
    default:
      printf("\nCouldn't set pair.\n");
      break;
  }

uint16_t readWord(i8080* const s, uint16_t addr)
{
    return (readByte(s, addr + 1) << 8 | readByte(s, addr));
}

uint16_t nextWord(i8080* const s)
{
    uint16_t word = readWord(s, s->pc);
    s->pc += 2;
    return word;
}

LHLD function:

void lhld(i8080* const s, uint8_t opcode)
{
  set_pair(s, opcode & 0x7, readWord(s, nextWord(s)));
}

The problem I noticed while testing was that the nextWord function isn't read, making it 0.

I read and checked the PC value and before LHLD it's = 0x0006 When nextWord is called it should be read into memory, but when it's read into memory it becomes 0?

BEFORE LHLD: 0x0006 // Before LHLD operations

BEFORE VALUE: 0x0000 // Value inputted to set_pair


AFTER VALUE: 0x0000, 0x0000, 0x0000 // After low, high and value are set in set_pair


AFTER LHLD: 0x11F9 // PC value read into memory (In hex)

AFTER LHLD: 4601 // PC value read into memory (In decimal)

H: 0x0000, L: 0x0000 // Value of H and L registers after LHLD

All instructions are called accordingly and everything else works. I've also tried solving the problem with a debugger notably LLDB, I've checked the variable values and how it effects the program; This is what I got for the variables called during the LHLD operation (JMP a16 is also included here since I thought it had to do with the bug, JMP is the first instruction called during the execution of the file then LHLD follows):

AF = 0002 BC = 0000 DE = 0000 HL = 0000 PC = 0100 SP = 0000 CYC = 0  (C3 13 01 00)
F = 2 SF = 0 ZF = 0 HF = 0 PF = 0 CF = 0
 - JMP, $

opcode='\xc3'

nextWord function: addr=257

opcode='\xc3'

jump function: addr=275

opcode='\xc3'

opcode='\xc3'

opcode='\xc3'

AF = 0002 BC = 0000 DE = 0000 HL = 0000 PC = 0113 SP = 0000 CYC = 10  (2A 06 00 F9)
F = 2 SF = 0 ZF = 0 HF = 0 PF = 0 CF = 0
 - LHLD, $

opcode='*'

opcode='*'

opcode='*'

After nextWord function during the read: addr=276

opcode='*'

readWord is called again = addr=6

opcode='*'

opcode='*'

opcode='*'

opcode='*'

NOTE: The reason I mentioned a variable several times in a row is because this is the sequence of the variable values shown until it comes to the next instruction (MVI C, d8).

Thank you in advance, I hope this is enough information.

UPDATE: So I've tried the following code below:

void lhld(i8080* const s, uint8_t opcode)
{
  readWord(s, nextWord(s));
  set_pair(s, opcode & 0x7, readWord(s, nextWord(s)));
}

This actually continues execution till some extent, this of course is a bug but it's quite interesting that with readWord(s, nextWord(s)); the output is:

*** FILE LOADED: test_files/TST8080.COM
MICROCOSM ASSOCIATES 8080/8085 CPU DIAGNOSTIC
 VERSION 1.0  (C) 1980

 CPU HAS FAILED!    ERROR EXIT=0521

*** FILE LOADED: test_files/CPUTEST.COM

DIAGNOSTICS II V1.2 - CPU TEST
COPYRIGHT (C) 1981 - SUPERSOFT ASSOCIATES

ABCDEFGHIJKLMNOPQRSTUVWXYZ
CPU IS 8080/8085
BEGIN TIMING TEST
END TIMING TEST


*** FILE LOADED: test_files/8080PRE.COM
8080 Preliminary tests complete

*** FILE LOADED: test_files/8080EXM.COM
dad <b,d,h,sp>................Program executed in 0 seconds

and without the readWord(s, nextWord(s)); we have the output:

*** FILE LOADED: test_files/TST8080.COM
MICROCOSM ASSOCIATES 8080/8085 CPU DIAGNOSTIC
 VERSION 1.0  (C) 1980

 CPU IS OPERATIONAL

*** FILE LOADED: test_files/CPUTEST.COM

DIAGNOSTICS II V1.2 - CPU TEST
COPYRIGHT (C) 1981 - SUPERSOFT ASSOCIATES

ABCDEFGHIJKLMNOPQRSTUVWXYZ
CPU IS 8080/8085
BEGIN TIMING TEST
END TIMING TEST
CPU TESTS OK


*** FILE LOADED: test_files/8080PRE.COM
8080 Preliminary tests complete

*** FILE LOADED: test_files/8080EXM.COM
8080 instruction exerciser

Any ideas on what might be causing nextWord not to work?

Upvotes: 1

Views: 89

Answers (0)

Related Questions