Assembly

Страница 4/5
1 | 2 | 3 | | 5

By rolandve

Master (220)

Аватар пользователя rolandve

15-05-2020, 11:08

Hi All,

I'm reading some data from a port, process that data and then I store it in a memory location. The first byte works, but somehow, I use ' inc hl' in the wrong way. I get my addresses from TP that gives the reference to the value (so I assume the integer that has the bytes address). Is the way I handle addresses wrong or should I do it another way?

      ld hl,address { address is the reference provided by TP, a previously allocated block of bytes }
      ld (hl),a      { a contains the result of the operation. Verified this by printing the value }
      inc hl        { should increase the value of HL, so it should point too the next allocated byte}
      ....           { do some other operations }
     ld (hl),a.   { this does not return the value in a at the expected location which is supposed to be the address}

By Pencioner

Scribe (1207)

Аватар пользователя Pencioner

15-05-2020, 11:16

'some other operations' - are you sure they preserve content of HL and does not change it? if there's some BIOS calls etc than it might change HL. try to insert PUSH HL after INC HL and POP HL after other operations and before LD (HL), A and see if it helps - if so then something is changing your HL in 'some other operations' part Smile

By rolandve

Master (220)

Аватар пользователя rolandve

15-05-2020, 13:11

thanks! That would be an obvious one. No: there is nothing using HL. I am just doing operations on the A or B registers. Thats very easy to check because I only use opcodes for these. There are no break-outs to bios calls.

The code below reads the clocks first second register. Drop's it in a variable tmpInt and an address that is referred to as tmpInt. 'inc hl' ($23) does not seem to increase the memory address loaded in HL or somehow it gets lost. I allocated enough space in bytes. AT is the address of the first available byte.

           $2A/at/         { ld hl,at }
           $E/$B4/ 	{ ld c,$B4 }
           $6/$0/		{ ld b,0   }
           $ED/$41/	{ out (c),b}
           $E/$B5/		{ ld c,$B5 }
           $ED/$78/	{ in a,(c) }
           $CB/$27/       { sla a     <- shift left 4 times}
           $CB/$27/	{ sla a    }
           $CB/$27/       { sla a    }
           $CB/$27/	{ sla a    }
           $CB/$3F/	{ srl a     <- shift right 4 times}
           $CB/$3F/	{ srl a    }
           $CB/$3F/	{ srl a    }
           $CB/$3F/	{ srl a    }
           $4F/		{ ld c,a   }   
           $6/$0/          { ld b,0   }
          $ED/$43/tmpInt/ { ld (tmpInt),bc}
          $77                { ld (hl),a }

By pgimeno

Master (245)

Аватар пользователя pgimeno

15-05-2020, 17:39

