Skip to content
This repository has been archived by the owner on Dec 24, 2020. It is now read-only.

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
layout title permalink machines
page
COMPAQ Portable (128Kb) with Monochrome Graphics and Debugger
/devices/pcx86/machine/compaq/portable/vdu/128kb/debugger/
id type debugger
compaq-portable-128kb
pcx86
true

{% include machine.html id="compaq-portable-128kb" %}

Debugging Notes

I originally created the XML File for this machine by copying an IBM PC configuration with a monochrome display adapter and motherboard SW1 settings 01000001. Note that the SW1 monitor switches, SW1[5] and SW1[6], are both off (0), indicating a monochrome monitor.

However, when I booted the machine, the BIOS displayed error 501 in the top left corner. I tracked this error down to the following code, which sets the CGA Mode register to 0x21 (instead of the normal 0x2D), programs the CRTC's CURSORLO/CURSORHI registers to a large value (0xAA55 is masked with 0x3FFF yielding 0x2A55), then reads CURSORHI, expecting 0x2A, and then finally verifies the existence of video memory at B800:0000; it seems to expect the frame buffer to be addressible at both MDA and CGA addresses.

&F000:E48D C70672003412     MOV      [0072],1234              ;history=4
&F000:E493 A06500           MOV      AL,[0065]                ;history=3
&F000:E496 24F7             AND      AL,F7                    ;history=2
&F000:E498 BAD803           MOV      DX,03D8                  ;history=1
>> tr
videoMDA.outPort(0x03D8,MODE,0x21) at F000:E49B
AX=0021 BX=E3C6 CX=0004 DX=03D8 SP=0400 BP=2000 SI=E3C2 DI=001E 
SS=0000 DS=0040 ES=0040 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E49C BF0200           MOV      DI,0002                  ;cycles=12
>> tr
AX=0021 BX=E3C6 CX=0004 DX=03D8 SP=0400 BP=2000 SI=E3C2 DI=0002 
SS=0000 DS=0040 ES=0040 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E49F B955AA           MOV      CX,AA55                  ;cycles=12
>> tr
AX=0021 BX=E3C6 CX=AA55 DX=03D8 SP=0400 BP=2000 SI=E3C2 DI=0002 
SS=0000 DS=0040 ES=0040 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E4A2 81E1FF3F         AND      CX,3FFF                  ;cycles=12
>> tr
AX=0021 BX=E3C6 CX=2A55 DX=03D8 SP=0400 BP=2000 SI=E3C2 DI=0002 
SS=0000 DS=0040 ES=0040 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E4A6 BAD403           MOV      DX,03D4                  ;cycles=16
>> tr
AX=0021 BX=E3C6 CX=2A55 DX=03D4 SP=0400 BP=2000 SI=E3C2 DI=0002 
SS=0000 DS=0040 ES=0040 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E4A9 B30E             MOV      BL,0E                    ;cycles=12
>> tr
AX=0021 BX=E30E CX=2A55 DX=03D4 SP=0400 BP=2000 SI=E3C2 DI=0002 
SS=0000 DS=0040 ES=0040 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E4AB E8C604           CALL     E974 (romBIOS+0x0974)    ;cycles=12
>> pr
videoMDA.outPort(0x03D4,CRTC.INDX,0x0E) at F000:E976
videoMDA.outPort(0x03D5,CRTC.CURSORHI,0x2A) at F000:E97A
videoMDA.outPort(0x03D4,CRTC.INDX,0x0F) at F000:E980
videoMDA.outPort(0x03D5,CRTC.CURSORLO,0x55) at F000:E984
AX=0055 BX=E30F CX=2A55 DX=03D5 SP=0400 BP=2000 SI=E3C2 DI=0002 
SS=0000 DS=0040 ES=0040 PS=F002 V0 D0 I0 T0 S0 Z0 A0 P0 C0 
&F000:E4AE 4A               DEC      DX                       ;cycles=164
>> tr
AX=0055 BX=E30F CX=2A55 DX=03D4 SP=0400 BP=2000 SI=E3C2 DI=0002 
SS=0000 DS=0040 ES=0040 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E4AF B00E             MOV      AL,0E                    ;cycles=6
>> tr
AX=000E BX=E30F CX=2A55 DX=03D4 SP=0400 BP=2000 SI=E3C2 DI=0002 
SS=0000 DS=0040 ES=0040 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E4B1 EE               OUT      DX,AL                    ;cycles=12
>> tr
videoMDA.outPort(0x03D4,CRTC.INDX,0x0E) at F000:E4B1
AX=000E BX=E30F CX=2A55 DX=03D4 SP=0400 BP=2000 SI=E3C2 DI=0002 
SS=0000 DS=0040 ES=0040 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E4B2 42               INC      DX                       ;cycles=12
>> tr
AX=000E BX=E30F CX=2A55 DX=03D5 SP=0400 BP=2000 SI=E3C2 DI=0002 
SS=0000 DS=0040 ES=0040 PS=F002 V0 D0 I0 T0 S0 Z0 A0 P0 C0 
&F000:E4B3 EC               IN       AL,DX                    ;cycles=6
>> tr
videoMDA.inPort(0x03D5,CRTC.CURSORHI) at F000:E4B3
AX=00FF BX=E30F CX=2A55 DX=03D5 SP=0400 BP=2000 SI=E3C2 DI=0002 
SS=0000 DS=0040 ES=0040 PS=F002 V0 D0 I0 T0 S0 Z0 A0 P0 C0 
&F000:E4B4 3AC5             CMP      AL,CH                    ;cycles=12

