+  RHDN Forum Archive
|-+  Romhacking
| |-+  ROM Hacking Discussion
| | |-+  PC98 / Intel 8088 stuff
Pages: [1]
Author Topic: PC98 / Intel 8088 stuff  (Read 838 times)
KingMike
Guest
« on: September 11, 2007, 11:06:42 pm »

So, I decided to once again look at Guest's tracer.
His memory map helps, but the one part confusing me is... how does the memory map relate to the CPU address space.
So Wikipedia insists that the Intel 8088 just has some kinda weird-ass mirroring system.
Such as one instruction. It's at RAM address 125FF, but this is CPU address 0E5A:405F.
How's that work? As I also checked an example trace included with Guest's tracer. Doesn't seem to be a linear connection. That's what's stopping current progress.
Well, I at least think I figured out how to use the tracer. So hopefully after that I can try to see about doing a 1-byte text hack and font shrinking on a game.
tomaitheous
Guest
« Reply #1 on: September 12, 2007, 01:12:08 am »


 It's been a number if years since I've written x86 assembly, but off the top of my head...

 The x86 (8088 is the 8bit BUS version of the 8086) has a 16bit IP (intel version of PC) and thus can only access a 64k address range. What intel did was add segment registers for the IP, stack pointer, and  source/destination address registers. These are named CS(code), DS(data), ES(data), and SS (stack).

 These segment registers help the processor overcome the 64k addressable limit by adding the source/destination/stack/IP original registers to their corresponding segment registers. The value in a segment register is shift by 4. For example $A000 for DS is actually $A0000, so if SI was $0010 then DS:SI would be $A0010.  (If you've programmed for PC DOS, then $A000 should look familiar  Wink )

 You can think of the segment registers as page indexing by 16 bytes:  $0000=0000, $0001 = 16 byte index, etc. Remember IP and SP have their own segment register so the CPU can access/transfer data outside the current 64k code segment address.

 Hope that helps.

-Rich



KingMike
Guest
« Reply #2 on: September 14, 2007, 01:13:18 pm »

Thanks, but there's something else I guess I'm not getting:

Code:
[1:2612][0e5a:4072] 8b 46 08                mov ax,ds:[bp+08h]  ax=0005 bx=24aa cx=0008 dx=0005
|| bp=c210 sp=c210 si=24ab di=00f0
|| cs=0e5a ds=1d0c ss=1d0c es=1d0c || vNzC
Am I translating this instruction correct?
bp+08 -> $C210 + 8 -> $C218
ds: $c218 -> ($1D0C <<4) + $C218 = $1D0C0 + $C218 = $292D8.
According to a RAM dump made with Neko-tracer, it is not the expected value of $928B, but $4072 (still an interesting result). Did I calculate this right?
(I'm guessing I didn't, as I think the value I want is at $1F569, or maybe $1EE7D or $21EB2).
tomaitheous
Guest
« Reply #3 on: September 14, 2007, 09:21:41 pm »


Edit: The calculation looks correct....
« Last Edit: September 14, 2007, 09:44:02 pm by tomaitheous »
KingMike
Guest
« Reply #4 on: September 29, 2007, 01:33:30 pm »

Alright, working on a WSC game now (hopefully being a console will make it easier to practice on). Another line of code bugging me...

I'm looking at the jl. I'm expecting it to branch, but doesn't.

Code:
[3942a8] 9:42a8 74 08               jz 42b2h                ax=20d9 bx=1803 cx=0000 dx=00c2 || bp=c04e sp=2464 si=3804 di=b060 || cs=9000 ds=0000 ss=0000 es=2000
[3942b2] 9:42b2 ea 00 ed 00 90      jmp 9000:ed00h          ax=20d9 bx=1803 cx=0000 dx=00c2 || bp=c04e sp=2464 si=3804 di=b060 || cs=9000 ds=0000 ss=0000 es=2000
[39ed00] 9:ed00 26 8a 24            mov ah,es:[si]          ax=20d9 bx=1803 cx=0000 dx=00c2 || bp=c04e sp=2464 si=3804 di=b060 || cs=9000 ds=0000 ss=0000 es=2000
[39ed03] 9:ed03 26 8a 44 01         mov al,es:[si+01h]      ax=53d9 bx=1803 cx=0000 dx=00c2 || bp=c04e sp=2464 si=3804 di=b060 || cs=9000 ds=0000 ss=0000 es=2000
[39ed07] 9:ed07 80 fc 00            cmp ah,00h              ax=5361 bx=1803 cx=0000 dx=00c2 || bp=c04e sp=2464 si=3804 di=b060 || cs=9000 ds=0000 ss=0000 es=2000
[39ed0a] 9:ed0a 74 05               jz ed11h                ax=5361 bx=1803 cx=0000 dx=00c2 || bp=c04e sp=2464 si=3804 di=b060 || cs=9000 ds=0000 ss=0000 es=2000
[39ed0c] 9:ed0c 80 fc 80            cmp ah,80h              ax=5361 bx=1803 cx=0000 dx=00c2 || bp=c04e sp=2464 si=3804 di=b060 || cs=9000 ds=0000 ss=0000 es=2000
[39ed0f] 9:ed0f 7c 05               jl ed16h                ax=5361 bx=1803 cx=0000 dx=00c2 || bp=c04e sp=2464 si=3804 di=b060 || cs=9000 ds=0000 ss=0000 es=2000
[39ed11] 9:ed11 ea b9 42 00 90      jmp 9000:42b9h          ax=5361 bx=1803 cx=0000 dx=00c2 || bp=c04e sp=2464 si=3804 di=b060 || cs=9000 ds=0000 ss=0000 es=2000
creaothceann
Guest
« Reply #5 on: September 29, 2007, 02:10:32 pm »

Well, depends on what data is at es:si, doesn't it?

Btw. is that a big-endian CPU? (mov al,es:[si+01h]...)
KingMike
Guest
« Reply #6 on: September 29, 2007, 10:31:50 pm »

I replaced the single Shift-JIS character $82A8 (I think, hiragana 'o') with two ASCII characters ('S' 'a', hex $53 and $61, first two characters in a dummy string "Sample").
So, es:si = $53, es:[se+1] = $61.
Shouldn't cmp ah,80h be comparing $53 and $80, and jl (jump less than) branching because ah ($53) is less than $80?

The CPU seems to be little-endian, but I think it loads the two bytes seperately, so it can use standard Shift-JIS (big-endian) values.
(I suppose I should mention, this is a hack to enable the use of 1-byte ASCII in place of 2-byte J-ASCII)

The mov lines are the original game's code I overwrote to jump to this piece.
creaothceann
Guest
« Reply #7 on: September 30, 2007, 06:47:23 am »

Quote from: KingMike on September 29, 2007, 10:31:50 pm
Shouldn't cmp ah,80h be comparing $53 and $80, and jl (jump less than) branching because ah ($53) is less than $80?

Yeah. :huh: Maybe it doesn't get the value $53, for some reason.
Firlet
Guest
« Reply #8 on: September 30, 2007, 06:58:40 am »

Quote from: KingMike on September 14, 2007, 01:13:18 pm
According to a RAM dump made with Neko-tracer, it is not the expected value of $928B, but $4072 (still an interesting result).

With 8086, sometimes those stack areas get written several times by shared code. So a dump may not show the result we want - there's no debugger I think, so you'll have to stick with the combo memory pc/write loggers to check what's going on (sad).


[quote ]
KingMike on September 29, 2007, 11:31:50 PM
Shouldn't cmp ah,80h be comparing $53 and $80, and jl (jump less than) branching because ah ($53) is less than $80?
[/quote]

cmp is 8-bit signed. So 83 > -128.
You can try 'JNA', 'JNB', 'JNBE' because they are unsigned.
KingMike
Guest
« Reply #9 on: September 30, 2007, 10:09:45 pm »

Great, that helped.
Now, I'm appearing to have some syntax issues.
Oswan tracer gives this line:
add ds:[bp+f33bh],0ch

I've tried NASM and MASM, and neither likes this syntax. They both say that f33bh is undefined (guess they don't like hex?)
using [ds:bp+62237],0ch gives an error of unspecified operation size.
Any idea how I can work this into an assemblable statement?
I could probably come up with commands to work around it.
What this command is supposed to do, is take the offset (bp+$f33b), and add 12 to the value at that offset in segment ds.
creaothceann
Guest
« Reply #10 on: October 01, 2007, 05:19:23 am »

