Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Civilization 1 has some infinite loop bugs, some assemblers experts would be welcome.

10 views
Skip to first unread message

Skybuck Flying

unread,
Jul 16, 2022, 7:18:53 PM7/16/22
to
Civilization 1 has some infinite loop bugs, caused most likely by unit pointing towards itself:

https://forums.civfanatics.com/threads/disassembly-of-loop-section-that-hangs-the-game-for-quite-a-while-maybe-even-forever.676481/

Live youtube stream showing the bug in action:

https://www.youtube.com/watch?v=GPBulseezIA

Any suggestions how to fix this in real time by manipulating some registers or memory contents is welcome !

Another civilization 1 hang, disassembly:

LOOP1:

1E1E:000016B9 8B4608 mov ax,[bp+08] ss:[F006]=0600
1E1E:000016BC 3946E0 cmp [bp-20],ax ss:[EFDE]=0000
1E1E:000016BF 7503 jne 000016C4 ($+3) (down)
1E1E:000016C1 E98E00 jmp 00001752 ($+8e) (down)
1E1E:000016C4 B80006 mov ax,0600
1E1E:000016C7 F76E06 imul word [bp+06] ss:[F004]=B808
1E1E:000016CA 8BF0 mov si,ax
1E1E:000016CC B80C00 mov ax,000C
1E1E:000016CF F76EE0 imul word [bp-20] ss:[EFDE]=0000
1E1E:000016D2 03F0 add si,ax
1E1E:000016D4 F684D48108 test byte [si-7E2C],08 ds:[FFFFB1D4]=6E6
1E1E:000016D9 751D jne 000016F8 ($+1d) (down)
1E1E:000016DB B022 mov al,22
1E1E:000016DD F6ACD781 imul byte [si-7E29] ds:[FFFFB1D7]=2020
1E1E:000016E1 8BF8 mov di,ax
1E1E:000016E3 B80100 mov ax,0001
1E1E:000016E6 8A8D4811 mov cl,[di+1148] ds:[1148]=0000
1E1E:000016EA D3E0 shl ax,cl
1E1E:000016EC 0946E2 or [bp-1E],ax ss:[EFE0]=468B
1E1E:000016EF 83BD381100 cmp word [di+1138],0000 ds:[1138]=0000
1E1E:000016F6 EB37 jmp short 0000172F ($+37) (down)
1E1E:000016F8 837EFE05 cmp word [bp-02],0005 ss:[EFFC]=9A50
1E1E:000016FC 7534 jne 00001732 ($+34) (no jmp)
1E1E:000016FE B81C00 mov ax,001C
1E1E:00001701 F76EF4 imul word [bp-0C] ss:[EFF2]=FF50
1E1E:00001704 8BD8 mov bx,ax

LOOP2:

1E1E:0000172F FF46AC inc word [bp-54] ss:[EFAA]=6F13
1E1E:00001732 B80C00 mov ax,000C
1E1E:00001735 F76EE0 imul word [bp-20] ss:[EFDE]=0000
1E1E:00001738 8BD8 mov bx,ax
1E1E:0000173A B80006 mov ax,0600
1E1E:0000173D F76E06 imul word [bp+06] ss:[F004]=B808
1E1E:00001740 8BF0 mov si,ax
1E1E:00001742 8A80DE81 mov al,[bx+si-7E22] ds:[FFFFB4BA]=6863
1E1E:00001746 98 cbw
1E1E:00001747 8946E0 mov [bp-20],ax ss:[EFDE]=0000
1E1E:0000174A 3DFFFF cmp ax,FFFF
1E1E:0000174D 7403 je 00001752 ($+3) (no jmp)
1E1E:0000174F E967FF jmp 000016B9 ($-99) (up)


registers:
EAX=0000003D ESI=00003000 DS=3324 ES=625D FS=0000 GS=0000 SS=0000 Real
EBX=00000000 EDI=00000000 CS=1E1E EIP=000016B9 C1 Z0 S0 O0 A1 P0 D0 I1 T0
ECX=00000000 EBP=0000EFFE NOPG IOPL3 CPL0
EDX=0000FE50 ESP=0000EF9C 4492
ST0=00000.00 ST1=00000.00 ST2=00000.00 ST3=00000.00
ST4=00000.00 ST5=00000.00 ST6=00000.00 ST7=00000.00

wolfgang kern

unread,
Jul 18, 2022, 4:09:24 AM7/18/22
to
On 17/07/2022 01:18, Skybuck Flying wrote:
> Civilization 1 has some infinite loop bugs, caused most likely by unit pointing towards itself:
>
> https://forums.civfanatics.com/threads/disassembly-of-loop-section-that-hangs-the-game-for-quite-a-while-maybe-even-forever.676481/
>
> Live youtube stream showing the bug in action:
>
> https://www.youtube.com/watch?v=GPBulseezIA
>
> Any suggestions how to fix this in real time by manipulating some registers or memory contents is welcome !

what you posted here seems to be incomplete parts of a debug sessions
rather than code of the executable.
So I can only guess how the origin code look like.

IIRC Sid Mayers first CIV came on a single 5.25 FD and many (especially
European) "vendors" just copied it and sold it (also in 3.5) but with a
few things missing. [good old copy protection worked at this time then].

So there is actually no easy bug-fix available. Rewrite whole game.
The endless loops may come from the huge difference in timing.
such old DOS games didn't use PIT/PIC nor RTCLK for timing, they just
used multiple instruction timing [DOS2 FNCT] for delays.
__
wolfgang

I kept you rare seen ASM here even it's totally out of context.

Skybuck Flying

unread,
Jul 23, 2022, 6:50:25 PM7/23/22
to
The bug is most likely caused by units referencing each other into some kind of infinite loop.

Using the debugger it's possible to skip the bottom jmp statement when it's about to be executed, with the following debugger command:

SR EIP xxxxxxxx

Where x is the address for the instruction below the jmp statement.

(This will "(S)et (R)egister" the "(E)xtended (I)nstruction (P)ointer register" to address x)

Declare war and try and get rid of many units as possible.

(
This is a temporarely fix but at least allows the game to continue which is fun.

There also seems to be a tool available that might be able to fix this if there is a save game available, which will usually
not be the case because not all turns are saved.
)

Most likely the bug is caused by unsentry and re-sentry some units during the same turn.


Bye,
Skybuck.
0 new messages