I am using Free Pascal as compiler.
So i wrote a Print Pascal String function...
Because pascal is buildup like this:
db Length, Text, db 0
and when using dynamic strings the compiler does this:
db 2, 'Hi000 .... to 255 ', db 0
So the only chose is to write a print function to deal with this.
procedure WriteStr(XPos, YPos, Attribute: Byte; Str: String); assembler; [public, alias: 'SR_WRITESTR'];
asm
???XOR???EDX, EDX?????????{Clear}
???MOV???DX, XPos?????????{XPos}
???MOV???CX, YPos?????????{YPos}
???MOV???ESI, Str?????????{Str pointer}
???SHL???CX, 40?????????{YPos * 80}
???ADD???DX, CX?????????{XPos + (YPos * 80)}
???SHL???DX, 1????????????{DX * 2, because of the attribute}
???ADD???EDX, $B8000?????????{Screen pointer}
???MOV???EDI, EDX?????????{Destination pointer}
???XOR???EAX, EAX?????????{Clear}
???LODSB???????????????{Read string length}
???MOV???ECX, EAX?????????{Set length in counter}
???MOV???AH, Attribute??????{Attribute / Color}
???@PrintChar:
??????LODSB????????????{Put char in AL}
??????STOSW????????????{Write AX to Mem}
???LOOP???@PrintChar?????????{If ECX != 0, write next}
end;
The string is printed on the screen but not at the right place!
SHL???CX, 40 <- PROBLEM
Why is this rong or doesn't work ??? , one shift to left = *2 right?
EDIT: Can it be because i use the ECX (CX) register?
ASM help
Re:ASM help
It's wrong because:
Shift counts on the x86 are taken mod 32 (this has bitten me before, usually when I need them mod 64).
So you have SHL CX, 8 (40 - 32 = .
A shift by 8 is equivelant to multiplying by 256. (2^8).
You are therefore throwing your Y position of by a whole bunch of lot.
So, let's try this again:
80 decimal is 64 + 16 is $50 hex.
Assuming you don't want to use IMUL or anything, the simplest way is:
SHL CX, 4 {YPos * 16}
ADD DX, CX {XPos + YPos * 16}
SHL CX, 2 {YPos * 64}
ADD DX, CX {XPos + YPos * 16 + YPos * 64 = XPos + YPos * 80}
Hope this helps and wasn't too unclear of an explanation.
--Jamethiel
SHL DX, 1
Shift counts on the x86 are taken mod 32 (this has bitten me before, usually when I need them mod 64).
So you have SHL CX, 8 (40 - 32 = .
A shift by 8 is equivelant to multiplying by 256. (2^8).
You are therefore throwing your Y position of by a whole bunch of lot.
So, let's try this again:
80 decimal is 64 + 16 is $50 hex.
Assuming you don't want to use IMUL or anything, the simplest way is:
SHL CX, 4 {YPos * 16}
ADD DX, CX {XPos + YPos * 16}
SHL CX, 2 {YPos * 64}
ADD DX, CX {XPos + YPos * 16 + YPos * 64 = XPos + YPos * 80}
Hope this helps and wasn't too unclear of an explanation.
--Jamethiel
SHL DX, 1
Re:ASM help
Thx Jamethiel!
I better read that bit wise tutorial not so fast ;D
( XPos + ( YPos * 16 ) ) + ( ( YPos * 16 ) * 4 )
So:
procedure WriteStr(XPos, YPos, Attribute: Byte; Str: String); assembler; [public, alias: 'SR_WRITESTR'];
asm
XOR EDX, EDX {Clear}
MOV DX, XPos {XPos}
MOV CX, YPos {YPos}
MOV ESI, Str {Str pointer}
SHL CX, 4 {YPos * 16}
ADD DX, CX {XPos + (YPos * 16)}
SHL CX, 2 {(YPos * 16) * 4}
ADD DX, CX {XPos + (YPos * 80)}
SHL DX, 1 {DX * 2}
ADD EDX, $B8000 {Screen pointer}
MOV EDI, EDX {Destination pointer}
XOR EAX, EAX {Clear}
LODSB {Read string length}
MOV ECX, EAX {Set length in counter}
MOV AH, Attribute {Attribute / Color}
@PrintChar:
LODSB {Put char in AL}
STOSW {Write AX to Mem}
LOOP @PrintChar {If ECX != 0, write next}
end;
I better read that bit wise tutorial not so fast ;D
( XPos + ( YPos * 16 ) ) + ( ( YPos * 16 ) * 4 )
So:
procedure WriteStr(XPos, YPos, Attribute: Byte; Str: String); assembler; [public, alias: 'SR_WRITESTR'];
asm
XOR EDX, EDX {Clear}
MOV DX, XPos {XPos}
MOV CX, YPos {YPos}
MOV ESI, Str {Str pointer}
SHL CX, 4 {YPos * 16}
ADD DX, CX {XPos + (YPos * 16)}
SHL CX, 2 {(YPos * 16) * 4}
ADD DX, CX {XPos + (YPos * 80)}
SHL DX, 1 {DX * 2}
ADD EDX, $B8000 {Screen pointer}
MOV EDI, EDX {Destination pointer}
XOR EAX, EAX {Clear}
LODSB {Read string length}
MOV ECX, EAX {Set length in counter}
MOV AH, Attribute {Attribute / Color}
@PrintChar:
LODSB {Put char in AL}
STOSW {Write AX to Mem}
LOOP @PrintChar {If ECX != 0, write next}
end;