A 1986 COMPAQ Maintenance and Service Guide indicated that error 501 was a "Display Controller Failure (Video Display or Video Controller Board)". And the 1982 COMPAQ Operations Guide contained some information on switch settings on p. 18 of the "320-KBYTE DISK DRIVE" manual (p. 259 of the entire PDF), where it documents only two values for the SW1 monitor switches:

  • 10: COMPAQ VIDEO BOARD (DEFAULT)
  • 00: COMPAQ VIDEO & IBM MONOCHROME BOARDS

For reference, here are the SW1 monitor switch values originally defined by IBM:

  • 11: NONE
  • 01: TV (COMPOSITE)
  • 10: COLOR DISPLAY
  • 00: MONOCHROME DISPLAY

COMPAQ's descriptions were a bit cryptic, but since I had already tried 00, there was no harm in trying 10.

On this new boot attempt, there was no cursor initially, and two different errors were displayed: 301 and 401. But then the COMPAQ MS-DOS 1.10 date and time prompts appeared -- success!

Ignoring the SW1 monitor error for the moment, the next order of business was to isolate the cause of other errors: 301 ("Keyboard Error") and 401 ("Printer Error").

It turned out that the printer issue was easily resolved by changing the parallel port's adapter number from 2 to 1, which changes the port's base I/O address from 0x378 to 0x3BC. The latter is what's normally used by the built-in parallel port on an IBM monochrome adapter, so either COMPAQ used the same default address or the BIOS assumed that a monochrome card was installed. Or something like that.

Next, I'll work on figuring out the keyboard error, and then I'll take a look at how the COMPAQ BIOS detects and initializes the video hardware.

Keyboard Error

Setting a write breakpoint on video memory (bw b800:0) eventually led me to following code:

>> pr
AX=0E20 BX=0007 CX=0000 DX=0008 SP=0400 BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F046 V0 D0 I0 T0 S0 Z1 A0 P1 C0 
&F000:E5D9 BA0103           MOV      DX,0301                  ;cycles=16
>> pr
AX=0E20 BX=0007 CX=0000 DX=0301 SP=0400 BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F046 V0 D0 I0 T0 S0 Z1 A0 P1 C0 
&F000:E5DC E856FC           CALL     E235 (romBIOS+0x0235)    ;cycles=12

after which " 301" appeared at the top of the screen. From there, I was able to backtrack to the first bit code that appeared to tinker with the 8255 (the original PC keyboard interface) via ports 0x60 and 0x61:

&F000:E538 BA2100           MOV      DX,0021
&F000:E53B E851FD           CALL     E28F (romBIOS+0x028F)
&F000:E53E B0FF             MOV      AL,FF
&F000:E540 EE               OUT      DX,AL
&F000:E541 E461             IN       AL,61

But first, I was curious about that code at E538 -- which it turns out was simply verifying that all possible 8-bit values could be written to and read back from the PIC's IMR. Here's what E28F looks like:

romBIOS+0x028F:
&F000:E28F 33C0             XOR      AX,AX
&F000:E291 B90001           MOV      CX,0100
&F000:E294 EE               OUT      DX,AL
&F000:E295 EE               OUT      DX,AL
&F000:E296 EC               IN       AL,DX
&F000:E297 3AC4             CMP      AL,AH
&F000:E299 750C             JNZ      E2A7 (romBIOS+0x02A7)
&F000:E29B EC               IN       AL,DX
&F000:E29C 3AC4             CMP      AL,AH
&F000:E29E 7507             JNZ      E2A7 (romBIOS+0x02A7)
&F000:E2A0 FEC0             INC      AL
&F000:E2A2 FEC4             INC      AH
&F000:E2A4 E2EE             LOOP     E294 (romBIOS+0x0294)
&F000:E2A6 C3               RET     
&F000:E2A7 58               POP      AX
&F000:E2A8 FFE3             JMP      BX

And E28F is called many other times, for many other ports, including port 0x61. And in the process of writing every possible value to port 0x61, a keyboard reset is triggered, BUT that's not the keyboard reset we care about. That comes later, in the code below. At this point, I've also turned on keyboard messages (m kbd on) and port messages (m port on) in the PCjs debugger.

