superfury wrote:Well, the strange thing is: I'm receiving strange command bytes:
First it sets command byte 0x54, which sets PIT 1, mode 2, LSB
[…] Show full quote
Well, the strange thing is: I'm receiving strange command bytes:
First it sets command byte 0x54, which sets PIT 1, mode 2, LSB
Then it sets command byte 0x40, which latches PIT1(overwrite mode to latch low, high mode).
Further commands keep being command 0x40(latch low,high mode)? Or does this latch mode only affect reads from port 0x40-0x42?
Well that matches what the AT bios writes.
0x54 -> channel 1, set mode command -> load LSB only, mode 2, binary
0x40 -> channel 1, counter latch command. low four bits are unused / don't care bits, but here they are 0. It does not set counter mode, or binary mode, or do not change the previously set mode to load LSB only. Counter stays at load LSB only, mode 2, binary.
Yes, the latch command should only 'freeze' the counter value until the bytes are read. It should not affect the configuration of the PIT.
That's what 'latching' means: it copies the current counter value to an internal register, and the next read command will get the value of that register (rather than the actual counter value). The counter is not affected by this, and will continue running as configured.
This functionality is built into the PIT to avoid race conditions when reading the counter values.
Does the latch always use lo/hi mode or does it use the current mode(1 input in lo or hi mode, 2 inputs in lo/hi mode) to signify it's read mode or completion of the latch(and disabling the latch)?
Ok. And what about writes? Writes don't need a latch, because it's writing to a reload buffer(in itself a latch for reloading when triggered by starting, depending on the mode)?
Not sure if I follow.
The counter "latching" is a command to store its current count to a "latch" so you can read its stored/frozen value while it keeps counting, instead of reading the real time count. It is just a command like the commands to set the load mode, count mode and binary/bcd mode.
I think you already "latch" writes, because you either wait for both LSB/MSB, or either LSB or MSB, and store them, before loading 16-bit word into counter.
The latch command now simply loads the current word into the latch register and set a flag(like the read back status flag). While the flag is set, reads don't reload the latch before reading the latch. Reads from the entire register(One 8-bit read for lo and hi mode, two reads for lo/hi mode) reset that flag.
Writes ignore any latch settings. Although reads(with and without latch) and writes share a single lo/hi toggle.
Thus executing a read byte, write byte in lo/hi mode will read the lo byte and write it to the hi byte? Or is that seperated? (Situations like read lo, write lo, read hi, write hi will end up becoming read lo, write hi, read lo, write hi when executed that way on the port)?
Depends on whether you emulate a 8253 or 8254. 8253 does not allow interleaved read/writes while 8254 does. The datasheets are pretty clear about that.
Which ones are used in the IBM PC(/AT)? Do I need to worry about interleaved reads/writes(including BIOSes)?
Edit: I've just upgraded the emulation to a 8254 chip. Implemented improved BCD mode and wrapping counters. I've also seperated read and write hi/lo states for all 3 channels.
Which ones are used in the IBM PC(/AT)? Do I need to worry about interleaved reads/writes(including BIOSes)?
The PC and XT use 8253's.
The AT system manual is strange. It says 8253-5 in the system diagram, but 8254-2 in the paragraph about the system timer. I think they should use 8254's, and the diagram was probably not updated correctly.
I've fixed some 'bugs' in the 8254 chip emulation. But now the IBM AT BIOS screws up some way: It first sounds PIT2 correctly (correct tone). Then, the next beep is programmed with a higher lo/hi value? (08B4h to be exact)
Taking older parts of the PIT core, it starts this new error at the last commit of 2016/09/15(Yesterday). So it has something to do with the latch command?
Uploaded it externally (since it's a bit over 5MB, 90MB unpacked even with zip file compression). And that's just before the BIOS does much (about step 20). It contains two logs: the PIT log and the debugger.txt contains POST codes sent to port 0x80(diagnostics port).
Uploaded it externally (since it's a bit over 5MB, 90MB unpacked even with zip file compression). And that's just before the BIOS does much (about step 20). It contains two logs: the PIT log and the debugger.txt contains POST codes sent to port 0x80(diagnostics port).
Ugh, I really did not want the port 61h access. Also writing it says "misc" but reading it says "data", is that typo?
So, 0x500 = 1280, 0x4b8 = 1208, it's in ERR_BEEP.
1cat PIT.log | grep Write 200:01:13:12.01264: Write to misc port 0x61=FC 300:01:13:36.07288: Write to data port 0x43=54 400:01:13:36.07616: Write to data port 0x41=00 500:01:13:36.07632: Write to data port 0x43=40 600:01:13:36.07656: Write to data port 0x43=40 700:01:13:36.07672: Write to data port 0x43=40 800:01:13:36.07960: Write to data port 0x41=FF 900:01:13:36.08208: Write to data port 0x43=40 1000:01:13:36.08232: Write to data port 0x43=40 1100:01:13:36.08256: Write to data port 0x43=40 1200:01:13:36.08280: Write to data port 0x43=40 1300:01:13:36.08304: Write to data port 0x43=40 1400:01:13:37.00208: Write to data port 0x41=12 1500:01:13:54.01480: Write to misc port 0x61=1C 1600:01:13:54.01488: Write to misc port 0x61=10 1700:01:15:45.05784: Write to data port 0x43=B6 1800:01:15:45.05792: Write to data port 0x42=00 1900:01:15:45.05800: Write to data port 0x42=05 2000:01:15:45.05816: Write to misc port 0x61=33 2100:01:27:20.02136: Write to misc port 0x61=30 2200:01:27:30.07696: Write to misc port 0x61=30 2300:01:32:37.03952: Write to data port 0x43=B6 2400:01:32:37.03960: Write to data port 0x42=B8 2500:01:32:37.03968: Write to data port 0x42=04 2600:01:32:37.03984: Write to misc port 0x61=33 2700:01:34:26.09456: Write to misc port 0x61=30 2800:01:34:37.03008: Write to misc port 0x61=30
Edit: So I think it fails the refresh rate test. For some reason, the bit mask 0x10 does not seem to toggle at very square wavish action.
It appears you feed the OUT2 directly as port 0x61 input mask 0x10, but on real hardware, the OUT2 edge (rising?) toggles the 0x61 bit.
So because the timer 2 is in mode 2, the pulses are only one clock cycle in length, so it is hard for software to catch them. Make the pulse to toggle the 0x10 bit in port 0x61.
I've included port 61h access, because some of it's bits are from the timers(which is handled by the module as well, bits 0&1 affect the PIT2 gate(bit 0) and PIT2 output mask(bit 1), and bit 4&5 contain the output of PIT1(bit 4) and PIT2(bit 5)). That's why I included it.
Sorry my mistake; I spoke of timer2 output, but I of course meant the timer1 output. Well, 0-based or 1-based indexing...
The out1 is the refresh output, it should toggle the refresh feedback data bit.
The out2 is the speaker output, and it is fed back directly. No toggling.
UniPCemu PIT logs and diagnostic information 2016/09/17 11:31
File license
Fair use/fair dealing exception
I've modified the logs to properly report as 'data'(0x40-0x42), ''command'(0x43) and 'misc'(0x61). The diagnostic output is also in the archive.
Edit: The results with Windows' findstr "Write" PIT.log command results in the exact same output as your log(minus the timings, since this PC I'm logging on runs slower(2.0GHz dual core instead of 4.0GHz i7)).
Edit: Looking at the diagnostic log (debugger.log) reveals that it's executing an internal HLT after point 11h, which is:
1 MOV AL,11H ; <><><><><><><><><><><><> 2 OUT MFG_PORT,AL ; <><> CHECKPOINT 11 <><> 3 4;----- VERIFY SPEED/REFRESH CLOCK RATES ( ERROR = 1 LONG AND 1 SHORT BEEP ) 5 XOR BL,BL ; CLEAR REFRESH CYCLE REPEAT COUNT 6 XOR CX,CX ; INITIALIZE SPEED RATE REGISTER 7 EVEN ; PLACE ON EVEN WORD BOUNDARY 8C34: 9 IN AL,PORT_B ; READ REFRESH BIT REGISTER 10 TEST AL,REFRFSH_BIT ; MASK FOR BIT 11 LOOPZ C34 ; DECREMENT LOOP COUNTER TILL ON 12C35: 13 IN AL,PORT_B ; READ REFRESH BIT REGISTER 14 TEST AL,REFRFESH_BIT ; MASK FOR BIT 15 LOOPNZ C35 ; DECREMENT LOOP COUNTER TILL OFF 16 17 DEC BL ; DECREMENT REFRESH CYCLE REPEAT COUNT 18 JNZ C34 ; REPEAT TILL CYCLE COUNT DONE 19 20 CMP CX,RATE_UPPER ; CHECK FOR RATE BELOW UPPER LIMIT 21 JAE C36 ; SKIP ERROR BEEP IF BELOW MAXIMUM 22C36E: 23 MOV DX,0101H ; GET BEEP COUNTS FOR REFRESH ERROR 24 CALL ERR_BEEP ; CALL TO POST ERROR BEEP ROUTINES 25 HLT ; HALT SYSTEM - BAD REFRESH RATE 26C36I 27 CMP CX,RATE_LOWER ; CHECK FOR RATE ABOVE LOWER LIMIT 28 JA C36E ; GO TO ERROR BEEP IF BELOW MINIMUM
So there's a problem with the refresh bit according to that code?
Edit: At the end, CX contains FAB3(CPU running at 5.9MHz with 8086 timings). This apparently is incorrect, according to the BIOS(which needs to be in FFXX range if I remember correctly.