This page contains random historical facts about Intel 8000 family and IBM PC computers that I've discovered while building my system.
So the answer is that 8237 was not designed for 8088 CPUs (which is odd given that Intel released this chip in 1979, when 8086 and 8088 already existed).
In fact 8237 was designed by AMD. The AMD part number is Am9517A (the AMD datasheet contains following note "The 8237A is an AMD-invented device more commonly referred to as the Am9517A"). There is an anouncement in InfoWorld magazine (May 9, 1979) saying that Intel introduced 8237 (3 MHz) and 8237-2 (5 MHz) DMA controllers that are pin equivalent of AMD 9517. It says nothing though about using AMD's design by Intel, but it was the case. In fact on Intel 8237 chips there is an AMD copyright marking. I guess that Intel received 8237 design from AMD as a part of portfolio exchange (perhaps the same exchange that allowed AMD to manufacture 8086 and 8088 processors).
Intel had a better alternative for 8237 - Intel 8089 I/O coprocessor. The 8089 is much more advanced than 8237 - it has its own instruction set and basically it is possible to program it to perform advanced I/O operations independently from CPU. But for whatever reason (perhaps the cost - the price for 8089 was about $80 and for 8237 - about $20, maybe availability, or maybe existing 8237 knowledge and experience) IBM decided not to use 8089 in IBM PC, and here we are stuck with inefficient and slow 8237 :-)
Note that the stack location is not defined correctly between these two instructions. So if an interrupt occurs during that time a random memory locations (new SS, old SP, and below) will be modified, possibly corrupting program's or system's memory. Disabling interrupts using CLI before changing stack address does not provide complete workaround, because it doesn't disable NMI. Newer 8088 processors (Intel 8088 marked '81 or '81, '83, all CMOS 80C88, and all V20) don't check for interrupts after the MOV sreg,reg/mem and POP sreg instructions, effectively disabling the interrupts for one instruction. Note that interrupts are disabled after changing any segment register, not just SS (some sources mention that on 286+ processors interrupts are disabled only after changing SS). Early Intel 8088 processors (marked "INTEL '78" or "(C) 1978" on the package) don't provide this workaround, and therefore they are susceptible to memory corruption during stack location change.
1. Put CPU in single step mode
2. Execute an instruction that changes a segment register (DS or ES, do not use SS!)
3. Check if single step interrupt executed for address following the segment change instruction. If it is executed - the processor is buggy.
See cpu.inc file from Sergey's XT BIOS for the implementation.
(Partial) workaround is disabling interrupts before changing stack register. On IBM PC compatible computers it is also possible to disable NMIs (using port B - 61h).
Not a bug - no workaround necessary
REP ES MOVSW
All 8088 and 80C88 will execute POP CS instruction (0Fh), loading CS from the stack, and incrementing IP by 1.
FDC - NEC design