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 ) 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: [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. [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 » |
|
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 » |
|
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 » |
|
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.) 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
|
|
|
|
|