Cleaned up DMA port handling and minor tweaks

This commit is contained in:
Jeff Parsons 2015-04-13 14:02:02 -07:00 committed by jeffpar
commit 158cc65da3
16 changed files with 453 additions and 175 deletions

View file

@ -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

View file

@ -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

View file

@ -10,7 +10,7 @@
<rom id="romBIOS" addr="0xf8000" size="0x8000" alias="[0xf0000,0xffff0000,0xffff8000]" file="/devices/pc/bios/compaq/deskpro386/1988-01-28.json"/>
<video ref="/devices/pc/video/video-ega-128kb-lock.xml"/>
<keyboard ref="/devices/pc/keyboard/keyboard-minimal-functions.xml"/>
<debugger id="debugger" messages="fault" commands=""/>
<debugger id="debugger" messages="fault|port" commands=""/>
<panel ref="/devices/pc/panel/btpanel.xml"/>
<fdc ref="/disks/pc/library.xml" width="340px" automount='{A: {name: "PC-DOS 3.00 (Disk 1)", path: "/disks/pc/dos/ibm/3.00/PCDOS300-DISK1.json"}, B: {name: "PC-DOS 3.00 (Disk 2)", path: "/disks/pc/dos/ibm/3.00/PCDOS300-DISK2.json"}}'/>
<hdc id="hdcAT" type="at" drives='[{name:"20Mb Hard Disk",type:2}]'/>

View file

@ -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); },

View file

@ -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();
}

View file

@ -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);

View file

@ -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.

View file

@ -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;

View file

@ -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));
};
/**

View file

@ -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);
}
};

View file

@ -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

View file

@ -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;
};

View file

@ -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
*/

View file

@ -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;

View file

@ -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)

View file

@ -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);