>> tr
AX=0000 BX=E595 CX=0000 DX=0008 SP=0400 BP=2000 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F002 V0 D0 I0 T0 S0 Z0 A0 P0 C0 
&F000:E59B E461             IN       AL,61                    ;cycles=19
>> tr
AX=004D BX=E595 CX=0000 DX=0008 SP=0400 BP=2000 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F002 V0 D0 I0 T0 S0 Z0 A0 P0 C0 
&F000:E59D 0C80             OR       AL,80                    ;cycles=18
>> tr
AX=00CD BX=E595 CX=0000 DX=0008 SP=0400 BP=2000 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F082 V0 D0 I0 T0 S1 Z0 A0 P0 C0 
&F000:E59F 24BF             AND      AL,BF                    ;cycles=12
>> tr
AX=008D BX=E595 CX=0000 DX=0008 SP=0400 BP=2000 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F086 V0 D0 I0 T0 S1 Z0 A0 P1 C0 
&F000:E5A1 E661             OUT      61,AL                    ;cycles=12
>> tr
keyboard clock line changing to false
keyboard data line changing to false
AX=008D BX=E595 CX=0000 DX=0008 SP=0400 BP=2000 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F086 V0 D0 I0 T0 S1 Z0 A0 P1 C0 
&F000:E5A3 247F             AND      AL,7F                    ;cycles=18
>> tr
AX=000D BX=E595 CX=0000 DX=0008 SP=0400 BP=2000 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F002 V0 D0 I0 T0 S0 Z0 A0 P0 C0 
&F000:E5A5 E661             OUT      61,AL                    ;cycles=12
>> tr
keyboard data line changing to true
chipset.receiveKbdData(0x00)
AX=000D BX=E595 CX=0000 DX=0008 SP=0400 BP=2000 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F002 V0 D0 I0 T0 S0 Z0 A0 P0 C0 
&F000:E5A7 BB2800           MOV      BX,0028                  ;cycles=18
>> tr
AX=000D BX=0028 CX=0000 DX=0008 SP=0400 BP=2000 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F002 V0 D0 I0 T0 S0 Z0 A0 P0 C0 
&F000:E5AA E856FC           CALL     E203 (romBIOS+0x0203)    ;cycles=12
>> u e203
romBIOS+0x0203:
&F000:E203 5D               POP      BP
&F000:E204 B90401           MOV      CX,0104
&F000:E207 E2FE             LOOP     E207 (romBIOS+0x0207)
&F000:E209 4B               DEC      BX
&F000:E20A 75F8             JNZ      E204 (romBIOS+0x0204)
&F000:E20C FFE5             JMP      BP
>> g e20c
running
stopped (30331 opcodes, 213962 cycles, 1538868214773 ms, 0 hz)
AX=000D BX=0000 CX=0000 DX=0008 SP=0400 BP=E5AD SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F046 V0 D0 I0 T0 S0 Z1 A0 P1 C0 
&F000:E20C FFE5             JMP      BP
>> tr
AX=000D BX=0000 CX=0000 DX=0008 SP=0400 BP=E5AD SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F046 V0 D0 I0 T0 S0 Z1 A0 P1 C0 
&F000:E5AD 0C40             OR       AL,40                    ;cycles=19
>> tr
AX=004D BX=0000 CX=0000 DX=0008 SP=0400 BP=E5AD SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E5AF E661             OUT      61,AL                    ;cycles=12
>> tr
keyboard clock line changing to true
keyboard reset
keyboard response 0xAA buffered
chipset.receiveKbdData(0xAA)
keyboard data 0xAA delivered
AX=004D BX=0000 CX=0000 DX=0008 SP=0400 BP=E5AD SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E5B1 B314             MOV      BL,14                    ;cycles=18
>> tr
AX=004D BX=0014 CX=0000 DX=0008 SP=0400 BP=E5AD SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E5B3 E84DFC           CALL     E203 (romBIOS+0x0203)    ;cycles=12
>> pr
chipset.receiveKbdData(0x00)
keyboard data 0x00 delivered
AX=004D BX=0000 CX=0000 DX=0008 SP=0400 BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F046 V0 D0 I0 T0 S0 Z1 A0 P1 C0 
&F000:E5B6 E83404           CALL     E9ED (romBIOS+0x09ED)    ;cycles=109774
>> u e9ed
romBIOS+0x09ED:
&F000:E9ED E460             IN       AL,60
&F000:E9EF 86E0             XCHG     AH,AL
&F000:E9F1 E461             IN       AL,61
&F000:E9F3 0C80             OR       AL,80
&F000:E9F5 E661             OUT      61,AL
&F000:E9F7 247F             AND      AL,7F
&F000:E9F9 E661             OUT      61,AL
&F000:E9FB C3               RET     
>> tr
AX=004D BX=0000 CX=0000 DX=0008 SP=03FE BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F046 V0 D0 I0 T0 S0 Z1 A0 P1 C0 
&F000:E9ED E460             IN       AL,60                    ;cycles=31
>> tr
chipset.inPort(0x0060,PPI_A): 0x00 at F000:E9ED
AX=0000 BX=0000 CX=0000 DX=0008 SP=03FE BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F046 V0 D0 I0 T0 S0 Z1 A0 P1 C0 
&F000:E9EF 86E0             XCHG     AH,AL                    ;cycles=18
>> tr
AX=0000 BX=0000 CX=0000 DX=0008 SP=03FE BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F046 V0 D0 I0 T0 S0 Z1 A0 P1 C0 
&F000:E9F1 E461             IN       AL,61                    ;cycles=12
>> tr
AX=004D BX=0000 CX=0000 DX=0008 SP=03FE BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F046 V0 D0 I0 T0 S0 Z1 A0 P1 C0 
&F000:E9F3 0C80             OR       AL,80                    ;cycles=18
>> tr
AX=00CD BX=0000 CX=0000 DX=0008 SP=03FE BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F082 V0 D0 I0 T0 S1 Z0 A0 P0 C0 
&F000:E9F5 E661             OUT      61,AL                    ;cycles=12
>> tr
keyboard data line changing to false
AX=00CD BX=0000 CX=0000 DX=0008 SP=03FE BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F082 V0 D0 I0 T0 S1 Z0 A0 P0 C0 
&F000:E9F7 247F             AND      AL,7F                    ;cycles=18
>> tr
AX=004D BX=0000 CX=0000 DX=0008 SP=03FE BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E9F9 E661             OUT      61,AL                    ;cycles=12
>> tr
keyboard data line changing to true
chipset.receiveKbdData(0x00)
keyboard data 0x00 delivered
AX=004D BX=0000 CX=0000 DX=0008 SP=03FE BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E9FB C3               RET                               ;cycles=18
>> tr
AX=004D BX=0000 CX=0000 DX=0008 SP=0400 BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E5B9 86C4             XCHG     AL,AH                    ;cycles=16
>> tr
AX=4D00 BX=0000 CX=0000 DX=0008 SP=0400 BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E5BB 3CAA             CMP      AL,AA                    ;cycles=12
>> tr
AX=4D00 BX=0000 CX=0000 DX=0008 SP=0400 BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F017 V0 D0 I0 T0 S0 Z0 A1 P1 C1 
&F000:E5BD 750E             JNZ      E5CD (romBIOS+0x05CD)    ;cycles=12
>> tr
AX=4D00 BX=0000 CX=0000 DX=0008 SP=0400 BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F017 V0 D0 I0 T0 S0 Z0 A1 P1 C1 
&F000:E5CD 0AC0             OR       AL,AL                    ;cycles=20
>> tr
AX=4D00 BX=0000 CX=0000 DX=0008 SP=0400 BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F056 V0 D0 I0 T0 S0 Z1 A1 P1 C0 
&F000:E5CF 7403             JZ       E5D4 (romBIOS+0x05D4)    ;cycles=11
>> tr
AX=4D00 BX=0000 CX=0000 DX=0008 SP=0400 BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F056 V0 D0 I0 T0 S0 Z1 A1 P1 C0 
&F000:E5D4 B020             MOV      AL,20                    ;cycles=20
>> tr
AX=4D20 BX=0000 CX=0000 DX=0008 SP=0400 BP=E5B6 SI=0001 DI=4000 
SS=0000 DS=F000 ES=B800 PS=F056 V0 D0 I0 T0 S0 Z1 A1 P1 C0 
&F000:E5D6 E8AEFC           CALL     E287 (romBIOS+0x0287)    ;cycles=12
>> u
romBIOS+0x05D9:
&F000:E5D9 BA0103           MOV      DX,0301
&F000:E5DC E856FC           CALL     E235 (romBIOS+0x0235)
&F000:E5DF BABC03           MOV      DX,03BC
&F000:E5E2 EC               IN       AL,DX
&F000:E5E3 50               PUSH     AX
&F000:E5E4 BBECE5           MOV      BX,E5EC
&F000:E5E7 E8A5FC           CALL     E28F (romBIOS+0x028F)
&F000:E5EA EB06             JMP      E5F2 (romBIOS+0x05F2)