F33Bh = 62267, not 62237. (Just prefix the constant with a "0" to fix the complaints.)

No idea about the operation size.
Firlet
Guest
« Reply #11 on: October 01, 2007, 01:57:57 pm »

Quote from: KingMike on September 30, 2007, 10:09:45 pm
Great, that helped.
Now, I'm appearing to have some syntax issues.
Oswan tracer gives this line:
add ds:[bp+f33bh],0ch

I've tried NASM and MASM, and neither likes this syntax. They both say that f33bh is undefined (guess they don't like hex?)
using [ds:bp+62237],0ch gives an error of unspecified operation size.
Any idea how I can work this into an assemblable statement?
I could probably come up with commands to work around it.
What this command is supposed to do, is take the offset (bp+$f33b), and add 12 to the value at that offset in segment ds.

Download the newest NASM.

Operation size:
add byte [ds:bp+0f33bh],00ch
add word [ds:bp+0f33bh],00ch
KingMike
Guest
« Reply #12 on: December 01, 2007, 02:06:36 pm »

Recently began looking at some code again.
My code for reading a width table seems to create some random junk tiles on the screen.

What I don't understand is:
the game has no problem with me changing the constant width (determined by the instruction "add byte [ds:bp+0f33bh],0ch") to whatever I feel like. So any reason it'd have a problem if I change it to load a different value each time?
(and if I leave the code for a constant width in, instead of jumping to my routine, then the game runs fine.)

Code:
push ax ;save ax
 push bp
; mov 00000h:0f3feh,ax ;manually entering the hex, as I can't seem to make this line compile.
;reading the last 16-bit value read from the script.
 cmp ax,8000h            ;checks if the most significant digit is >80 (=SJIS character)
 jnb sjis_end ;over $8000 = Shift-JIS
 mov al,ah                     ;copy high byte to low byte
 and ax,00ffh                ;zero out high byte
 mov bp,ax                    ;copy to offset
 mov ax,[cs:bp+0ef00h] ;read width table for character
 pop bp                           ;restore original BP
 add [ds:bp+0f33bh],al  ;store to the original RAM offset (1 byte) holding the horizontal pixel offset of the next char.
 pop ax
 jmp 09000h:04655h     ;back to original routine

sjis_end:
 add byte [ds:bp+0f33bh],0ch
 pop bp
 pop ax
 jmp 09000h:04655h
Pages: [1]  


Powered by SMF 1.1.4 | SMF © 2006-2007, Simple Machines LLC