That part seems correct (modulo the fact that $2A is 'ld hl,(NN)' and not 'ld hl,NN' but I guess that's a bug in the comment only). Maybe if you show a bit more of the context? Especially how is 'at' defined, if it's a local variable or what.

By rolandve

Master (220)

Аватар пользователя rolandve

15-05-2020, 21:36

Thanks. $21 is the correct value. Context: its supposed to read the clock Smile You can ask BDOS or read the actual clock ports. Very nice to read the technical specifications then you understand why even BDOS just gives you 3 digits. Once you have the 6 values, you would still need to store them. I created a array of bytes (later a getmem, that gives a pointer) and try to store the clock digits in this array (or memory block) for processing. Thus AT is an absolute byte to the pointer of reserved memory or the first entry of the byte array.

By thegeps

Hero (579)

Аватар пользователя thegeps

16-05-2020, 01:12

rolandve wrote:

thanks! That would be an obvious one. No: there is nothing using HL. I am just doing operations on the A or B registers. Thats very easy to check because I only use opcodes for these. There are no break-outs to bios calls.

The code below reads the clocks first second register. Drop's it in a variable tmpInt and an address that is referred to as tmpInt. 'inc hl' ($23) does not seem to increase the memory address loaded in HL or somehow it gets lost. I allocated enough space in bytes. AT is the address of the first available byte.

           $2A/at/         { ld hl,at }
           $E/$B4/ 	{ ld c,$B4 }
           $6/$0/		{ ld b,0   }
           $ED/$41/	{ out (c),b}
           $E/$B5/		{ ld c,$B5 }
           $ED/$78/	{ in a,(c) }
           $CB/$27/       { sla a     <- shift left 4 times}
           $CB/$27/	{ sla a    }
           $CB/$27/       { sla a    }
           $CB/$27/	{ sla a    }
           $CB/$3F/	{ srl a     <- shift right 4 times}
           $CB/$3F/	{ srl a    }
           $CB/$3F/	{ srl a    }
           $CB/$3F/	{ srl a    }
           $4F/		{ ld c,a   }   
           $6/$0/          { ld b,0   }
          $ED/$43/tmpInt/ { ld (tmpInt),bc}
          $77                { ld (hl),a }

Is all this code between "inc hl" and "ld (hl),a" ?
If so "ld hl,at" changes hl value just after inc hl...

By rolandve

Master (220)

Аватар пользователя rolandve

16-05-2020, 10:35

Thanks, always good to re-check the opcodes. I can't dream them yet, so one might slip. However:
$77 ld (hl), A : ' the value of A is loaded in the location pointed to. So the content of HL is not changed. It just points to a memory address.

By thegeps

Hero (579)

Аватар пользователя thegeps

16-05-2020, 12:17

I'm talking about the first row of code (the one you wrote opcode $2a instead of $21) it changes for sure HL value...
So, as I asked before if it is just after "inc hl" then hl assume the at value, discarding its previous incremented value. So, if you want us to help you, please, show the complete snipet...

By rolandve

Master (220)

Аватар пользователя rolandve

16-05-2020, 20:00

That opcode is there because that's where I load the address of the first byte, where data should be stored. So it changes HL because I need the address (which is an absolute integer in TP). AT is the first byte of that place. Here the function that works but is far from efficient because I can't get the result of the A register in the next memory address. I stripped out all non functional code. That includes the code we discussed above. I could also optimise this by using loops, but I've got no experience with that either. Going to use Winape because I need to have a Z80 emulator that has a monitor, so I can actually see what my code does.


function clock : TimeString;

var
     tmpInt : integer;
     ss,ds,sm,dm,sh,dh : byte;
     num : array [0..5] of byte;
     hour,min,sec :string[2];
     pt : ^integer;
     at : integer absolute pt;
begin;
    inline(
             $E/$B4/ 	{ ld c,$B4 }
             $6/$0/		{ ld b,0   } 
             $ED/$41/	{ out (c),b}
             $E/$B5/		{ ld c,$B5 }
             $ED/$78/	{ in a,(c) }
             $CB/$27/    { sla a     <- shift left 4 times}
             $CB/$27/	{ sla a    }
             $CB/$27/    { sla a    }
             $CB/$27/	{ sla a    }
             $CB/$3F/	{ srl a     <- shift right 4 times}
             $CB/$3F/	{ srl a    }
             $CB/$3F/	{ srl a    }
             $CB/$3F/	{ srl a    }
             $4F/		{ ld c,a   }   
             $6/$0/      { ld b,0   }
             $ED/$43/tmpInt { ld (tmpInt),bc}

);
 num[5]:=lo(tmpInt);
	inline(
               $E/$B4/ 	{ ld c,$B4 }
               $6/$1/		{ ld b,1   }
               $ED/$41/	{ out (c),b}
               $E/$B5/		{ ld c,$B5 }
               $ED/$78/	{ in a,(c) }
               $CB/$27/    { sla a     <- shift left 4 times}
               $CB/$27/	{ sla a    }
               $CB/$27/    { sla a    }
               $CB/$27/	{ sla a    }
               $CB/$3F/	{ srl a     <- shift right 4 times}
               $CB/$3F/	{ srl a    }
               $CB/$3F/	{ srl a    }
               $CB/$3F/	{ srl a    }
               $4F/		{ ld c,a   }
               $6/$0/      { ld b,0   }
               $ED/$43/tmpInt { ld (tmpInt),bc}
 );
  num[4]:=lo(tmpInt);
		inline(
		$E/$B4/ 	{ ld c,$B4 }
		$6/$2/		{ ld b,2   }
		$ED/$41/	{ out (c),b}
		$E/$B5/		{ ld c,$B5 }
		$ED/$78/	{ in a,(c) }
		$CB/$27/    { sla a     <- shift left 4 times}
               $CB/$27/	{ sla a    }
         	$CB/$27/    { sla a    }
        $CB/$27/	{ sla a    }
        $CB/$3F/	{ srl a     <- shift right 4 times}
        $CB/$3F/	{ srl a    }
        $CB/$3F/	{ srl a    }
        $CB/$3F/	{ srl a    }
        $4F/		{ ld c,a   }
        $6/$0/      { ld b,0   }
       $ED/$43/tmpInt{ ld (tmpInt),bc}
 );
		num[3]:=lo(tmpInt);
		inline(
		$E/$B4/ 	{ ld c,$B4 }
		$6/$3/		{ ld b,3   }
		$ED/$41/	{ out (c),b}
		$E/$B5/		{ ld c,$B5 }
		$ED/$78/	{ in a,(c) }
		$CB/$27/    { sla a     <- shift left 4 times}
        $CB/$27/	{ sla a    }
		$CB/$27/    { sla a    }
        $CB/$27/	{ sla a    }
        $CB/$3F/	{ srl a     <- shift right 4 times}
        $CB/$3F/	{ srl a    }
        $CB/$3F/	{ srl a    }
        $CB/$3F/	{ srl a    }
        $4F/		{ ld c,a   }
        $6/$0/      { ld b,0   }
        $ED/$43/tmpInt{ ld (tmpInt),bc}
        );
        num[2]:=lo(tmpInt);
        		inline(
		$E/$B4/ 	{ ld c,$B4 }
		$6/$4/		{ ld b,4   }
		$ED/$41/	{ out (c),b}
		$E/$B5/		{ ld c,$B5 }
		$ED/$78/	{ in a,(c) }
		$CB/$27/    { sla a     <- shift left 4 times}
        $CB/$27/	{ sla a    }
		$CB/$27/    { sla a    }
        $CB/$27/	{ sla a    }
        $CB/$3F/	{ srl a     <- shift right 4 times}
        $CB/$3F/	{ srl a    }
        $CB/$3F/	{ srl a    }
        $CB/$3F/	{ srl a    }
        $4F/		{ ld c,a   }
        $6/$0/      { ld b,0   }
        $ED/$43/tmpInt{ ld (tmpInt),bc}
        );
        num[1]:=lo(tmpInt);
        inline(
		$E/$B4/ 	{ ld c,$B4 }
		$6/$5/		{ ld b,5   }
		$ED/$41/	{ out (c),b}
		$E/$B5/		{ ld c,$B5 }
		$ED/$78/	{ in a,(c) }
		$CB/$27/    { sla a     <- shift left 4 times}
        $CB/$27/	{ sla a    }
		$CB/$27/    { sla a    }
        $CB/$27/	{ sla a    }
        $CB/$3F/	{ srl a     <- shift right 4 times}
        $CB/$3F/	{ srl a    }
        $CB/$3F/	{ srl a    }
        $CB/$3F/	{ srl a    }
        $4F/		{ ld c,a   }
        $6/$0/      { ld b,0   }
        $ED/$43/tmpInt{ ld (tmpInt),bc}
        );
		num[0]:=lo(tmpInt);
		str((num[0]*10)+num[1],hour);
		if length(hour) = 1 then hour:=concat('0',hour);
		str((num[2]*10+num[3]),min);
		if length(min) = 1 then min:=concat('0',min);
		str((num[4]*10+num[5]),sec);
		if length(sec) = 1 then sec:=concat('0',sec);
		clock:=concat(hour,':',min,':',sec);
end;

By thegeps

Hero (579)

Аватар пользователя thegeps

17-05-2020, 10:48

It is needed the passage "ld (tmpInt),bc" when you'll have all your six values starting from HL address?
I see you use it to pass the value of register a in a temporary location. Is it right? And explain me (I don't know TP): can't and integer address (in this case tmpInt) contain a 8bit value?

Страница 4/5
1 | 2 | 3 | | 5