So what do we deduce from the above code? E5AF is where the keyboard is reset and the standard 0xAA response is queued up and delivered. Then the BIOS calls E203, which just spins for a short time, and then it calls E9ED, which reads the keyboard's response.

The problem is that my Keyboard component wants to deliver the next byte in its queue every msTransmit milliseconds, and that timeout was originally set to 15ms, but apparently the COMPAQ BIOS delay loop at E203 takes longer than 15ms, and so the previous 0xAA response gets replaced with 0x00 (indicating no more keyboard data) BEFORE the BIOS gets around to reading the response.

It's possible that I shouldn't replace the 0xAA response unless another scan or response code has been queued up, but I've debugged too many BIOS handlers, keyboard interrupt handlers, Windows 1.x keyboard device drivers, etc, to risk changing that behavior now. Besides, it turns that a simpler and safer solution was to simply bump the Keyboard component's msTransmit value up from 15ms to 25ms.

So that's what I did, and happily, it seems to have cured the 301 keyboard error.

Revisiting the COMPAQ VDU

For a baseline, I first looked at all IBM 5150 MDA I/O performed by the IBM ROM:

videoMDA.outPort(0x03D8,MODE,0x00) at F000:E0C3
videoMDA.outPort(0x03B8,MODE,0x01) at F000:E0C9
videoMDA.outPort(0x03B8,MODE,0x01) at F000:F11E
videoMDA.outPort(0x03B4,CRTC.INDX,0x00) at F000:F146
videoMDA.outPort(0x03B5,CRTC.HTOTAL,0x61) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x01) at F000:F146
videoMDA.outPort(0x03B5,CRTC.HDISP,0x50) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x02) at F000:F146
videoMDA.outPort(0x03B5,CRTC.HSPOS,0x52) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x03) at F000:F146
videoMDA.outPort(0x03B5,CRTC.HSWIDTH,0x0F) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x04) at F000:F146
videoMDA.outPort(0x03B5,CRTC.VTOTAL,0x19) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x05) at F000:F146
videoMDA.outPort(0x03B5,CRTC.VTOTADJ,0x06) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x06) at F000:F146
videoMDA.outPort(0x03B5,CRTC.VDISP,0x19) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x07) at F000:F146
videoMDA.outPort(0x03B5,CRTC.VSPOS,0x19) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x08) at F000:F146
videoMDA.outPort(0x03B5,CRTC.ILMODE,0x02) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x09) at F000:F146
videoMDA.outPort(0x03B5,CRTC.MAXSCAN,0x0D) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0A) at F000:F146
videoMDA.outPort(0x03B5,CRTC.CURSCAN,0x0B) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0B) at F000:F146
videoMDA.outPort(0x03B5,CRTC.CURSCANB,0x0C) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0C) at F000:F146
videoMDA.outPort(0x03B5,CRTC.STARTHI,0x00) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0D) at F000:F146
videoMDA.outPort(0x03B5,CRTC.STARTLO,0x00) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0E) at F000:F146
videoMDA.outPort(0x03B5,CRTC.CURSORHI,0x00) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0F) at F000:F146
videoMDA.outPort(0x03B5,CRTC.CURSORLO,0x00) at F000:F14C
videoMDA.outPort(0x03B8,MODE,0x29) at F000:F190
bus.outPort(0x03B9,unknown,0x30) at F000:F1C3
videoMDA.outPort(0x03B8,MODE,0x01) at F000:E392
videoMDA.outPort(0x03B8,MODE,0x01) at F000:F11E
videoMDA.outPort(0x03B4,CRTC.INDX,0x00) at F000:F146
videoMDA.outPort(0x03B5,CRTC.HTOTAL,0x61) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x01) at F000:F146
videoMDA.outPort(0x03B5,CRTC.HDISP,0x50) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x02) at F000:F146
videoMDA.outPort(0x03B5,CRTC.HSPOS,0x52) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x03) at F000:F146
videoMDA.outPort(0x03B5,CRTC.HSWIDTH,0x0F) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x04) at F000:F146
videoMDA.outPort(0x03B5,CRTC.VTOTAL,0x19) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x05) at F000:F146
videoMDA.outPort(0x03B5,CRTC.VTOTADJ,0x06) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x06) at F000:F146
videoMDA.outPort(0x03B5,CRTC.VDISP,0x19) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x07) at F000:F146
videoMDA.outPort(0x03B5,CRTC.VSPOS,0x19) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x08) at F000:F146
videoMDA.outPort(0x03B5,CRTC.ILMODE,0x02) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x09) at F000:F146
videoMDA.outPort(0x03B5,CRTC.MAXSCAN,0x0D) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0A) at F000:F146
videoMDA.outPort(0x03B5,CRTC.CURSCAN,0x0B) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0B) at F000:F146
videoMDA.outPort(0x03B5,CRTC.CURSCANB,0x0C) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0C) at F000:F146
videoMDA.outPort(0x03B5,CRTC.STARTHI,0x00) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0D) at F000:F146
videoMDA.outPort(0x03B5,CRTC.STARTLO,0x00) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0E) at F000:F146
videoMDA.outPort(0x03B5,CRTC.CURSORHI,0x00) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0F) at F000:F146
videoMDA.outPort(0x03B5,CRTC.CURSORLO,0x00) at F000:F14C
videoMDA.outPort(0x03B8,MODE,0x29) at F000:F190
bus.outPort(0x03B9,unknown,0x30) at F000:F1C3
videoMDA.outPort(0x03B8,MODE,0x01) at F000:F11E
videoMDA.outPort(0x03B4,CRTC.INDX,0x00) at F000:F146
videoMDA.outPort(0x03B5,CRTC.HTOTAL,0x61) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x01) at F000:F146
videoMDA.outPort(0x03B5,CRTC.HDISP,0x50) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x02) at F000:F146
videoMDA.outPort(0x03B5,CRTC.HSPOS,0x52) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x03) at F000:F146
videoMDA.outPort(0x03B5,CRTC.HSWIDTH,0x0F) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x04) at F000:F146
videoMDA.outPort(0x03B5,CRTC.VTOTAL,0x19) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x05) at F000:F146
videoMDA.outPort(0x03B5,CRTC.VTOTADJ,0x06) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x06) at F000:F146
videoMDA.outPort(0x03B5,CRTC.VDISP,0x19) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x07) at F000:F146
videoMDA.outPort(0x03B5,CRTC.VSPOS,0x19) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x08) at F000:F146
videoMDA.outPort(0x03B5,CRTC.ILMODE,0x02) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x09) at F000:F146
videoMDA.outPort(0x03B5,CRTC.MAXSCAN,0x0D) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0A) at F000:F146
videoMDA.outPort(0x03B5,CRTC.CURSCAN,0x0B) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0B) at F000:F146
videoMDA.outPort(0x03B5,CRTC.CURSCANB,0x0C) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0C) at F000:F146
videoMDA.outPort(0x03B5,CRTC.STARTHI,0x00) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0D) at F000:F146
videoMDA.outPort(0x03B5,CRTC.STARTLO,0x00) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0E) at F000:F146
videoMDA.outPort(0x03B5,CRTC.CURSORHI,0x00) at F000:F14C
videoMDA.outPort(0x03B4,CRTC.INDX,0x0F) at F000:F146
videoMDA.outPort(0x03B5,CRTC.CURSORLO,0x00) at F000:F14C
videoMDA.outPort(0x03B8,MODE,0x29) at F000:F190
bus.outPort(0x03B9,unknown,0x30) at F000:F1C3
bus.outPort(0x03BC,unknown,0xAA) at F000:E5BE
bus.inPort(0x03BC,unknown) at F000:E5C1
*bus.outPort(0x0278,unknown,0xAA) at F000:E5BE
bus.inPort(0x0278,unknown) at F000:E5C1
bus.inPort(0x0201,unknown) at F000:E605

