User Tools

Site Tools


debug_ibm

IBM PC Memory Poking with DEBUG and CHKDSK

Reading, writing and testing memory on the IBM PC (5150) and PC/XT (5160) from the DEBUG prompt, plus the memory map, the system-board RAM banks and the common I/O ports. Written for DEBUG from PC DOS / MS-DOS 2.x.

Everything in DEBUG is hex. Never type an H suffix — 10 means sixteen.

Examples assume a 64-256K system board with an expansion RAM card from 40000 up. For testing, only write to RAM that DOS is not using.

Quick Reference

Task Command
Start DEBUG DEBUG
Start with a file loaded DEBUG FILE.COM
Quit Q
Dump 128 bytes D 4000:0000
Dump 16 bytes D 4000:0000 L10
Carry on dumping D
Write bytes E 4000:0000 55 AA 12
Fill a 64K bank F 4000:0000 FFFF 55
Compare two ranges C 4000:0000 L8000 4000:8000
Find a byte S 4000:0000 L8000 AA
Copy a block M 4000:0000 L100 5000:0000
Hex sum and difference H 5000 4000
Show registers R
Disassemble the reset vector U FFFF:0000
BIOS date D F000:FFF5 L8
Model byte D F000:FFFE L1
Memory size the BIOS counted D 0040:0013 L2
Turn off parity NMI O A0 00
Read an I/O port I 61
Pause a long dump Ctrl-S or Ctrl-NumLock
Stop a long dump Ctrl-C or Ctrl-Break
What DOS counted CHKDSK

Starting and Addressing

# Start DEBUG with nothing loaded:

DEBUG

The prompt is a single -. A dash means DEBUG is waiting.

# Start DEBUG with a file loaded at CS:100:

DEBUG FILE.COM

# Quit back to DOS:

Q

Segment:offset

Every address is SEGMENT:OFFSET. The physical address is (segment x 10h) + offset.

DEBUG address Physical
4000:0000 40000
4000:FFFF 4FFFF
5000:0000 50000
4000:8000 48000 — the same byte as 4800:0000
F000:FFF0 FFFF0 — the same byte as FFFF:0000

Leave the segment off and DEBUG picks one for you — DS for D, E, F, C, S, M and CS for U, A, G, T.

Ranges and lists

# Range as start plus END OFFSET, same segment:

D 4000:0000 FFFF

# Range as start plus L and a LENGTH:

D 4000:0000 L8000

Maximum length is L FFFF. To cover a full 64K segment, use the end-offset form.

# A list — bytes and quoted text, mixed freely — for E, F and S:

E 4000:0000 01 02 FF "HELLO" 00

Look at Memory

# Dump 128 bytes (8 lines) as hex and ASCII:

D 4000:0000

Each line is the address, 16 hex bytes, then the ASCII. A . means not printable.

# Dump exactly 16 bytes:

D 4000:0000 L10

# Carry on from where the last dump stopped:

D

# Find every AA in the first half of the bank:

S 4000:0000 L8000 AA

Prints each address where the pattern was found.

# Find the IBM copyright string in the BIOS:

S F000:E000 FFFF "IBM"

Change Memory

# Write three bytes, no questions asked:

E 4000:0000 55 AA 12

# Edit byte by byte, interactively:

E 4000:0000

DEBUG shows each byte in turn and waits.

Keys Action
new value, then Space Store it, move to the next byte
Space alone Skip, keep the byte as it is
- Back one byte
Enter Finish

# Fill a whole 64K bank with 55:

F 4000:0000 FFFF 55

# Fill with a repeating pattern — 01 02 01 02 …:

F 4000:0000 L100 01 02

# Copy a block:

M 4000:0000 L100 5000:0000

# Fill a CGA 80×25 screen with the letter A — proof you found video RAM:

F B800:0000 LFA0 41 07

# Same thing on a monochrome (MDA) adapter:

F B000:0000 LFA0 41 07

Each character cell is two bytes — the character, then the attribute. 07 is normal white on black.

Compare and Do Hex Math

# Compare two ranges and print every byte that differs:

C 4000:0000 L8000 4000:8000

No output at all means identical. Each line of output is a mismatch, in the order address 1, byte 1, byte 2, address 2.

# Sum and difference of two hex numbers:

H 5000 4000

Prints 9000 1000.

Registers and Code

# Show all registers and the next instruction:

R

# Change AX — DEBUG prompts with a colon:

R AX

# Disassemble the reset vector — a far jump into the BIOS power-on test:

U FFFF:0000

# Type in 8088 instructions at offset 100:

A 100

A blank line ends assembly.

# Run from CS:IP:

G

# Start at 100, stop at a breakpoint at 110:

G=100 110

# Run one instruction, then show the registers:

T

# Run five instructions:

T 5

Reboot from DEBUG

# Set the warm-boot flag so the power-on test skips the memory count:

E 0040:0072 34 12

# Jump to the reset vector:

G=FFFF:0000

Skip the first command for a full cold boot with the memory test.

