(Scroll to the bottom for the interesting part)Jakim wrote:Anyway, did anybody check how PoP counts time? Hardware/software? I've had various cycles during game and I'm curious how it its affect is.
PoP has 4 timers, numbered 0 to 3.
All 4 timers are used like this:
- Set it to the time you want to wait.
- Wait until it becomes zero.
Interrupt 8 decreases each timer periodically:
Code: Select all
seg009:79C5 new_int_8_timer2 proc far ; CODE XREF: int8_speaker_sound_2+2FP
seg009:79C5 ; new_int_8_midi+87P
seg009:79C5 ; DATA XREF: ...
seg009:79C5 push ds
seg009:79C6 push ax
seg009:79C7 push bx
seg009:79C8 mov ax, seg data
seg009:79CB mov ds, ax
seg009:79CD mov bx, 6 ; 6, 4, 2, 0 -> 4 timers
seg009:79D0 inc word_1DEC8
seg009:79D4 jnz loc_1416A
seg009:79D6 inc word_1DECA
seg009:79DA
seg009:79DA loc_1416A: ; CODE XREF: new_int_8_timer2+Fj
seg009:79DA ; new_int_8_timer2+23j
seg009:79DA cmp wait_time0[bx], 0
seg009:79DF jz loc_14175
seg009:79E1 dec wait_time0[bx]
seg009:79E5
seg009:79E5 loc_14175: ; CODE XREF: new_int_8_timer2+1Aj
seg009:79E5 sub bx, 2
seg009:79E8 jnb loc_1416A
seg009:79EA mov ax, word_1DEE2
seg009:79ED add word_1DED6, ax
seg009:79F1 jnb loc_1418A
seg009:79F3 pushf
seg009:79F4 call dword_1DED8
seg009:79F8 jmp short loc_1418E
seg009:79FA ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
seg009:79FA
seg009:79FA loc_1418A: ; CODE XREF: new_int_8_timer2+2Cj
seg009:79FA mov al, 20h ; ' '
seg009:79FC out 20h, al ; Interrupt controller, 8259A.
seg009:79FE
seg009:79FE loc_1418E: ; CODE XREF: new_int_8_timer2+33j
seg009:79FE pop bx
seg009:79FF pop ax
seg009:7A00 pop ds
seg009:7A01 iret
seg009:7A01 new_int_8_timer2 endp
Code: Select all
000142BA:i1E push ds
000142BB:i50 push ax
000142BC:i53 push bx
000142BD:iB8CE1A mov ax,1ACE
000142C0:i8ED8 mov ds,ax
000142C2:iBB0600 mov bx,0006
000142C5:iFF06E831 inc [+31E8]
000142C9:i7504 jne file:000142CF
000142CB:iFF06EA31 inc [+31EA]
000142CF:i83BFEC3100 cmp (w) [bx+31EC],+00
000142D4:i7404 je file:000142DA
000142D6:iFF8FEC31 dec [bx+31EC]
000142DA:i83EB02 sub (w) bx,+02
000142DD:i73F0 jnc file:000142CF
000142DF:iA10232 mov ax,[+3202]
000142E2:i0106F631 add [+31F6],ax
000142E6:i7307 jnc file:000142EF
000142E8:i9C pushfw
000142E9:iFF1EF831 call (d) [+31F8]
000142ED:iEB04 jmps file:000142F3
000142EF:iB020 mov al,20
000142F1:iE620 out 20,al
000142F3:i5B pop bx
000142F4:i58 pop ax
000142F5:i1F pop ds
000142F6:iCF iret16
Code: Select all
seg009:7A02 set_other_timer proc far ; CODE XREF: speaker_sound_stop+Fp
seg009:7A02 ; set_other_timer_2+Fp
seg009:7A02 pushf
seg009:7A03 cli
seg009:7A04 sub ax, ax
seg009:7A06 mov es, ax
seg009:7A08 mov word ptr es:20h, offset new_int_8_timer2 ; int 8
seg009:7A0F mov es:22h, cs
seg009:7A14 mov al, byte_1DEEA
seg009:7A17 out 43h, al ; Timer 8253-5 (AT: 8254.2).
seg009:7A19 mov ax, word_1DEE2
seg009:7A1C mov word_1DEE0, ax
seg009:7A1F out 40h, al ; Timer 8253-5 (AT: 8254.2).
seg009:7A21 xchg al, ah
seg009:7A23 out 40h, al ; Timer 8253-5 (AT: 8254.2).
seg009:7A25 popf
seg009:7A26 retf
seg009:7A26 set_other_timer endp
Code: Select all
000142F7:i9C pushf
000142F8:iFA cli
000142F9:i2BC0 sub ax,ax
000142FB:i8EC0 mov es,ax
000142FD:i26C7062000C579 mov [es:+0020],79C5
00014304:i268C0E2200 mov [es:+0022],cs
00014309:iA00A32 mov al,[+320A]
0001430C:iE643 out 43,al
0001430E:iA10232 mov ax,[+3202]
00014311:iA30032 mov [+3200],ax
00014314:iE640 out 40,al
00014316:i86C4 xchg al,ah
00014318:iE640 out 40,al
0001431A:i9D popf
0001431B:iCB retf
Code: Select all
First, set the timer:
seg003:04FE loc_4CEE: ; CODE XREF: sub_4CE8+62j
seg003:04FE cmp kid_sword, 2
seg003:0503 jnz loc_4CFD
seg003:0505 mov wait_time1, 6 ; speed when fighting (smaller is faster)
seg003:050B jmp short loc_4D03
seg003:050D ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
seg003:050D
seg003:050D loc_4CFD: ; CODE XREF: sub_4CE8+Bj
seg003:050D mov wait_time1, 5 ; speed when not fighting (smaller is faster)
seg003:0513
seg003:0513 loc_4D03: ; CODE XREF: sub_4CE8+13j
...
Then wait until it becomes zero: (Busy waiting)
seg003:0555 loc_4D45: ; CODE XREF: sub_4CE8+64j
seg003:0555 cmp wait_time1, 0
seg003:055A jz loc_4CEE
seg003:055C jmp short loc_4D45
Code: Select all
00004EEE:i803E644302 cmp [+4364],02
00004EF3:i7508 jne file:00004EFD
00004EF5:iC706EE310600 mov [+31EE],0006 ; speed when fighting (smaller is faster)
00004EFB:iEB06 jmps file:00004F03
00004EFD:iC706EE310500 mov [+31EE],0005 ; speed when not fighting (smaller is faster)
...
00004F45:i833EEE3100 cmp (w) [+31EE],+00
00004F4A:i74A2 je file:00004EEE
00004F4C:iEBF7 jmps file:00004F45
Search: C7 06 EE 31 06 00 EB 06 C7 06 EE 31 05 00
If you change the bolded parts to something smaller, the game will become faster. 00 00 will make it unplayably faster.
If you change only one of them, then only the fighting becomes faster, or only the non-fighting parts.
When the game runs faster this way, the remaining time also decreases faster. (Try it!)
So to sum up things:
- Timing is based on timer interrupts, which are not affected by the speed of the CPU or DOSBox cycles. (However, if the game runs very slow, the timer may already have reached zero when the busy waiting loop is reached. In this case the game will be slower than intended.)
- Speed is a bit different (slower) when fighting. And it seems to be done on purpose!
- Time also passes slower when you're fighting!
Also, did you know that time stops if the kid dies? You can see this best if there is less than one minute left.