NOTE: The writes to port 3B9 are from code that initializes the Color Select (aka Overscan) register, which doesn't exist on an MDA; on a CGA, the port is 3D9. Similarly, MDA port 3BC corresponds to CGA port 3DC (Light Pen), but like 3B9, MDA ports 3BC and 3BD do not exist.

One of things we see from the above programming patterns is that the ROM first writes 0x01 to the Mode register, then reprograms the CRTC, and finally writes 0x29 to the Mode register.

Now let's look at how COMPAQ programs its VDU, when SW1 monitor switches SW1[5] and SW1[6] are set to 00, indicating a monochrome monitor:

PCx86 v1.72.3
Copyright © 2012-2019 Jeff Parsons <[email protected]>
License: GPL version 3 or later <http://gnu.org/licenses/gpl.html>
Loading /devices/pcx86/rom/compaq/portable/100518-001-REVB.json.......
Loading /devices/pcx86/video/ibm/mda/ibm-mda.json.......
Loading /disks-demo/pcx86/dos/compaq/1.10/COMPAQ-DOS110.json.......
Bus: 8Kb ROM at 000FE000
FDC: Mounted diskette "COMPAQ MS-DOS 1.10" in drive A
Bus: 128Kb RAM at 0000
Bus: 4Kb VIDEO at 000B0000
Type ? for help with PCx86 Debugger commands
AX=0000 BX=0000 CX=0000 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000 
SS=0000 DS=0000 ES=0000 PS=F002 V0 D0 I0 T0 S0 Z0 A0 P0 C0 
&FFFF:0000 EA5BE000F0       JMP      &F000:E05B (romBIOS+0x005B)
>> bp f000:e49c
bp &F000:E49C set
>> bp 0:7c00
bp &0000:7C00 set
>> m video on
messages on:  video
>> m port on
messages on:  port
>> g
running
videoMDA.outPort(0x03B8,MODE,0x01) at F000:E079
videoMDA.outPort(0x03B4,CRTC.INDX,0x00) at F000:E084
videoMDA.outPort(0x03B5,CRTC.HTOTAL,0x61) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x01) at F000:E084
videoMDA.outPort(0x03B5,CRTC.HDISP,0x50) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x02) at F000:E084
videoMDA.outPort(0x03B5,CRTC.HSPOS,0x52) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x03) at F000:E084
videoMDA.outPort(0x03B5,CRTC.HSWIDTH,0x0F) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x04) at F000:E084
videoMDA.outPort(0x03B5,CRTC.VTOTAL,0x19) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x05) at F000:E084
videoMDA.outPort(0x03B5,CRTC.VTOTADJ,0x06) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x06) at F000:E084
videoMDA.outPort(0x03B5,CRTC.VDISP,0x19) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x07) at F000:E084
videoMDA.outPort(0x03B5,CRTC.VSPOS,0x19) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x08) at F000:E084
videoMDA.outPort(0x03B5,CRTC.ILMODE,0x02) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x09) at F000:E084
videoMDA.outPort(0x03B5,CRTC.MAXSCAN,0x0D) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x0A) at F000:E084
videoMDA.outPort(0x03B5,CRTC.CURSCAN,0x0B) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x0B) at F000:E084
videoMDA.outPort(0x03B5,CRTC.CURSCANB,0x0C) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x0C) at F000:E084
videoMDA.outPort(0x03B5,CRTC.STARTHI,0x00) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x0D) at F000:E084
videoMDA.outPort(0x03B5,CRTC.STARTLO,0x00) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x0E) at F000:E084
videoMDA.outPort(0x03B5,CRTC.CURSORHI,0x00) at F000:E087
videoMDA.outPort(0x03B4,CRTC.INDX,0x0F) at F000:E084
videoMDA.outPort(0x03B5,CRTC.CURSORLO,0x00) at F000:E087
checkCursor(): cursor shape changed from NaN,NaN to 11,2 (0x0B-0x0C)
videoMDA.outPort(0x03B8,MODE,0x29) at F000:E0AC
videoMDA.outPort(0x03D8,MODE,0x01) at F000:E079
videoMDA.outPort(0x03D4,CRTC.INDX,0x00) at F000:E084
videoMDA.outPort(0x03D5,CRTC.HTOTAL,0x71) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x01) at F000:E084
videoMDA.outPort(0x03D5,CRTC.HDISP,0x50) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x02) at F000:E084
videoMDA.outPort(0x03D5,CRTC.HSPOS,0x5A) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x03) at F000:E084
videoMDA.outPort(0x03D5,CRTC.HSWIDTH,0x0A) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x04) at F000:E084
videoMDA.outPort(0x03D5,CRTC.VTOTAL,0x19) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x05) at F000:E084
videoMDA.outPort(0x03D5,CRTC.VTOTADJ,0x06) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x06) at F000:E084
videoMDA.outPort(0x03D5,CRTC.VDISP,0x19) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x07) at F000:E084
videoMDA.outPort(0x03D5,CRTC.VSPOS,0x19) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x08) at F000:E084
videoMDA.outPort(0x03D5,CRTC.ILMODE,0x02) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x09) at F000:E084
videoMDA.outPort(0x03D5,CRTC.MAXSCAN,0x0D) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x0A) at F000:E084
videoMDA.outPort(0x03D5,CRTC.CURSCAN,0x0B) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x0B) at F000:E084
videoMDA.outPort(0x03D5,CRTC.CURSCANB,0x0C) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x0C) at F000:E084
videoMDA.outPort(0x03D5,CRTC.STARTHI,0x00) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x0D) at F000:E084
videoMDA.outPort(0x03D5,CRTC.STARTLO,0x00) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x0E) at F000:E084
videoMDA.outPort(0x03D5,CRTC.CURSORHI,0x00) at F000:E087
videoMDA.outPort(0x03D4,CRTC.INDX,0x0F) at F000:E084
videoMDA.outPort(0x03D5,CRTC.CURSORLO,0x00) at F000:E087
videoMDA.outPort(0x03D9,CGA.COLOR,0x30) at F000:E09A
videoMDA.outPort(0x03D8,MODE,0x2D) at F000:E0AC
bus.outPort(0x000F,unknown,0x0E) at F000:E0DB
bus.inPort(0x0201,unknown) at F000:E415
bus.inPort(0x02FB,unknown) at F000:E436
bus.outPort(0x02FB,unknown,0x00) at F000:E439
bus.inPort(0x02FB,unknown) at F000:E43C
 bus.inPort(0x0378,unknown) at F000:E459