Files

# Name the file to work on:

N TEST.COM

# Load the named file at CS:100:

L

# Write the named file back to disk:

W

W with sector numbers writes raw sectors and can wreck a disk — including the hard disk. Do not use W unless you mean it.

# List the commands:

?

Later versions only. DOS 2.x DEBUG answers with an error.

DEBUG keys

Keys Action
Ctrl-S or Ctrl-NumLock Pause a long dump
Ctrl-C or Ctrl-Break Stop it

IBM PC Memory Map

Physical DEBUG What is there
00000-003FF 0000:0000 8088 interrupt vectors
00400-004FF 0040:0000 BIOS data area
00500-005FF 0050:0000 DOS and BASIC data area
00600-9FFFF 0060:0000 IBMBIO.COM, IBMDOS.COM, COMMAND.COM, programs — conventional RAM, up to 640K
A0000-AFFFF A000 Reserved — EGA/VGA graphics RAM if fitted
B0000-B0FFF B000 MDA text RAM, 4K — Hercules uses B0000-B7FFF
B1000-B7FFF — Images of the MDA RAM
B8000-BBFFF B800 CGA video RAM, 16K
BC000-BFFFF — Image of the CGA RAM
C0000-C7FFF C000 EGA/VGA BIOS ROM — empty with MDA or CGA
C8000-C9FFF C800 XT hard disk controller ROM
CA000-DFFFF CA00 Other adapter ROMs, EMS page frame
E0000-EFFFF E000 Reserved — empty on a PC or XT
F0000-F5FFF F000 Reserved — spare ROM socket on the 5150 at F4000
F6000-FDFFF F600 ROM BASIC (Cassette BASIC), 32K
FE000-FFFFF FE00 BIOS, 8K — reset starts at FFFF0

The late XT BIOS (1986) fills all of F0000-FFFFF with two 32K ROMs. BASIC and the BIOS entry points stay at the same addresses.

The address that is the opposite of the HP 150

# 1. B800 really is video RAM here.

Writing to B800 (CGA) or B000 (MDA) changes the screen and nothing else. Harmless. The dangerous writes on a PC are below 0600 — vectors and BIOS data — and anywhere DOS or DEBUG is living.

Useful BIOS locations

DEBUG Size What it holds
0040:0010 word Equipment word — drives, video type, ports
0040:0013 word Memory size in K
0040:0017 byte Keyboard shift flags
0040:0049 byte Video mode — 07 is MDA, 03 is CGA 80 column
0040:006C 4 bytes Timer ticks since midnight
0040:0072 word Reset flag — 1234 means warm boot
F000:FFF5 8 bytes BIOS date, ASCII
F000:FFFE byte Model — FF is PC, FE is XT, FD is PCjr, FC is AT

Words are stored low byte first. Memory size 80 02 is 0280 hex, which is 640.

# Read the memory size the BIOS counted:

D 0040:0013 L2
Dump shows Hex Memory
40 00 0040 64K
00 01 0100 256K
00 02 0200 512K
80 02 0280 640K

# Read the BIOS date:

D F000:FFF5 L8

Adapter ROMs

# Check for an adapter ROM — the hard disk controller lives here:

D C800:0000 L10

A ROM starts with 55 AA. The third byte is its length in 512-byte blocks. FF all the way across means nothing is there.

# Start the low-level format routine in many XT controller ROMs:

G=C800:5

Destroys everything on the hard disk. The entry offset depends on the controller — 5 is the Xebec and Western Digital habit, not a standard.

System Board RAM

Every bank is nine chips — eight data bits plus parity.

5150 with the 16-64K board

Bank Physical Chips
0 00000-03FFF 16K (4116), soldered
1 04000-07FFF 16K
2 08000-0BFFF 16K
3 0C000-0FFFF 16K

5150 or 5160 with the 64-256K board

Bank Physical Chips
0 00000-0FFFF 64K (4164)
1 10000-1FFFF 64K
2 20000-2FFFF 64K
3 30000-3FFFF 64K

Everything from 40000 to 9FFFF is on expansion cards.

5160 with the 256-640K board

Bank Physical Chips
0 00000-3FFFF 256K (41256)
1 40000-7FFFF 256K (41256)
2 80000-8FFFF 64K (4164)
3 90000-9FFFF 64K (4164)

The three gotchas that will waste your afternoon

# 1. Reading RAM the BIOS never counted can halt the machine.

The power-on test writes every byte it counts, which sets the parity bits. RAM that is fitted but above the counted size has random parity. Dump it and the parity circuit fires an NMI:

PARITY CHECK 2

The machine is now dead until you power-cycle. PARITY CHECK 1 is the system board, PARITY CHECK 2 is an expansion card. Fill before you read.

# Fill the range first so the parity bits are valid:

F 4000:0000 FFFF 00

# Or turn the NMI off while you test:

O A0 00

# Turn the NMI back on afterwards:

O A0 80

With NMI off, a bad bit shows up in the dump instead of killing the machine — which is what you want when hunting it.

