diff --git a/devices/pc/bios/compaq/deskpro386/1988-01-28.nasm b/devices/pc/bios/compaq/deskpro386/1988-01-28.nasm
index 4e62f2d91..5863a787a 100644
--- a/devices/pc/bios/compaq/deskpro386/1988-01-28.nasm
+++ b/devices/pc/bios/compaq/deskpro386/1988-01-28.nasm
@@ -1,6 +1,6 @@
;
; ROM BIOS for Compaq DeskPro 386-16
-; Rev J.4, from parts 109592-001 and 109591-001, dated 1988-Jan-28
+; Rev J.4, from parts 109592-001 and 109591-001, dated '01/28/88'
; (C)Copyright COMPAQ Computer Corporation 1982,83,84,85,86,87-All rights reserved.
;
; Listing produced by NDISASM, 2015-Apr-04
@@ -2287,7 +2287,7 @@ x9311: cmp ah,al ; 00009311 3AE0 ':.'
db 0x0D,0x0A,'Non-System disk or disk error',0x0D,0x0A,'replace and strike any key when ready',0x0D,0x0A,'$',0x0D,0x0A,'602-Diskette Boot Record Error',0x0D,0x0A,'$'
- mov bx,0x2 ; 00009380 BB0200 '...'
+x9380: mov bx,0x2 ; 00009380 BB0200 '...'
mov cx,0xfde8 ; 00009383 B9E8FD '...'
x9386: mov al,0x80 ; 00009386 B080 '..'
out 0x70,al ; 00009388 E670 '.p'
@@ -2968,6 +2968,9 @@ x9bed: mov al,ah ; 00009BED 8AC4 '..'
loop x9bed ; 00009BF6 E2F5 '..'
jmp bp ; 00009BF8 FFE5 '..'
+ ;
+ ; Clear the screen (DS=F000, BX=BA77 for CGA or BA86 for Mono)
+ ;
x9bfa: mov ax,0x720 ; 00009BFA B82007 '. .'
mov es,[bx+0x6] ; 00009BFD 8E4706 '.G.'
xor di,di ; 00009C00 33FF '3.'
@@ -4619,7 +4622,7 @@ xa9e9: cs rep movsw ; 0000A9E9 F32EA5 '...'
and byte [0x87],0xfb ; 0000AA17 80268700FB '.&...'
jmp short xaa2f ; 0000AA1C EB11 '..'
-xaa1e: mov bx,0xba77 ; 0000AA1E BB77BA '.w.'
+xaa1e: mov bx,xba77 ; 0000AA1E BB77BA '.w.'
mov es,[cs:bx+0x6] ; 0000AA21 2E8E4706 '..G.'
call x9e1c ; 0000AA25 E8F4F3 '...'
jz xaa2f ; 0000AA28 7405 't.'
@@ -4744,7 +4747,7 @@ xaac9: and byte [0x10],0xcf ; 0000AAC9 80261000CF '.&...'
call xc791 ; 0000AB1B E8731C '.s.'
xab1e: ret ; 0000AB1E C3 '.'
-xab1f: mov dx,0xba77 ; 0000AB1F BA77BA '.w.'
+xab1f: mov dx,xba77 ; 0000AB1F BA77BA '.w.'
mov bx,dx ; 0000AB22 8BDA '..'
add bx,byte +0xf ; 0000AB24 83C30F '...'
or al,al ; 0000AB27 0AC0 0x0A,'.'
@@ -4807,7 +4810,7 @@ xab96: mov al,0x58 ; 0000AB96 B058 '.X'
out 0x84,al ; 0000AB98 E684 '..'
push cs ; 0000AB9A 0E '.'
pop ds ; 0000AB9B 1F '.'
- mov bx,0xba77 ; 0000AB9C BB77BA '.w.'
+ mov bx,xba77 ; 0000AB9C BB77BA '.w.'
xab9f: mov al,0x59 ; 0000AB9F B059 '.Y'
out 0x84,al ; 0000ABA1 E684 '..'
mov es,[bx+0x6] ; 0000ABA3 8E4706 '.G.'
@@ -6103,23 +6106,30 @@ xb68a: stc ; 0000B68A F9 '.'
db ' 605-Diskette Drive Type Error-(Run Setup)',0x0D,0x0A
db ' Insert DIAGNOSTIC diskette in Drive A:',0x0D,0x0A
- db 0xD8 ; 0000BA77 D8
- add dx,sp ; 0000BA78 03D4 '..'
- sub [si+0xf0],si ; 0000BA7A 29B4F000 ')...'
- mov ax,0x6000 ; 0000BA7E B80060 '..`'
- mov dh,[bx+0x1e] ; 0000BA81 8AB71E00 '....'
- inc ax ; 0000BA85 40 '@'
- mov ax,0xb403 ; 0000BA86 B803B4 '...'
- sub sp,dx ; 0000BA89 29D4 ').'
- lock add [bx+si+0x6000],dh ; 0000BA8B F000B00060 '....`'
- imul si,[bx+0x21],word 0xbd10; 0000BA90 69B7210010BD 'i.!...'
- wait ; 0000BA96 9B '.'
- mov dx,0xe5e9 ; 0000BA97 BAE9E5 '...'
- fdiv dword [bx+si+0xe68e] ; 0000BA9A D8B08EE6 '....'
- jo xbad3 ; 0000BA9E 7033 'p3'
- shl dh,0x71 ; 0000BAA0 C0E671 '..q'
- mov al,0x40 ; 0000BAA3 B040 '.@'
- out 0x86,al ; 0000BAA5 E686 '..'
+ ;
+ ; Video card data
+ ;
+xba77: dw 0x03D8 ; 0000BA77 D803 ; +0x00: I/O address of Mode Select Register (CGA)
+ db 0xD4,0x29,0xB4,0xF0 ; 0000BA79 D429B4F0
+ dw 0xB800 ; 0000BA7D 00B8 ; +0x06: real-mode segment of frame buffer
+ db 0x00,0x60,0x8A,0xB7 ; 0000BA7F 00608AB7
+ db 0x1E,0x00,0x40 ; 0000BA83 1E0040
+
+xba86: dw 0x03B8 ; 0000BA86 B803 ; +0x00: I/O address of Mode Select Register (Mono)
+ db 0xB4,0x29,0xD4,0xF0 ; 0000BA88 B429D4F0
+ dw 0xB000 ; 0000BA8C 00B0 ; +0x06: real-mode segment of frame buffer
+ db 0x00,0x60,0x69,0xB7 ; 0000BA8E 006069B7
+ db 0x21,0x00,0x10 ; 0000BA92 210010
+
+ mov bp,0xba9b ; 0000BA95 BD9BBA
+ jmp x9380 ; 0000BA98 E9E5D8
+
+ mov al,0x8e ; 0000BA9B B08E
+ out 0x70,al ; 0000BA9D E670
+ xor ax,ax ; 0000BA9F 33C0
+ out 0x71,al ; 0000BAA1 E671
+ mov al,0x40 ; 0000BAA3 B040
+ out 0x86,al ; 0000BAA5 E686
xbaa7: cli ; 0000BAA7 FA '.'
mov al,0xf ; 0000BAA8 B00F '..'
@@ -9921,11 +9931,15 @@ xd9db: mov ax,0x40 ; 0000D9DB B84000 '.@.'
or bx,bx ; 0000D9ED 0BDB '..'
jnz xd9f4 ; 0000D9EF 7503 'u.'
jmp xda8c ; 0000D9F1 E99800 '...'
-
+;
+; At checkpoint 0x6B, the conventional+extended memory test has been completed, and you should
+; see a total at the top of the screen (eg, "01792 KB OK").
+;
xd9f4: mov al,0x6b ; 0000D9F4 B06B '.k'
out 0x84,al ; 0000D9F6 E684 '..'
mov ax,0x1c00 ; 0000D9F8 B8001C '...'
mov ds,ax ; 0000D9FB 8ED8 '..'
+
test word [0x64],0x1 ; 0000D9FD F70664000100 '..d...'
jz xda1b ; 0000DA03 7416 't.'
call xc786 ; 0000DA05 E87EED '.~.'
@@ -9935,6 +9949,7 @@ xd9f4: mov al,0x6b ; 0000D9F4 B06B '.k'
mov cl,[0x69] ; 0000DA10 8A0E6900 '..i.'
mov dx,[0x67] ; 0000DA14 8B166700 '..g.'
call x822d ; 0000DA18 E812A8 '...'
+
xda1b: test word [0x64],0x4 ; 0000DA1B F70664000400 '..d...'
jz xda39 ; 0000DA21 7416 't.'
call xc786 ; 0000DA23 E860ED '.`.'
@@ -9944,6 +9959,7 @@ xda1b: test word [0x64],0x4 ; 0000DA1B F70664000400 '..d...'
mov cl,[0x6d] ; 0000DA2E 8A0E6D00 '..m.'
mov dx,[0x6b] ; 0000DA32 8B166B00 '..k.'
call x8242 ; 0000DA36 E809A8 '...'
+
xda39: test word [0x64],0x2 ; 0000DA39 F70664000200 '..d...'
jz xda57 ; 0000DA3F 7416 't.'
call xc786 ; 0000DA41 E842ED '.B.'
@@ -9952,7 +9968,13 @@ xda39: test word [0x64],0x2 ; 0000DA39 F70664000200 '..d...'
mov si,cx ; 0000DA4A 8BF1 '..'
mov cl,[0x71] ; 0000DA4C 8A0E7100 '..q.'
mov dx,[0x6f] ; 0000DA50 8B166F00 '..o.'
+;
+; During the next call, the following additional text may be displayed on the screen:
+;
+; F00000 02 201-Memory Error
+;
call x822d ; 0000DA54 E8D6A7 '...'
+
xda57: test word [0x64],0x8 ; 0000DA57 F70664000800 '..d...'
jz xda75 ; 0000DA5D 7416 't.'
call xc786 ; 0000DA5F E824ED '.$.'
@@ -9961,7 +9983,13 @@ xda57: test word [0x64],0x8 ; 0000DA57 F70664000800 '..d...'
mov si,cx ; 0000DA68 8BF1 '..'
mov cl,[0x75] ; 0000DA6A 8A0E7500 '..u.'
mov dx,[0x73] ; 0000DA6E 8B167300 '..s.'
+;
+; During the next call, the following additional text may be displayed on the screen:
+;
+; F00000 FF 203-Memory Address Error
+;
call x8242 ; 0000DA72 E8CDA7 '...'
+
xda75: test word [0x64],0x10 ; 0000DA75 F70664001000 '..d...'
jz xda8c ; 0000DA7B 740F 't.'
call xc786 ; 0000DA7D E806ED '...'
@@ -9969,6 +9997,7 @@ xda75: test word [0x64],0x10 ; 0000DA75 F70664001000 '..d...'
mov bx,0xb68c ; 0000DA83 BB8CB6 '...'
mov cx,0x1a ; 0000DA86 B91A00 '...'
call xc745 ; 0000DA89 E8B9EC '...'
+
xda8c: test word [0x64],0xffff ; 0000DA8C F7066400FFFF '..d...'
jz xdaac ; 0000DA92 7418 't.'
call xc786 ; 0000DA94 E8EFEC '...'
@@ -14293,6 +14322,7 @@ xffb3: pop ds ; 0000FFB3 1F '.'
jmp 0xf000:reset ; 0000FFF0 EA05F900F0
- db ' 01/28/88'
+ db 0x20
+ db '01/28/88'
db 0xFC ; 0000FFFE FC
db 0x98 ; 0000FFFF 98
diff --git a/devices/pc/bios/compaq/deskpro386/notes.md b/devices/pc/bios/compaq/deskpro386/notes.md
index 492d1ca29..bd0373ccb 100644
--- a/devices/pc/bios/compaq/deskpro386/notes.md
+++ b/devices/pc/bios/compaq/deskpro386/notes.md
@@ -182,3 +182,229 @@ But when we stopped here next, it was no longer good:
%00FF0740 0000 0000 0000 0000 - 0000 0000 0000 0000 ................
Turns out this is because the A20 line has been disabled.
+
+-------------------------------------------------------------------------------------------------
+
+Let's look at a complete run:
+
+ EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000304
+ ESP=00000000 EBP=00000000 ESI=00000000 EDI=00000000
+ SS=0000 DS=0000 ES=0000 FS=0000 GS=0000 PS=00000002 V0 D0 I0 T0 S0 Z0 A0 P0 C0
+ F000:FFF0 EA05F900F0 JMP F000:F905
+
+I want to catch writes to the top-left corner of the screen, so I set a write breakpoint:
+
+ bw b800:0
+
+which reports:
+
+ write breakpoint added to memory block 000B8000
+ breakpoint enabled: B800:0000 (write)
+
+and then we're off:
+
+ running
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x00) @F000:F907
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x01) @F000:F926
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x02) @F000:F93C
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x03) @F000:F942
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x04) @F000:F946
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x05) @F000:F95F
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x06) @F000:F978
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x08) @F000:F9AA
+ notice: PIC0(0x20): unsupported OCW2 automatic EOI command: 0x00
+ stopped (149 ops, 622 cycles, 92 ms, 6761 hz)
+ EAX=0000F000 EBX=00000000 ECX=00000008 EDX=00000020
+ ESP=00000000 EBP=00000000 ESI=0000F8E7 EDI=00000000
+ SS=0000 DS=F000 ES=0000 FS=0000 GS=0304 PS=00000046 V0 D0 I0 T0 S0 Z1 A0 P1 C0
+ F000:F9ED E6A0 OUT A0,AL
+ running
+ notice: PIC1(0xA0): unsupported OCW2 automatic EOI command: 0x00
+ stopped (150 ops, 5 cycles, 19 ms, 263 hz)
+ EAX=0000F000 EBX=00000000 ECX=00000008 EDX=00000020
+ ESP=00000000 EBP=00000000 ESI=0000F8E7 EDI=00000000
+ SS=0000 DS=F000 ES=0000 FS=0000 GS=0304 PS=00000046 V0 D0 I0 T0 S0 Z1 A0 P1 C0
+ F000:F9EF B009 MOV AL,09
+ running
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x09) @F000:F9F1
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x0F) @F000:BAAA
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x10) @F000:BAFB
+ bus.outPort(0x004B,unknown,0x12) @F000:BAFF
+ bus.outPort(0x004B,unknown,0x42) @F000:BB03
+ bus.outPort(0x004B,unknown,0x92) @F000:BB07
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x11) @F000:BB29
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x12) @F000:BB70
+ breakpoint hit: B800:0000 (write)
+ stopped (413 ops, 959 cycles, 80 ms, 11988 hz)
+ EAX=00000720 EBX=0000BA77 ECX=00001FFF EDX=000003D8
+ ESP=00000000 EBP=0000BB78 ESI=0000F0C6 EDI=00000002
+ SS=0000 DS=F000 ES=B800 FS=0000 GS=0304 PS=00000046 V0 D0 I0 T0 S0 Z1 A0 P1 C0
+ F000:9C05 F3 REPZ
+ F000:9C06 AB STOSW
+
+This is where screen memory is first initialized ("blanked").
+
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x13) @F000:BB90
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x14) @F000:BBB8
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x15) @F000:BBD8
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x17) @F000:BC08
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x18) @F000:BC14
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x40) @F000:B552
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x2F) @0018:87B4
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x41) @F000:B572
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x42) @F000:B599
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x43) @F000:B5C4
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x44) @F000:B5D2
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x45) @F000:B600
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x43) @F000:B5C4
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x44) @F000:B5D2
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x45) @F000:B600
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x46) @F000:B61C
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x19) @F000:BC2C
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x30) @F000:A8B0
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x31) @F000:A905
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x32) @F000:A91D
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x33) @F000:A93B
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x34) @F000:A953
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x36) @F000:A991
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x38) @F000:A99C
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x39) @F000:A9BC
+ bus.inPort(0x03BC,unknown) @F000:A9CA
+ bus.outPort(0x03BC,unknown,0x00) @F000:A9CD
+ bus.inPort(0x03BC,unknown) @F000:A9D0
+ bus.inPort(0x0378,unknown) @F000:A9CA
+ bus.outPort(0x0378,unknown,0x00) @F000:A9CD
+ bus.inPort(0x0378,unknown) @F000:A9D0
+ bus.inPort(0x0278,unknown) @F000:A9CA
+ bus.outPort(0x0278,unknown,0x00) @F000:A9CD
+ bus.inPort(0x0278,unknown) @F000:A9D0
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x3A) @F000:A9DE
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x3B) @F000:A9FB
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x52) @F000:AA41
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x53) @F000:AA54
+ bus.outPort(0x03B9,unknown,0x30) @F000:9BE7
+ write breakpoint added to memory block 000B8000
+ write breakpoint added to memory block 000B8000
+ breakpoint hit: B800:0000 (write)
+ stopped (1340834 ops, 3291994 cycles, 821 ms, 4009737 hz)
+ EAX=00000720 EBX=00000720 ECX=00003FFF EDX=0000B800
+ ESP=000000D0 EBP=FFFF2230 ESI=00000CBA EDI=00000002
+ SS=0030 DS=0000 ES=B800 FS=0000 GS=0304 PS=00000246 V0 D0 I1 T0 S0 Z1 A0 P1 C0
+ C000:0E93 F3 REPZ
+ C000:0E94 AB STOSW
+
+Now the video card's own BIOS is doing the same thing, followed by more of the same:
+
+ write breakpoint added to memory block 000B8000
+ write breakpoint added to memory block 000B8000
+ breakpoint hit: B800:0000 (write)
+ stopped (1384492 ops, 79242 cycles, 52 ms, 1523885 hz)
+ EAX=00000720 EBX=00000720 ECX=00003FFF EDX=0000B800
+ ESP=000000C8 EBP=FFFF2230 ESI=00000C3A EDI=00000002
+ SS=0030 DS=0000 ES=B800 FS=0000 GS=0304 PS=00000246 V0 D0 I1 T0 S0 Z1 A0 P1 C0
+ C000:0E93 F3 REPZ
+ C000:0E94 AB STOSW
+ running
+ breakpoint hit: B800:0000 (write)
+ stopped (1476959 ops, 347538 cycles, 67 ms, 5187134 hz)
+ EAX=00000FDB EBX=00000FDB ECX=00000050 EDX=000003DA
+ ESP=000000CC EBP=FFFF00E2 ESI=00000000 EDI=00000002
+ SS=0030 DS=0000 ES=B800 FS=0000 GS=0304 PS=00000246 V0 D0 I1 T0 S0 Z1 A0 P1 C0
+ C000:18D7 FB STI
+ running
+ write breakpoint added to memory block 000B8000
+ write breakpoint added to memory block 000B8000
+ breakpoint hit: B800:0000 (write)
+ stopped (2824784 ops, 4644466 cycles, 528 ms, 8796337 hz)
+ EAX=00000720 EBX=00000720 ECX=00003FFF EDX=0000B800
+ ESP=000000C8 EBP=FFFF2230 ESI=00000CBA EDI=00000002
+ SS=0030 DS=0000 ES=B800 FS=0000 GS=0304 PS=00000246 V0 D0 I1 T0 S0 Z1 A0 P1 C0
+ C000:0E93 F3 REPZ
+ C000:0E94 AB STOSW
+ running
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x8C) @F000:D05C
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x1A) @F000:BC79
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x50) @F000:AA76
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x51) @F000:AA7F
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x52) @F000:AA9C
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x1B) @F000:BC80
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x1C) @F000:BC87
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x90) @F000:CC53
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x91) @F000:CC85
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x1D) @F000:BC8E
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x93) @F000:CC8A
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x94) @F000:CD06
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x95) @F000:CD3C
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x96) @F000:CD6A
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x2D) @F000:BC95
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x0D) @F000:E107
+ bus.outPort(0x004B,unknown,0x12) @F000:E10B
+ bus.outPort(0x0048,unknown,0x22) @F000:E112
+ bus.outPort(0x004B,unknown,0x00) @F000:E139
+ bus.inPort(0x0048,unknown) @F000:E13B
+ bus.inPort(0x0048,unknown) @F000:E13E
+ bus.outPort(0x004B,unknown,0x12) @F000:E11A
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x0E) @F000:E11E
+ bus.outPort(0x004B,unknown,0x92) @F000:E122
+ bus.outPort(0x004A,unknown,0x22) @F000:E129
+ bus.outPort(0x004B,unknown,0x80) @F000:E139
+ bus.inPort(0x004A,unknown) @F000:E13B
+ bus.inPort(0x004A,unknown) @F000:E13E
+ bus.outPort(0x004B,unknown,0x92) @F000:E131
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x1E) @F000:BC9C
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x80) @F000:CFDF
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x81) @F000:CFF7
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x82) @F000:D011
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x84) @F000:D02D
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x1F) @F000:BCA3
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x75) @F000:F74D
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x76) @F000:F761
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x77) @0030:F772
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x78) @0030:F790
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x00) @F000:F907
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x07) @F000:F986
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x08) @F000:F9AA
+ notice: PIC0(0x20): unsupported OCW2 automatic EOI command: 0x00
+ stopped (19729382 ops, 81457037 cycles, 7165 ms, 11368742 hz)
+ EAX=0000F000 EBX=00000006 ECX=00000008 EDX=00000020
+ ESP=00000000 EBP=00000000 ESI=0000F8E7 EDI=00000000
+ SS=0000 DS=F000 ES=0000 FS=0000 GS=0000 PS=00000046 V0 D0 I0 T0 S0 Z1 A0 P1 C0
+ F000:F9ED E6A0 OUT A0,AL
+ running
+ notice: PIC1(0xA0): unsupported OCW2 automatic EOI command: 0x00
+ stopped (19729383 ops, 5 cycles, 20 ms, 250 hz)
+ EAX=0000F000 EBX=00000006 ECX=00000008 EDX=00000020
+ ESP=00000000 EBP=00000000 ESI=0000F8E7 EDI=00000000
+ SS=0000 DS=F000 ES=0000 FS=0000 GS=0000 PS=00000046 V0 D0 I0 T0 S0 Z1 A0 P1 C0
+ F000:F9EF B009 MOV AL,09
+
+We're back in the Compaq BIOS, the video card appears to be fully initialized now, so perhaps the next
+write to video memory will be the first memory test results.
+
+And in fact, it is. But the "bw b800:0" command doesn't work, because the memory test results are being
+performed in protected-mode, and there is no segment 0xB800 mapped to video memory at that point.
+
+So the write breakpoint must be specified as "bw %b8000" instead. Now we catch it:
+
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x09) @F000:F9F1
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x79) @F000:F7CD
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x7B) @F000:F814
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x20) @F000:BCAA
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x60) @F000:D6E6
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x61) @F000:D704
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x18) @0030:870A
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x18) @0030:8715
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x62) @0030:D719
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x63) @0030:D761
+ chipset.outPort(0x0084,DMA.SPARE0.PAGE,0x70) @0030:DB38
+ breakpoint hit: %000B8000 (write)
+ stopped (19736120 ops, 23810 cycles, 165 ms, 144303 hz)
+ EAX=00000000 EBX=0000000A ECX=0000000A EDX=00000730
+ ESP=000000D0 EBP=00000080 ESI=00000095 EDI=00008002
+ SS=0028[00000300,FFFF] DS=0018[0001C000,FFFF] ES=0040[000B0000,FFFF]
+ CS=0030[000F0000,FFFF] FS=0000[00000000,FFFF] GS=0304[00003040,FFFF]
+ LD=0000[00000000,0000] GD=[0001C000,005F] ID=[000FF821,0007] TR=0000 A20=ON
+ CR0=0000FFF1 CR2=00000000 CR3=00000000 PS=00000082 V0 D0 I0 T0 S1 Z0 A0 P0 C0
+ 0030:80DA F3 REPZ
+ 0030:80DB A5 MOVSW
+
diff --git a/devices/pc/machine/compaq/deskpro386/ega/2048kb/machine.xml b/devices/pc/machine/compaq/deskpro386/ega/2048kb/machine.xml
index 2a9060bb7..99be534f1 100644
--- a/devices/pc/machine/compaq/deskpro386/ega/2048kb/machine.xml
+++ b/devices/pc/machine/compaq/deskpro386/ega/2048kb/machine.xml
@@ -10,7 +10,7 @@
-
+
diff --git a/modules/pcjs/lib/chipset.js b/modules/pcjs/lib/chipset.js
index 84be23307..cfdc7ab6a 100644
--- a/modules/pcjs/lib/chipset.js
+++ b/modules/pcjs/lib/chipset.js
@@ -326,7 +326,7 @@ ChipSet.aMonitorSwitches = {
* For FDC DMA notes, refer to http://wiki.osdev.org/ISA_DMA
* For general DMA notes, refer to http://www.freebsd.org/doc/en/books/developers-handbook/dma.html
*
- * TODO: Determine why the MODEL_5150 ROM BIOS sets the page register for channel 1 (port 0x83) to zero
+ * TODO: Determine why the MODEL_5150 ROM BIOS sets the DMA channel 1 page register (port 0x83) to zero
*/
ChipSet.DMA0 = {
INDEX: 0,
@@ -359,7 +359,7 @@ ChipSet.DMA1 = {
CH6_PAGE: 0x89, // OUT: DMA channel 6 page register (MODEL_5170)
CH7_PAGE: 0x8A, // OUT: DMA channel 7 page register (MODEL_5170)
CH5_PAGE: 0x8B, // OUT: DMA channel 5 page register (MODEL_5170)
- CH4_PAGE: 0x8F, // OUT: DMA channel 4 page register (MODEL_5170; unusable; aka "refresh" page register?)
+ CH4_PAGE: 0x8F, // OUT: DMA channel 4 page register (MODEL_5170; unusable; aka "Refresh" page register?)
CH4_ADDR: 0xC0, // OUT: starting address IN: current address
CH4_COUNT: 0xC2, // OUT: starting word count IN: remaining word count
CH5_ADDR: 0xC4, // OUT: starting address IN: current address
@@ -890,22 +890,54 @@ ChipSet.CMOS = {
};
/*
- * Manufacturing Test Ports (MODEL_5170)
+ * DMA Page Registers
*
- * The MODEL_5170 TechRef lists 0x80-0x9F as the range for DMA page registers, but that seems a bit
- * overbroad; at one point, it says:
+ * The MODEL_5170 TechRef lists 0x80-0x9F as the range for DMA page registers, but that may be a bit
+ * overbroad. There are a total of 8 (7 usable) DMA channels on the MODEL_5170, each of which has the
+ * following assigned DMA page registers:
+ *
+ * Channel # Page Reg
+ * --------- --------
+ * 0 0x87
+ * 1 0x83
+ * 2 0x81
+ * 3 0x82
+ * 4 0x8F (not usable; the 5170 TechRef refers to this as the "Refresh" page register)
+ * 5 0x8B
+ * 6 0x89
+ * 7 0x8A
+ *
+ * That leaves 0x80, 0x84, 0x85, 0x86, 0x88, 0x8C, 0x8D and 0x8E unaccounted for in the range 0x80-0x8F.
+ * (I'm saving the question of what, if anything, is available in the range 0x90-0x9F for another day.)
+ *
+ * As for port 0x80, the TechRef says:
*
* "I/O address hex 080 is used as a diagnostic-checkpoint port or register.
- * This port corresponds to a read/write register in the DMA page register (74LS6I2)."
+ * This port corresponds to a read/write register in the DMA page register (74LS612)."
*
- * 0x80 is the neighborhood, but that particular port is not documented as a DMA page register.
- * We'll refer to it as a "manufacturing port" (see bMFGData). Be aware that the MODEL_5170 BIOS is
- * littered with manufacturing test ("MFG_TST") code which, if enabled, writes to other DMA page
- * registers, presumably treating them as scratch registers.
+ * so I used to have dedicated handlers and storage (bMFGData) for the register at port 0x80, but I've since
+ * appended it to abDMAPageSpare, an 8-element array that captures all I/O to the 8 unassigned (aka "spare")
+ * DMA page registers. The 5170 BIOS uses 0x80 as a "checkpoint" register, and the DESKPRO386 uses 0x84 in a
+ * similar fashion. The 5170 also contains "MFG_TST" code that uses other unassigned DMA page registers as
+ * scratch registers, which come in handy when RAM hasn't been tested/initialized yet.
+ *
+ * Here's our mapping of entries in the abDMAPageSpare array to the unassigned ("spare") DMA page registers:
+ *
+ * Index # Page Reg
+ * -------- --------
+ * 0 0x84
+ * 1 0x85
+ * 2 0x86
+ * 3 0x88
+ * 4 0x8C
+ * 5 0x8D
+ * 6 0x8E
+ * 7 0x80
+ *
+ * The only reason port 0x80 is out of sequence (ie, at the end of the array, at index 7 instead of index 0) is
+ * because it was added the array later, and the entire array gets written to our save/restore data structures, so
+ * reordering the elements would be a bad idea.
*/
-ChipSet.MFG = { // this.bMFGData
- PORT: 0x80
-};
/*
* NMI Mask Register (MODEL_5150 and MODEL_5160 only)
@@ -1125,8 +1157,7 @@ ChipSet.prototype.reset = function(fHard)
this.b8042OutPort = ChipSet.KBC.OUTPORT.NO_RESET | ChipSet.KBC.OUTPORT.A20_ON;
- this.bMFGData = 0;
- this.abDMAPageSpare = new Array(7);
+ this.abDMAPageSpare = new Array(8);
this.bCMOSAddr = 0; // NMI is enabled, since the ChipSet.CMOS.ADDR.NMI_DISABLE bit is not set in bCMOSAddr
@@ -1679,7 +1710,7 @@ ChipSet.prototype.save = function()
if (this.model >= ChipSet.MODEL_5170) {
state.set(5, [this.b8042Status, this.b8042InBuff, this.b8042CmdData,
this.b8042OutBuff, this.b8042InPort, this.b8042OutPort]);
- state.set(6, [this.bMFGData, this.abDMAPageSpare, this.bCMOSAddr, this.abCMOSData, this.nRTCCyclesLastUpdate, this.nRTCCyclesNextUpdate]);
+ state.set(6, [this.abDMAPageSpare[7], this.abDMAPageSpare, this.bCMOSAddr, this.abCMOSData, this.nRTCCyclesLastUpdate, this.nRTCCyclesNextUpdate]);
}
return state.data();
};
@@ -1739,8 +1770,8 @@ ChipSet.prototype.restore = function(data)
a = data[6];
if (a) {
this.assert(this.model >= ChipSet.MODEL_5170);
- this.bMFGData = a[0];
this.abDMAPageSpare = a[1];
+ this.abDMAPageSpare[7] = a[0]; // formerly bMFGData
this.bCMOSAddr = a[2];
this.abCMOSData = a[3];
this.nRTCCyclesLastUpdate = a[4];
@@ -2675,7 +2706,11 @@ ChipSet.prototype.inDMAPageSpare = function(iSpare, port, addrFrom)
*/
ChipSet.prototype.outDMAPageSpare = function(iSpare, port, bOut, addrFrom)
{
- if (this.messageEnabled(Messages.DMA | Messages.PORT)) {
+ /*
+ * TODO: Remove the DEBUG-only DESKPRO386 code once we're done debugging DeskPro 386 ROMs;
+ * it enables logging of all DeskPro ROM checkpoint I/O to port 0x84.
+ */
+ if (this.messageEnabled(Messages.DMA | Messages.PORT) || DEBUG && this.model == ChipSet.MODEL_DESKPRO386 && port == 0x84) {
this.printMessageIO(port, bOut, addrFrom, "DMA.SPARE" + iSpare + ".PAGE", null, true);
}
this.abDMAPageSpare[iSpare] = bOut;
@@ -4680,34 +4715,6 @@ ChipSet.prototype.outCMOSData = function(port, bOut, addrFrom)
}
};
-/**
- * inMFGData(port, addrFrom)
- *
- * @this {ChipSet}
- * @param {number} port (0x80)
- * @param {number} [addrFrom] (not defined if the Debugger is trying to read the specified port)
- * @return {number} simulated port value
- */
-ChipSet.prototype.inMFGData = function(port, addrFrom)
-{
- this.printMessageIO(port, null, addrFrom, "MFG_DATA", this.bMFGData);
- return this.bMFGData;
-};
-
-/**
- * outMFGData(port, bOut, addrFrom)
- *
- * @this {ChipSet}
- * @param {number} port (0x80)
- * @param {number} bOut
- * @param {number} [addrFrom] (not defined if the Debugger is trying to write the specified port)
- */
-ChipSet.prototype.outMFGData = function(port, bOut, addrFrom)
-{
- this.printMessageIO(port, bOut, addrFrom, "MFG_DATA");
- this.bMFGData = bOut;
-};
-
/**
* outNMI(port, bOut, addrFrom)
*
@@ -4985,7 +4992,7 @@ ChipSet.aPortInput5170 = {
0x64: ChipSet.prototype.in8042Status,
0x70: ChipSet.prototype.inCMOSAddr,
0x71: ChipSet.prototype.inCMOSData,
- 0x80: ChipSet.prototype.inMFGData,
+ 0x80: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(7, port, addrFrom); },
0x84: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(0, port, addrFrom); },
0x85: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(1, port, addrFrom); },
0x86: /** @this {ChipSet} */ function(port, addrFrom) { return this.inDMAPageSpare(2, port, addrFrom); },
@@ -5054,7 +5061,7 @@ ChipSet.aPortOutput5170 = {
0x64: ChipSet.prototype.out8042InBuffCmd,
0x70: ChipSet.prototype.outCMOSAddr,
0x71: ChipSet.prototype.outCMOSData,
- 0x80: ChipSet.prototype.outMFGData,
+ 0x80: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(7, port, bOut, addrFrom); },
0x84: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(0, port, bOut, addrFrom); },
0x85: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(1, port, bOut, addrFrom); },
0x86: /** @this {ChipSet} */ function(port, bOut, addrFrom) { this.outDMAPageSpare(2, port, bOut, addrFrom); },
diff --git a/modules/pcjs/lib/computer.js b/modules/pcjs/lib/computer.js
index fbccbe769..50b2a72ed 100644
--- a/modules/pcjs/lib/computer.js
+++ b/modules/pcjs/lib/computer.js
@@ -876,6 +876,10 @@ Computer.prototype.powerOff = function(fSave, fShutdown)
Computer.prototype.reset = function()
{
if (this.bus && this.bus.reset) {
+ /*
+ * TODO: Why does WebStorm think that this.bus.type is undefined? The base class (Component)
+ * constructor defines it.
+ */
this.printMessage("Resetting " + this.bus.type);
this.bus.reset();
}
diff --git a/modules/pcjs/lib/debugger.js b/modules/pcjs/lib/debugger.js
index 1ee00ab19..3698aff97 100644
--- a/modules/pcjs/lib/debugger.js
+++ b/modules/pcjs/lib/debugger.js
@@ -2549,7 +2549,7 @@ if (DEBUGGER) {
* @this {Debugger}
* @param {Array} aAddr
* @param {boolean} [fWrite]
- * @param {number} [cb] is number of extra bytes to check (0, 1 or 3)
+ * @param {number} [cb] is number of bytes to check (1, 2 or 4); default is 1
* @return {number} is the corresponding physical address, or X86.ADDR_INVALID
*/
Debugger.prototype.getAddr = function(aAddr, fWrite, cb)
@@ -2564,9 +2564,9 @@ if (DEBUGGER) {
if (addr == null) {
var seg = this.getSegment(aAddr[1]);
if (!fWrite) {
- addr = seg.checkRead(aAddr[0], cb || 0, true);
+ addr = seg.checkRead(aAddr[0], cb || 1, true);
} else {
- addr = seg.checkWrite(aAddr[0], cb || 0, true);
+ addr = seg.checkWrite(aAddr[0], cb || 1, true);
}
aAddr[2] = addr;
}
@@ -2587,7 +2587,7 @@ if (DEBUGGER) {
Debugger.prototype.getByte = function(aAddr, inc)
{
var b = 0xff;
- var addr = this.getAddr(aAddr, false, 0);
+ var addr = this.getAddr(aAddr, false, 1);
if (addr !== X86.ADDR_INVALID) {
b = this.bus.getByteDirect(addr);
this.assert((b == (b & 0xff)), "invalid byte (" + b + ") at address: " + this.hexAddr(aAddr));
@@ -2623,7 +2623,7 @@ if (DEBUGGER) {
Debugger.prototype.getShort = function(aAddr, inc)
{
var w = 0xffff;
- var addr = this.getAddr(aAddr, false, 1);
+ var addr = this.getAddr(aAddr, false, 2);
if (addr !== X86.ADDR_INVALID) {
w = this.bus.getShortDirect(addr);
this.assert((w == (w & 0xffff)), "invalid word (" + w + ") at address: " + this.hexAddr(aAddr));
@@ -2643,7 +2643,7 @@ if (DEBUGGER) {
Debugger.prototype.getLong = function(aAddr, inc)
{
var l = -1;
- var addr = this.getAddr(aAddr, false, 3);
+ var addr = this.getAddr(aAddr, false, 4);
if (addr !== X86.ADDR_INVALID) {
l = this.bus.getLongDirect(addr);
if (inc !== undefined) this.incAddr(aAddr, inc);
@@ -2665,7 +2665,7 @@ if (DEBUGGER) {
*/
Debugger.prototype.setByte = function(aAddr, b, inc)
{
- var addr = this.getAddr(aAddr, true, 0);
+ var addr = this.getAddr(aAddr, true, 1);
if (addr !== X86.ADDR_INVALID) {
this.bus.setByteDirect(addr, b);
if (inc !== undefined) this.incAddr(aAddr, inc);
@@ -2683,7 +2683,7 @@ if (DEBUGGER) {
*/
Debugger.prototype.setShort = function(aAddr, w, inc)
{
- var addr = this.getAddr(aAddr, true, 1);
+ var addr = this.getAddr(aAddr, true, 2);
if (addr !== X86.ADDR_INVALID) {
this.bus.setShortDirect(addr, w);
if (inc !== undefined) this.incAddr(aAddr, inc);
diff --git a/modules/pcjs/lib/ram.js b/modules/pcjs/lib/ram.js
index c01fe14ef..74adcc153 100644
--- a/modules/pcjs/lib/ram.js
+++ b/modules/pcjs/lib/ram.js
@@ -166,7 +166,7 @@ RAM.prototype.reset = function()
if (this.bus.addMemory(this.addrRAM, this.sizeRAM, Memory.TYPE.RAM)) {
this.fAllocated = true;
- this.status(Math.floor(this.sizeRAM / 1024) + "Kb");
+ this.status(Math.floor(this.sizeRAM / 1024) + "Kb allocated");
/*
* NOTE: I'm specifying MAXDEBUG for status() messages because I'm not yet sure I want these
@@ -175,6 +175,7 @@ RAM.prototype.reset = function()
* for these components, which the Computer component will display as it "powers up" components.
*/
if (MAXDEBUG && this.fInstalled) this.status("specified size overrides SW1");
+
/*
* Memory with an ID of "ramCPQ" is reserved for built-in memory located just below the 16Mb
* boundary on Compaq DeskPro 386 machines.
diff --git a/modules/pcjs/lib/serialport.js b/modules/pcjs/lib/serialport.js
index d3eeb682b..118224962 100644
--- a/modules/pcjs/lib/serialport.js
+++ b/modules/pcjs/lib/serialport.js
@@ -67,17 +67,17 @@ function SerialPort(parmsSerial) {
this.iAdapter = parmsSerial['adapter'];
switch (this.iAdapter) {
- case 1:
- this.portBase = 0x3F8;
- this.nIRQ = ChipSet.IRQ.COM1;
- break;
- case 2:
- this.portBase = 0x2F8;
- this.nIRQ = ChipSet.IRQ.COM2;
- break;
- default:
- Component.warning("Unrecognized serial adapter #" + this.iAdapter);
- return;
+ case 1:
+ this.portBase = 0x3F8;
+ this.nIRQ = ChipSet.IRQ.COM1;
+ break;
+ case 2:
+ this.portBase = 0x2F8;
+ this.nIRQ = ChipSet.IRQ.COM2;
+ break;
+ default:
+ Component.warning("Unrecognized serial adapter #" + this.iAdapter);
+ return;
}
/**
@@ -322,6 +322,7 @@ SerialPort.prototype.syncMouse = function()
SerialPort.prototype.setBinding = function(sHTMLType, sBinding, control)
{
var serial = this;
+
switch (sBinding) {
case SerialPort.sIOBuffer:
this.bindings[sBinding] = this.controlIOBuffer = control;
diff --git a/modules/pcjs/lib/video.js b/modules/pcjs/lib/video.js
index 020a0a067..cea9e2968 100644
--- a/modules/pcjs/lib/video.js
+++ b/modules/pcjs/lib/video.js
@@ -1249,7 +1249,7 @@ Card.ACCESS.WRITE.MASK = 0xff00;
*/
Card.ACCESS.readShort = function readShort(off)
{
- return this.readByte(off) | (this.readByte(off + 1) << 8);
+ return this.readByteDirect(off) | (this.readByteDirect(off + 1) << 8);
};
/**
@@ -1261,7 +1261,7 @@ Card.ACCESS.readShort = function readShort(off)
*/
Card.ACCESS.readLong = function readLong(off)
{
- return this.readByte(off) | (this.readByte(off + 1) << 8) | (this.readByte(off + 2) << 16) | (this.readByte(off + 3) << 24);
+ return this.readByteDirect(off) | (this.readByteDirect(off + 1) << 8) | (this.readByteDirect(off + 2) << 16) | (this.readByteDirect(off + 3) << 24);
};
/**
@@ -1274,8 +1274,8 @@ Card.ACCESS.readLong = function readLong(off)
Card.ACCESS.writeShort = function writeShort(off, w)
{
Component.assert(!(w & ~0xffff));
- this.writeByte(off, w & 0xff);
- this.writeByte(off + 1, w >> 8);
+ this.writeByteDirect(off, w & 0xff);
+ this.writeByteDirect(off + 1, w >> 8);
};
/**
@@ -1287,10 +1287,10 @@ Card.ACCESS.writeShort = function writeShort(off, w)
*/
Card.ACCESS.writeLong = function writeLong(off, w)
{
- this.writeByte(off, w & 0xff);
- this.writeByte(off + 1, (w >> 8) & 0xff);
- this.writeByte(off + 2, (w >> 16) & 0xff);
- this.writeByte(off + 3, (w >>> 24));
+ this.writeByteDirect(off, w & 0xff);
+ this.writeByteDirect(off + 1, (w >> 8) & 0xff);
+ this.writeByteDirect(off + 2, (w >> 16) & 0xff);
+ this.writeByteDirect(off + 3, (w >>> 24));
};
/**
diff --git a/modules/pcjs/lib/x86cpu.js b/modules/pcjs/lib/x86cpu.js
index 91425042c..e20b7b04a 100644
--- a/modules/pcjs/lib/x86cpu.js
+++ b/modules/pcjs/lib/x86cpu.js
@@ -1386,8 +1386,8 @@ X86CPU.prototype.setProtMode = function(fProt)
if (fProt === undefined) {
fProt = !!(this.regCR0 & X86.CR0.MSW.PE);
}
- if (!fProt) {
- this.printMessage("returning to real-mode");
+ if (!fProt != !(this.regCR0 & X86.CR0.MSW.PE)) {
+ this.printMessage("CPU switching to " + (fProt? "protected" : "real") + "-mode", this.bitsMessage, true);
}
this.aOpGrp6 = (fProt? X86.aOpGrp6Prot : X86.aOpGrp6Real);
this.segCS.updateMode(fProt);
@@ -2650,7 +2650,7 @@ X86CPU.prototype.setLong = function(addr, l)
X86CPU.prototype.getEAByte = function(seg, off)
{
this.segEA = seg;
- this.regEA = seg.checkRead(this.offEA = off, 0);
+ this.regEA = seg.checkRead(this.offEA = off, 1);
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
var b = this.getByte(this.regEA);
if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiMemLo;
@@ -2692,7 +2692,7 @@ X86CPU.prototype.getEAByteStack = function(off)
X86CPU.prototype.getEAWord = function(seg, off)
{
this.segEA = seg;
- this.regEA = seg.checkRead(this.offEA = off, (I386? this.dataSize-1 : 1));
+ this.regEA = seg.checkRead(this.offEA = off, (I386? this.dataSize : 2));
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
var w = this.getWord(this.regEA);
if (BACKTRACK) {
@@ -2737,7 +2737,7 @@ X86CPU.prototype.getEAWordStack = function(off)
X86CPU.prototype.modEAByte = function(seg, off)
{
this.segEA = seg;
- this.regEAWrite = this.regEA = seg.checkRead(this.offEA = off, 0);
+ this.regEAWrite = this.regEA = seg.checkRead(this.offEA = off, 1);
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
var b = this.getByte(this.regEA);
if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiMemLo;
@@ -2779,7 +2779,7 @@ X86CPU.prototype.modEAByteStack = function(off)
X86CPU.prototype.modEAWord = function(seg, off)
{
this.segEA = seg;
- this.regEAWrite = this.regEA = seg.checkRead(this.offEA = off, (I386? this.dataSize-1 : 1));
+ this.regEAWrite = this.regEA = seg.checkRead(this.offEA = off, (I386? this.dataSize : 2));
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
var w = this.getWord(this.regEA);
if (BACKTRACK) {
@@ -2823,7 +2823,7 @@ X86CPU.prototype.setEAByte = function(b)
{
if (this.opFlags & X86.OPFLAG.NOWRITE) return;
if (BACKTRACK) this.backTrack.btiMemLo = this.backTrack.btiEALo;
- this.setByte(this.segEA.checkWrite(this.offEA, 0), b);
+ this.setByte(this.segEA.checkWrite(this.offEA, 1), b);
};
/**
@@ -2840,9 +2840,9 @@ X86CPU.prototype.setEAWord = function(w)
this.backTrack.btiMemHi = this.backTrack.btiEAHi;
}
if (!I386) {
- this.setShort(this.segEA.checkWrite(this.offEA, 1), w);
+ this.setShort(this.segEA.checkWrite(this.offEA, 2), w);
} else {
- this.setWord(this.segEA.checkWrite(this.offEA, this.dataSize-1), w);
+ this.setWord(this.segEA.checkWrite(this.offEA, this.dataSize), w);
}
};
@@ -2858,7 +2858,7 @@ X86CPU.prototype.setEAWord = function(w)
*/
X86CPU.prototype.getSOByte = function(seg, off)
{
- return this.getByte(seg.checkRead(off, 0));
+ return this.getByte(seg.checkRead(off, 1));
};
/**
@@ -2874,9 +2874,9 @@ X86CPU.prototype.getSOByte = function(seg, off)
X86CPU.prototype.getSOWord = function(seg, off)
{
if (!I386) {
- return this.getShort(seg.checkRead(off, 1));
+ return this.getShort(seg.checkRead(off, 2));
} else {
- return this.getWord(seg.checkRead(off, this.dataSize-1));
+ return this.getWord(seg.checkRead(off, this.dataSize));
}
};
@@ -2892,7 +2892,7 @@ X86CPU.prototype.getSOWord = function(seg, off)
*/
X86CPU.prototype.setSOByte = function(seg, off, b)
{
- this.setByte(seg.checkWrite(off, 0), b);
+ this.setByte(seg.checkWrite(off, 1), b);
};
/**
@@ -2908,9 +2908,9 @@ X86CPU.prototype.setSOByte = function(seg, off, b)
X86CPU.prototype.setSOWord = function(seg, off, w)
{
if (!I386) {
- this.setShort(seg.checkWrite(off, 1), w);
+ this.setShort(seg.checkWrite(off, 2), w);
} else {
- this.setWord(seg.checkWrite(off, this.dataSize-1), w);
+ this.setWord(seg.checkWrite(off, this.dataSize), w);
}
};
diff --git a/modules/pcjs/lib/x86func.js b/modules/pcjs/lib/x86func.js
index 21d8facfc..77e461401 100644
--- a/modules/pcjs/lib/x86func.js
+++ b/modules/pcjs/lib/x86func.js
@@ -33,6 +33,7 @@
"use strict";
if (typeof module !== 'undefined') {
+ var str = require("../../shared/lib/strlib");
var Messages = require("./messages");
var X86 = require("./x86");
}
@@ -172,8 +173,8 @@ X86.fnBOUND = function BOUND(dst, src)
* Note that BOUND performs signed comparisons, so we must transform all arguments into signed values.
*/
var wIndex = (dst << 16) >> 16;
- var wLower = (this.getShort(this.regEA) << 16) >> 16;
- var wUpper = (this.getShort(this.regEA + 2) << 16) >> 16;
+ var wLower = (this.getWord(this.regEA) << 16) >> 16;
+ var wUpper = (this.getWord(this.regEA + this.dataSize) << 16) >> 16;
this.nStepCycles -= this.cycleCounts.nOpCyclesBound;
if (wIndex < wLower || wIndex > wUpper) {
/*
@@ -332,6 +333,7 @@ X86.fnBTS = function BTS(dst, src)
*/
X86.fnCALLw = function CALLw(dst, src)
{
+ if (DEBUG) this.printMessage("calling " + str.toHex(dst, this.dataSize << 1), this.bitsMessage, true);
this.pushWord(this.getIP());
this.setIP(dst);
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesCallWR : this.cycleCounts.nOpCyclesCallWM);
@@ -351,11 +353,12 @@ X86.fnCALLw = function CALLw(dst, src)
*/
X86.fnCALLF = function CALLF(off, sel)
{
- var regCS = this.getCS();
- var regEIP = this.getIP();
+ if (DEBUG) this.printMessage("calling " + str.toHex(sel, 4) + ':' + str.toHex(off, this.dataSize << 1), this.bitsMessage, true);
+ var oldCS = this.getCS();
+ var oldIP = this.getIP();
if (this.setCSIP(off, sel, true) != null) {
- this.pushWord(regCS);
- this.pushWord(regEIP);
+ this.pushWord(oldCS);
+ this.pushWord(oldIP);
}
};
@@ -372,7 +375,7 @@ X86.fnCALLFdw = function CALLFdw(dst, src)
if (this.regEA === X86.ADDR_INVALID) {
return X86.fnGRPUndefined.call(this, dst, src);
}
- X86.fnCALLF.call(this, dst, this.getShort(this.regEA + 2));
+ X86.fnCALLF.call(this, dst, this.getShort(this.regEA + this.dataSize));
this.nStepCycles -= this.cycleCounts.nOpCyclesCallDM;
this.opFlags |= X86.OPFLAG.NOWRITE;
return dst;
@@ -917,16 +920,16 @@ X86.fnINT = function INT(nIDT, nError, nCycles)
*/
this.nStepCycles -= this.cycleCounts.nOpCyclesInt + nCycles;
this.segCS.fCall = true;
- var regPS = this.getPS();
- var regCS = this.getCS();
- var regEIP = this.getIP();
+ var oldPS = this.getPS();
+ var oldCS = this.getCS();
+ var oldIP = this.getIP();
var addr = this.segCS.loadIDT(nIDT);
if (addr != X86.ADDR_INVALID) {
this.regLIP = addr;
if (PREFETCH) this.flushPrefetch(this.regLIP);
- this.pushWord(regPS);
- this.pushWord(regCS);
- this.pushWord(regEIP);
+ this.pushWord(oldPS);
+ this.pushWord(oldCS);
+ this.pushWord(oldIP);
if (nError != null) this.pushWord(nError);
this.nFault = -1;
}
@@ -952,11 +955,12 @@ X86.fnIRET = function IRET()
}
}
var cpl = this.segCS.cpl;
- var regEIP = this.popWord();
- var regCS = this.popWord();
- var regPS = this.popWord();
- if (this.setCSIP(regEIP, regCS, false) != null) {
- this.setPS(regPS, cpl);
+ var newIP = this.popWord();
+ var newCS = this.popWord();
+ var newPS = this.popWord();
+ if (DEBUG) this.printMessage(" returning to " + str.toHex(newCS, 4) + ':' + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true);
+ if (this.setCSIP(newIP, newCS, false) != null) {
+ this.setPS(newPS, cpl);
if (this.cIntReturn) this.checkIntReturn(this.regLIP);
}
};
@@ -990,7 +994,7 @@ X86.fnJMPFdw = function JMPFdw(dst, src)
if (this.regEA === X86.ADDR_INVALID) {
return X86.fnGRPUndefined.call(this, dst, src);
}
- this.setCSIP(dst, this.getShort(this.regEA + 2));
+ this.setCSIP(dst, this.getShort(this.regEA + this.dataSize));
if (this.cIntReturn) this.checkIntReturn(this.regLIP);
this.nStepCycles -= this.cycleCounts.nOpCyclesJmpDM;
this.opFlags |= X86.OPFLAG.NOWRITE;
@@ -1055,7 +1059,7 @@ X86.fnLDS = function LDS(dst, src)
X86.opUndefined.call(this);
return dst;
}
- this.setDS(this.getShort(this.regEA + 2));
+ this.setDS(this.getShort(this.regEA + this.dataSize));
this.nStepCycles -= this.cycleCounts.nOpCyclesLS;
return src;
};
@@ -1101,7 +1105,7 @@ X86.fnLES = function LES(dst, src)
X86.opUndefined.call(this);
return dst;
}
- this.setES(this.getShort(this.regEA + 2));
+ this.setES(this.getShort(this.regEA + this.dataSize));
this.nStepCycles -= this.cycleCounts.nOpCyclesLS;
return src;
};
@@ -1120,7 +1124,7 @@ X86.fnLFS = function LFS(dst, src)
X86.opUndefined.call(this);
return dst;
}
- this.setFS(this.getShort(this.regEA + 2));
+ this.setFS(this.getShort(this.regEA + this.dataSize));
this.nStepCycles -= this.cycleCounts.nOpCyclesLS;
return src;
};
@@ -1170,7 +1174,7 @@ X86.fnLGS = function LGS(dst, src)
X86.opUndefined.call(this);
return dst;
}
- this.setGS(this.getShort(this.regEA + 2));
+ this.setGS(this.getShort(this.regEA + this.dataSize));
this.nStepCycles -= this.cycleCounts.nOpCyclesLS;
return src;
};
@@ -1287,7 +1291,7 @@ X86.fnLSS = function LSS(dst, src)
X86.opUndefined.call(this);
return dst;
}
- this.setSS(this.getShort(this.regEA + 2));
+ this.setSS(this.getShort(this.regEA + this.dataSize));
this.nStepCycles -= this.cycleCounts.nOpCyclesLS;
return src;
};
@@ -1738,11 +1742,12 @@ X86.fnRCRd = function RCRd(dst, src)
*/
X86.fnRETF = function RETF(n)
{
- var regEIP = this.popWord();
- var regCS = this.popWord();
+ var newIP = this.popWord();
+ var newCS = this.popWord();
+ if (DEBUG) this.printMessage(" returning to " + str.toHex(newCS, 4) + ':' + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true);
n <<= (this.dataSize >> 2);
if (n) this.setSP(this.getSP() + n); // TODO: optimize
- if (this.setCSIP(regEIP, regCS, false)) {
+ if (this.setCSIP(newIP, newCS, false)) {
if (n) this.setSP(this.getSP() + n); // TODO: optimize
/*
* As per Intel documentation: "If any of [the DS or ES] registers refer to segments whose DPL is
diff --git a/modules/pcjs/lib/x86ops.js b/modules/pcjs/lib/x86ops.js
index 9750fa656..3ce6b884d 100644
--- a/modules/pcjs/lib/x86ops.js
+++ b/modules/pcjs/lib/x86ops.js
@@ -33,6 +33,7 @@
"use strict";
if (typeof module !== 'undefined') {
+ var str = require("../../shared/lib/strlib");
var Component = require("../../shared/lib/component");
var Messages = require("./messages");
var X86 = require("./x86");
@@ -1562,8 +1563,7 @@ X86.opOUTSb = function OUTSb()
/*
* NOTE: 5 + 4n is the cycle time for the 80286; the 80186/80188 has different values: 14 cycles for
- * an unrepeated INS, and 8 + 8n for a repeated INS. However, accurate cycle times for the 80186/80188 is
- * low priority. TODO: Fix this someday.
+ * an unrepeated INS, and 8 + 8n for a repeated INS. TODO: Fix this someday.
*/
var nCycles = 5;
@@ -1608,8 +1608,7 @@ X86.opOUTSw = function OUTSw()
/*
* NOTE: 5 + 4n is the cycle time for the 80286; the 80186/80188 has different values: 14 cycles for
- * an unrepeated INS, and 8 + 8n for a repeated INS. However, accurate cycle times for the 80186/80188 is
- * low priority. TODO: Fix this someday.
+ * an unrepeated INS, and 8 + 8n for a repeated INS. TODO: Fix this someday.
*/
var nCycles = 5;
@@ -3190,7 +3189,9 @@ X86.opGRP2wn = function GRP2wn()
X86.opRETn = function RETn()
{
var n = this.getIPWord() << (this.dataSize >> 2);
- this.setIP(this.popWord());
+ var newIP = this.popWord();
+ if (DEBUG) this.printMessage(" returning to " + str.toHex(this.segCS.sel, 4) + ':' + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true);
+ this.setIP(newIP);
if (n) this.setSP(this.getSP() + n); // TODO: optimize
this.nStepCycles -= this.cycleCounts.nOpCyclesRetn;
};
@@ -3202,7 +3203,9 @@ X86.opRETn = function RETn()
*/
X86.opRET = function RET()
{
- this.setIP(this.popWord());
+ var newIP = this.popWord();
+ if (DEBUG) this.printMessage(" returning to " + str.toHex(this.segCS.sel, 4) + ':' + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true);
+ this.setIP(newIP);
this.nStepCycles -= this.cycleCounts.nOpCyclesRet;
};
@@ -3286,8 +3289,7 @@ X86.opENTER = function ENTER()
var bLevel = this.getIPByte() & 0x1f;
/*
* NOTE: 11 is the minimum cycle time for the 80286; the 80186/80188 has different cycle times: 15, 25 and
- * 22 + 16 * (bLevel - 1) for bLevel 0, 1 and > 1, respectively. However, accurate cycle times for the 80186/80188
- * is low priority. TODO: Fix this someday.
+ * 22 + 16 * (bLevel - 1) for bLevel 0, 1 and > 1, respectively. TODO: Fix this someday.
*/
this.nStepCycles -= 11;
this.pushWord(this.regEBP);
@@ -3316,8 +3318,7 @@ X86.opLEAVE = function LEAVE()
this.setSP((this.getSP() & ~this.segSS.addrMask) | (this.regEBP & this.segSS.addrMask));
this.regEBP = (this.regEBP & ~this.dataMask) | (this.popWord() & this.dataMask);
/*
- * NOTE: 5 is the cycle time for the 80286; the 80186/80188 has a cycle time of 8. However, accurate cycle
- * counts for the 80186/80188 is low priority. TODO: Fix this someday.
+ * NOTE: 5 is the cycle time for the 80286; the 80186/80188 has a cycle time of 8. TODO: Fix this someday.
*/
this.nStepCycles -= 5;
};
@@ -3648,8 +3649,11 @@ X86.opOUTw = function OUTw()
X86.opCALL = function CALL()
{
var disp = this.getIPWord();
- this.pushWord(this.getIP());
- this.setIP(this.getIP() + disp);
+ var oldIP = this.getIP();
+ var newIP = oldIP + disp;
+ if (DEBUG) this.printMessage("calling " + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true);
+ this.pushWord(oldIP);
+ this.setIP(newIP);
this.nStepCycles -= this.cycleCounts.nOpCyclesCall;
};
diff --git a/modules/pcjs/lib/x86seg.js b/modules/pcjs/lib/x86seg.js
index 33904852d..7af515a63 100644
--- a/modules/pcjs/lib/x86seg.js
+++ b/modules/pcjs/lib/x86seg.js
@@ -243,12 +243,12 @@ X86Seg.prototype.loadIDTProt = function loadIDTProt(nIDT)
/**
* checkReadReal(off, cb, fSuppress)
*
- * TODO: Invoke X86.fnFault.call(this.cpu, X86.EXCEPTION.GP_FAULT) if off is 0xffff and cb is 1;
+ * TODO: Invoke X86.fnFault.call(this.cpu, X86.EXCEPTION.GP_FAULT) if off is 0xffff and cb > 1;
* also, whether or not the fnFault() call should include an error code, since this is happening in real-mode.
*
* @this {X86Seg}
* @param {number} off is a segment-relative offset
- * @param {number} cb is number of extra bytes to check (0 or 1)
+ * @param {number} cb is number of bytes to check (1, 2 or 4)
* @param {boolean} [fSuppress] is true to suppress any errors
* @return {number} corresponding physical address if valid, or ADDR_INVALID if error (TODO: No error conditions exist yet)
*/
@@ -260,12 +260,12 @@ X86Seg.prototype.checkReadReal = function checkReadReal(off, cb, fSuppress)
/**
* checkWriteReal(off, cb, fSuppress)
*
- * TODO: Invoke X86.fnFault.call(this.cpu, X86.EXCEPTION.GP_FAULT) if off is 0xffff and cb is 1;
+ * TODO: Invoke X86.fnFault.call(this.cpu, X86.EXCEPTION.GP_FAULT) if off is 0xffff and cb > 1;
* also, whether or not the fnFault() call should include an error code, since this is happening in real-mode.
*
* @this {X86Seg}
* @param {number} off is a segment-relative offset
- * @param {number} cb is number of extra bytes to check (0 or 1)
+ * @param {number} cb is number of bytes to check (1, 2 or 4)
* @param {boolean} [fSuppress] is true to suppress any errors
* @return {number} corresponding physical address if valid, or ADDR_INVALID if error (TODO: No error conditions exist yet)
*/
@@ -279,13 +279,13 @@ X86Seg.prototype.checkWriteReal = function checkWriteReal(off, cb, fSuppress)
*
* @this {X86Seg}
* @param {number} off is a segment-relative offset
- * @param {number} cb is number of extra bytes to check (0 or 1)
+ * @param {number} cb is number of bytes to check (1, 2 or 4)
* @param {boolean} [fSuppress] is true to suppress any errors
* @return {number} corresponding physical address if valid, or ADDR_INVALID if not
*/
X86Seg.prototype.checkReadProt = function checkReadProt(off, cb, fSuppress)
{
- if (off + cb <= this.limit) {
+ if (off + cb - 1 <= this.limit) {
return (this.base + off)|0;
}
return this.checkReadProtDisallowed(off, cb, fSuppress);
@@ -296,13 +296,13 @@ X86Seg.prototype.checkReadProt = function checkReadProt(off, cb, fSuppress)
*
* @this {X86Seg}
* @param {number} off is a segment-relative offset
- * @param {number} cb is number of extra bytes to check (0 or 1)
+ * @param {number} cb is number of bytes to check (1, 2 or 4)
* @param {boolean} [fSuppress] is true to suppress any errors
* @return {number} corresponding physical address if valid, ADDR_INVALID if not
*/
X86Seg.prototype.checkReadProtDown = function checkReadProtDown(off, cb, fSuppress)
{
- if (off + cb > this.limit) {
+ if (off + cb - 1 > this.limit) {
return (this.base + off)|0;
}
return this.checkReadProtDisallowed(off, cb, fSuppress);
@@ -313,7 +313,7 @@ X86Seg.prototype.checkReadProtDown = function checkReadProtDown(off, cb, fSuppre
*
* @this {X86Seg}
* @param {number} off is a segment-relative offset
- * @param {number} cb is number of extra bytes to check (0 or 1)
+ * @param {number} cb is number of bytes to check (1, 2 or 4)
* @param {boolean} [fSuppress] is true to suppress any errors
* @return {number} corresponding physical address if valid, ADDR_INVALID if not
*/
@@ -330,13 +330,13 @@ X86Seg.prototype.checkReadProtDisallowed = function checkReadProtDisallowed(off,
*
* @this {X86Seg}
* @param {number} off is a segment-relative offset
- * @param {number} cb is number of extra bytes to check (0 or 1)
+ * @param {number} cb is number of bytes to check (1, 2 or 4)
* @param {boolean} [fSuppress] is true to suppress any errors
* @return {number} corresponding physical address if valid, ADDR_INVALID if not
*/
X86Seg.prototype.checkWriteProt = function checkWriteProt(off, cb, fSuppress)
{
- if (off + cb <= this.limit) {
+ if (off + cb - 1 <= this.limit) {
return (this.base + off)|0;
}
return this.checkWriteProtDisallowed(off, cb, fSuppress);
@@ -347,13 +347,13 @@ X86Seg.prototype.checkWriteProt = function checkWriteProt(off, cb, fSuppress)
*
* @this {X86Seg}
* @param {number} off is a segment-relative offset
- * @param {number} cb is number of extra bytes to check (0 or 1)
+ * @param {number} cb is number of bytes to check (1, 2 or 4)
* @param {boolean} [fSuppress] is true to suppress any errors
* @return {number} corresponding physical address if valid, ADDR_INVALID if not
*/
X86Seg.prototype.checkWriteProtDown = function checkWriteProtDown(off, cb, fSuppress)
{
- if (off + cb > this.limit) {
+ if (off + cb - 1 > this.limit) {
return (this.base + off)|0;
}
return this.checkWriteProtDisallowed(off, cb, fSuppress);
@@ -364,7 +364,7 @@ X86Seg.prototype.checkWriteProtDown = function checkWriteProtDown(off, cb, fSupp
*
* @this {X86Seg}
* @param {number} off is a segment-relative offset
- * @param {number} cb is number of extra bytes to check (0 or 1)
+ * @param {number} cb is number of bytes to check (1, 2 or 4)
* @param {boolean} [fSuppress] is true to suppress any errors
* @return {number} corresponding physical address if valid, ADDR_INVALID if not
*/
diff --git a/modules/shared/lib/embed.js b/modules/shared/lib/embed.js
index b9fe966f1..0f966ae12 100644
--- a/modules/shared/lib/embed.js
+++ b/modules/shared/lib/embed.js
@@ -32,7 +32,7 @@
"use strict";
-/* global window: true, XSLTProcessor: false, web: true, Component: true, APPNAME: false, APPVERSION: false, DEBUG: true */
+/* global window: true, XSLTProcessor: false, APPNAME: false, APPVERSION: false, DEBUG: true */
if (typeof module !== 'undefined') {
var Component;
diff --git a/modules/shared/lib/strlib.js b/modules/shared/lib/strlib.js
index 0a889053b..68d5d7a68 100644
--- a/modules/shared/lib/strlib.js
+++ b/modules/shared/lib/strlib.js
@@ -145,7 +145,7 @@ str.toHex = function(n, cch)
*
* Alias for "0x" + str.toHex(b, 2)
*
- * @param {number|undefined} b is a byte value
+ * @param {number|null|undefined} b is a byte value
* @return {string} the hex representation of b
*/
str.toHexByte = function(b)
@@ -158,7 +158,7 @@ str.toHexByte = function(b)
*
* Alias for "0x" + str.toHex(w, 4)
*
- * @param {number|undefined} w is a word (16-bit) value
+ * @param {number|null|undefined} w is a word (16-bit) value
* @return {string} the hex representation of w
*/
str.toHexWord = function(w)
@@ -171,7 +171,7 @@ str.toHexWord = function(w)
*
* Alias for "0x" + toHex(l)
*
- * @param {number|undefined} l is a dword (32-bit) value
+ * @param {number|null|undefined} l is a dword (32-bit) value
* @return {string} the hex representation of w
*/
str.toHexLong = function(l)
diff --git a/modules/shared/lib/usrlib.js b/modules/shared/lib/usrlib.js
index 63f0d0db6..455d07f7e 100644
--- a/modules/shared/lib/usrlib.js
+++ b/modules/shared/lib/usrlib.js
@@ -39,7 +39,7 @@ var usr = {};
*
* @param {Array} a is an array
* @param {number|string|Array|Object} v
- * @param {function((number|string), (number|string))} [fnCompare]
+ * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]
* @return {number} the index of matching entry if non-negative, otherwise the index of the insertion point
*/
usr.binarySearch = function(a, v, fnCompare) {
@@ -73,7 +73,7 @@ usr.binarySearch = function(a, v, fnCompare) {
*
* @param {Array} a is an array
* @param {number|string|Array|Object} v is the value to insert
- * @param {function((number|string), (number|string))} [fnCompare]
+ * @param {function((number|string|Array|Object), (number|string|Array|Object))} [fnCompare]
*/
usr.binaryInsert = function(a, v, fnCompare) {
var index = usr.binarySearch(a, v, fnCompare);