bus.outPort(0x0378,unknown,0x00) at F000:E45C
bus.inPort(0x0378,unknown) at F000:E45F
bus.inPort(0x0278,unknown) at F000:E459
bus.outPort(0x0278,unknown,0x00) at F000:E45C
bus.inPort(0x0278,unknown) at F000:E45F
videoMDA.outPort(0x03B8,MODE,0x01) at F000:F167
videoMDA.outPort(0x03B8,MODE,0x21) at F000:F904
bus.outPort(0x03B9,unknown,0x30) at F000:F908
videoMDA.outPort(0x03B4,CRTC.INDX,0x00) at F000:F912
videoMDA.outPort(0x03B5,CRTC.HTOTAL,0x61) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x01) at F000:F912
videoMDA.outPort(0x03B5,CRTC.HDISP,0x50) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x02) at F000:F912
videoMDA.outPort(0x03B5,CRTC.HSPOS,0x52) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x03) at F000:F912
videoMDA.outPort(0x03B5,CRTC.HSWIDTH,0x0F) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x04) at F000:F912
videoMDA.outPort(0x03B5,CRTC.VTOTAL,0x19) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x05) at F000:F912
videoMDA.outPort(0x03B5,CRTC.VTOTADJ,0x06) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x06) at F000:F912
videoMDA.outPort(0x03B5,CRTC.VDISP,0x19) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x07) at F000:F912
videoMDA.outPort(0x03B5,CRTC.VSPOS,0x19) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x08) at F000:F912
videoMDA.outPort(0x03B5,CRTC.ILMODE,0x02) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x09) at F000:F912
videoMDA.outPort(0x03B5,CRTC.MAXSCAN,0x0D) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x0A) at F000:F912
videoMDA.outPort(0x03B5,CRTC.CURSCAN,0x0B) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x0B) at F000:F912
videoMDA.outPort(0x03B5,CRTC.CURSCANB,0x0C) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x0C) at F000:F912
videoMDA.outPort(0x03B5,CRTC.STARTHI,0x00) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x0D) at F000:F912
videoMDA.outPort(0x03B5,CRTC.STARTLO,0x00) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x0E) at F000:F912
videoMDA.outPort(0x03B5,CRTC.CURSORHI,0x00) at F000:F917
videoMDA.outPort(0x03B4,CRTC.INDX,0x0F) at F000:F912
videoMDA.outPort(0x03B5,CRTC.CURSORLO,0x00) at F000:F917
videoMDA.outPort(0x03B8,MODE,0x29) at F000:F1E5
videoMDA.outPort(0x03D8,MODE,0x21) at F000:E49B
bp &F000:E49C hit
stopped (3880368 opcodes, 51394154 cycles, 1540092234147 ms, 0 hz)
AX=0021 BX=E3C6 CX=0004 DX=03D8 SP=0400 BP=2000 SI=E3C2 DI=001E 
SS=0000 DS=0040 ES=0040 PS=F006 V0 D0 I0 T0 S0 Z0 A0 P1 C0 
&F000:E49C BF0200           MOV      DI,0002
>> u
romBIOS+0x049F:
&F000:E49F B955AA           MOV      CX,AA55
&F000:E4A2 81E1FF3F         AND      CX,3FFF
&F000:E4A6 BAD403           MOV      DX,03D4
&F000:E4A9 B30E             MOV      BL,0E
&F000:E4AB E8C604           CALL     E974 (romBIOS+0x0974)
&F000:E4AE 4A               DEC      DX
&F000:E4AF B00E             MOV      AL,0E
&F000:E4B1 EE               OUT      DX,AL
>> u
romBIOS+0x04B2:
&F000:E4B2 42               INC      DX
&F000:E4B3 EC               IN       AL,DX
&F000:E4B4 3AC5             CMP      AL,CH
&F000:E4B6 7543             JNZ      E4FB (romBIOS+0x04FB)
&F000:E4B8 4A               DEC      DX
&F000:E4B9 B00F             MOV      AL,0F
&F000:E4BB EE               OUT      DX,AL
&F000:E4BC 42               INC      DX
>> u
romBIOS+0x04BD:
&F000:E4BD EC               IN       AL,DX
&F000:E4BE 3AC1             CMP      AL,CL
&F000:E4C0 7539             JNZ      E4FB (romBIOS+0x04FB)
&F000:E4C2 F7D1             NOT      CX
&F000:E4C4 4F               DEC      DI
&F000:E4C5 75DB             JNZ      E4A2 (romBIOS+0x04A2)
&F000:E4C7 B800B8           MOV      AX,B800
&F000:E4CA 8EC0             MOV      ES,AX
>> u
romBIOS+0x04CC:
&F000:E4CC 33DB             XOR      BX,BX
&F000:E4CE 33FF             XOR      DI,DI
&F000:E4D0 B90040           MOV      CX,4000
&F000:E4D3 8BC7             MOV      AX,DI
&F000:E4D5 32C4             XOR      AL,AH
&F000:E4D7 7B02             JNP      E4DB (romBIOS+0x04DB)
&F000:E4D9 FEC0             INC      AL
&F000:E4DB 32C3             XOR      AL,BL
>> bp &f000:e4c7
bp &F000:E4C7 set
>> g
running
videoMDA.outPort(0x03D4,CRTC.INDX,0x0E) at F000:E976
videoMDA.outPort(0x03D5,CRTC.CURSORHI,0x2A) at F000:E97A
videoMDA.outPort(0x03D4,CRTC.INDX,0x0F) at F000:E980
videoMDA.outPort(0x03D5,CRTC.CURSORLO,0x55) at F000:E984
videoMDA.outPort(0x03D4,CRTC.INDX,0x0E) at F000:E4B1
videoMDA.inPort(0x03D5,CRTC.CURSORHI): 0x2A at F000:E4B3
videoMDA.outPort(0x03D4,CRTC.INDX,0x0F) at F000:E4BB
videoMDA.inPort(0x03D5,CRTC.CURSORLO): 0x55 at F000:E4BD
videoMDA.outPort(0x03D4,CRTC.INDX,0x0E) at F000:E976
videoMDA.outPort(0x03D5,CRTC.CURSORHI,0x15) at F000:E97A
videoMDA.outPort(0x03D4,CRTC.INDX,0x0F) at F000:E980
videoMDA.outPort(0x03D5,CRTC.CURSORLO,0xAA) at F000:E984
videoMDA.outPort(0x03D4,CRTC.INDX,0x0E) at F000:E4B1
videoMDA.inPort(0x03D5,CRTC.CURSORHI): 0x15 at F000:E4B3
videoMDA.outPort(0x03D4,CRTC.INDX,0x0F) at F000:E4BB
videoMDA.inPort(0x03D5,CRTC.CURSORLO): 0xAA at F000:E4BD
bp &F000:E4C7 hit
stopped (70 opcodes, 762 cycles, 1540092270128 ms, 0 hz)
AX=00AA BX=E30F CX=EA55 DX=03D5 SP=0400 BP=2000 SI=E3C2 DI=0000 
SS=0000 DS=0040 ES=0040 PS=F046 V0 D0 I0 T0 S0 Z1 A0 P1 C0 
&F000:E4C7 B800B8           MOV      AX,B800