# 2. On a 5150 the switches decide how much RAM exists.

SW1 positions 3-4 set the system-board RAM. SW2 sets the total. Fit a card and leave SW2 alone, and the BIOS never looks at it. The XT is different — SW1 positions 3-4 cover the system-board banks and the BIOS finds expansion RAM by testing for it.

# 3. A 5150 BIOS older than 10/27/82 cannot count past 544K.

No switch setting fixes it. Check the date before blaming the card.

D F000:FFF5 L8

I/O Ports

# Read an I/O port:

I 61

# Write an I/O port:

O A0 00
Port Device
20-21 8259 interrupt controller
40-43 8253 timer
60-63 8255 — keyboard, switches, speaker gate
A0 NMI mask — 80 on, 00 off
201 Game port
278, 378 Parallel ports
2F8 COM2
320 XT hard disk controller
3B0-3BB MDA
3BC Parallel port on the MDA card
3D0-3DF CGA
3F0-3F7 Floppy controller
3F8 COM1

Test Recipes

Bank at 40000 shown throughout — a 64K block. Change the segment for other banks. Turn the NMI off first with O A0 00 if you want to see bad bits rather than a parity halt.

Stay out of DOS's way. DEBUG sits in low memory and COMMAND.COM keeps its transient half in the top 20K or so of RAM. Everything between is fair game. Overwrite the top and DOS reloads COMMAND.COM from disk when you quit.

1. Data lines

# Write a walking one, then a walking zero:

E 4000:0000 01 02 04 08 10 20 40 80 FE FD FB F7 EF DF BF 7F

# Read it back — it must match exactly as written:

D 4000:0000 L10

2. Address lines A0-A15

One value per address line. None may overwrite another.

# Write a different value at each power-of-two offset:

E 4000:0000 00
E 4000:0001 01
E 4000:0002 02
E 4000:0004 03
E 4000:0008 04
E 4000:0010 05
E 4000:0020 06
E 4000:0040 07
E 4000:0080 08
E 4000:0100 09
E 4000:0200 0A
E 4000:0400 0B
E 4000:0800 0C
E 4000:1000 0D
E 4000:2000 0E
E 4000:4000 0F
E 4000:8000 10

# Read each address back with L1 and check it holds its own value:

D 4000:0100 L1

Repeat for every offset in the list. A wrong value names the stuck or shorted address line.

3. Whole bank

Fill, compare the halves, repeat with the opposite pattern.

# Fill the bank with 55:

F 4000:0000 FFFF 55

# Compare the two halves — no output means good:

C 4000:0000 L8000 4000:8000

# Fill the bank with AA:

F 4000:0000 FFFF AA

# Compare the two halves again:

C 4000:0000 L8000 4000:8000

4. Bank select

A write to the next bank must not land in this one.

# Mark this bank:

E 4000:0000 11

# Mark the next bank:

E 5000:0000 22

# Check this bank — it must still be 11:

D 4000:0000 L1

5. Empty space

# See what the bus returns where nothing answers:

D E000:0000 L20

Usually FF across the line. That is what a missing bank looks like too.

After DEBUG

# Check what DOS counted:

CHKDSK

The bytes total memory line is the number that matters.

Memory bytes total memory
64K 65536
128K 131072
256K 262144
384K 393216
512K 524288
640K 655360

Troubleshooting

Symptom Cause Fix
PARITY CHECK 2 and a dead machine read expansion RAM with bad or never-set parity fill before reading, or O A0 00 first
PARITY CHECK 1 and a dead machine same, on the system board same — then test that bank bit by bit
201 with a number at power-on memory test failed the number points at the bank and bit — test that bank
Card fitted, memory total unchanged (5150) SW2 not set for the new total set SW2, power-cycle
5150 stops counting at 544K BIOS older than 10/27/82 check D F000:FFF5 L8 — needs the later ROM
Dump shows all FF nothing decodes there wrong segment, or the bank is not selected
Screen fills with junk after a write wrote to B000 or B800 harmless — CLS after quitting
Machine hangs after an E or F wrote below 0600 or over DOS reboot — keep writes in free RAM
DOS asks for the COMMAND.COM disk on quit fill ran over the top of RAM harmless — put the DOS disk in
C prints lines of addresses the two ranges differ bad chip, data line or address line — run recipes 1 and 2
Recipe 4 reads 22 instead of 11 bank select not decoding check the card's address switches or decoder
Same byte at two addresses segment overlap not a fault — 4000:8000 is 4800:0000
Value lands sixteen times too big typed decimal or an H suffix everything is hex, no suffix
Command ran on the wrong memory segment left off DEBUG used DS or CS — type the full SEGMENT:OFFSET
Disk unreadable after DEBUG W with sector numbers do not use raw W unless you mean it
? gives an error DOS 2.x DEBUG lacks it use the Quick Reference above

Rule of thumb: read ROM and video freely, fill RAM before you read it, and never write below 0600.

debug_ibm.txt · Last modified: by admin