Table of Contents
HP 150 Memory Poking with DEBUG and CHKDSK
Reading, writing and testing memory on the HP 150 from the DEBUG prompt, plus
the memory map and the 384K SRAM expansion card. Written against DEBUG
from MS-DOS 2.x on the HP 150. Map is from Technical Manual 45625-90001,
p.4-1/4-2.
Everything in DEBUG is hex. Never type an H suffix — 10 means sixteen.
The HP 150 is not an IBM PC. For testing, only write inside 40000-9FFFF.
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 all of U10 | F 4000:0000 L8000 55 |
| Compare two ranges | C 4000:0000 L4000 4000:4000 |
| Find a byte | S 4000:0000 L8000 AA |
| Copy a block | M 4000:0000 L100 4800:0000 |
| Hex sum and difference | H 4800 4000 |
| Show registers | R |
| Disassemble | U F800:7A48 |
| Read an I/O port | I 40 |
| Write an I/O port | O 40 FF |
| Pause a long dump | Ctrl-S |
| Stop a long dump | Ctrl-C |
| 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:7FFF | 47FFF |
4800:0000 | 48000 |
4000:8000 | 48000 — the same byte as 4800: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 7FFF
# Range as start plus L and a LENGTH:
D 4000:0000 L8000
Maximum length is L FFFF.
# 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 U10:
S 4000:0000 L8000 AA
Prints each address where the pattern was found.
# Find a text string:
S 4000:0000 L8000 "HP"
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 all 32K of U10 with 55:
F 4000:0000 L8000 55
# Fill with a repeating pattern — 01 02 01 02 …:
F 4000:0000 L100 01 02
# Copy a block:
M 4000:0000 L100 4800:0000
Compare and Do Hex Math
# Compare two ranges and print every byte that differs:
C 4000:0000 L4000 4000:4000
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 4800 4000
Prints 8800 0800.
Registers and Code
# Show all registers and the next instruction:
R
# Change AX — DEBUG prompts with a colon:
R AX
# Disassemble the firmware memory-sizing loop:
U F800:7A48
# 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
I/O Ports
# Read an I/O port:
I 40
# Write an I/O port:
O 40 FF
HP 150 I/O ports are not IBM PC ports. A port number out of a PC book hits something else here.
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 floppy. Do
not use W unless you mean it.
# List the commands:
?
Some versions only.
DEBUG keys
| Keys | Action |
|---|---|
Ctrl-S | Pause a long dump |
Ctrl-C | Stop it |
HP 150 Memory Map
| Physical | DEBUG | What is there |
|---|---|---|
| 00000-003FF | 0000:0000 | 8088 interrupt vectors |
| 00400-067FF | 0040:0000 | Firmware variables (reserved) |
| 06800-3FFFF | 0680:0000 | IO.SYS, MSDOS.SYS, COMMAND.COM, programs — standard 256K on the memory PCA |
| 40000-7FFFF | 4000 to 7000 | RAM expansion — this card, U10-U17 |
| 80000-8FFFF | 8000 | ROM expansion — this card, U18-U19 |
| 90000-93FFF | 9000 | Accessory slot 1 window (NSLOTSEL1) |
| 94000-9FFFF | 9400 | Reserved, future slots |
| 90000-9FFFF | 9000 | This card, U20-U21 — overlays the two rows above |
| A0000-A3FFF | A000 | Accessory slot 2 window (NSLOTSEL2) |
| A4000-AFFFF | A400 | Reserved, future slots |
| B0000-B7FFF | B000 | Firmware ROM 1 |
| B8000-BBFFF | B800 | System status LEDs (6, on the memory PCA) |
| BC000-BC0FF | BC00 | CMOS configuration RAM, 256 x 4 bits |
| BC100-BFFFF | — | Images of the CMOS RAM |
| C0000-C7FFF | C000 | Graphics RAM, 32K |
| C8000-CFFFF | — | Image of the graphics RAM |
| D0000-D2FFF | D000 | Alphanumeric character RAM, 12K |
| D3000-D3FFF | D300 | CRT controller registers / VATT latch |
| D4000-DFFFF | — | Reserved |
| E0000-E7FFF | E000 | Firmware ROM 2 |
| E8000-EFFFF | E800 | Firmware ROM 3 |
| F0000-F7FFF | F000 | Firmware ROM 4 |
| F8000-FFFFF | F800 | Firmware ROM 5 — reset starts at FFFF0 |
Standard 256K banks on the memory PCA
| Bank | Physical | Chips |
|---|---|---|
| 0 | 00000-0FFFF | U42-U49 |
| 1 | 10000-1FFFF | U32-U39 |
| 2 | 20000-2FFFF | U22-U29 |
| 3 | 30000-3FFFF | U12-U19 |
The two addresses that are not what a PC taught you
# 1. B800 is not video RAM here.
On the HP 150 it is the six system status LEDs. Writing to it changes the LEDs, not the screen.
# 2. BC00 is the saved configuration.
It is the CMOS configuration RAM. Writing to it changes the saved configuration. Stay inside 40000-9FFFF for anything that writes.
The RAM Card
Twelve 32K chips, U10-U21, covering 40000-9FFFF.
| Chip | Physical | DEBUG range | 64K block | Decoder |
|---|---|---|---|---|
| U10 | 40000-47FFF | 4000:0000 - 4000:7FFF | 4 | U1 |
| U11 | 48000-4FFFF | 4800:0000 - 4800:7FFF | 4 | U1 |
| U12 | 50000-57FFF | 5000:0000 - 5000:7FFF | 5 | U1 |
| U13 | 58000-5FFFF | 5800:0000 - 5800:7FFF | 5 | U1 |
| U14 | 60000-67FFF | 6000:0000 - 6000:7FFF | 6 | U1 |
| U15 | 68000-6FFFF | 6800:0000 - 6800:7FFF | 6 | U1 |
| U16 | 70000-77FFF | 7000:0000 - 7000:7FFF | 7 | U1 |
| U17 | 78000-7FFFF | 7800:0000 - 7800:7FFF | 7 | U1 |
| U18 | 80000-87FFF | 8000:0000 - 8000:7FFF | 8 | U6 |
| U19 | 88000-8FFFF | 8800:0000 - 8800:7FFF | 8 | U6 |
| U20 | 90000-97FFF | 9000:0000 - 9000:7FFF | 9 | U6 |
| U21 | 98000-9FFFF | 9800:0000 - 9800:7FFF | 9 | U6 |
Other parts on the card
| Part | Device | Job |
|---|---|---|
| U1, U6 | GAL22V10D | Address decoders — U1 also drives /WE and the data buffer enable for the whole card |
| U2 | 74ALS245 | Data buffer |
| U3-U5 | 74ALS244 | Address and control buffers |
The gotcha that will waste your afternoon
# 1. Fit chips in fours, or the power-on test fails with 000C.
The power-on test wants expansion RAM in 128K steps — U10-U13, U14-U17,
U18-U21. Any other count still works under DOS — U10 alone gave 288K in
CHKDSK — but power-on stops here until you press Return:
Power-on test failed 000C
000C is two bits. Bit 3 — memory is not in whole 128K steps. Bit 2 — it then tests the missing 64K block and fails. Nothing is actually broken.
| Chips fitted | Total | Power-on test |
|---|---|---|
| 4 (U10-U13) | 384K | clean |
| 8 (U10-U17) | 512K | clean |
| 12 (U10-U21) | 640K | clean |
| any other count | 256K + 32K per chip | fails 000C, press Return |
Each chip is 32K, so CHKDSK reads 256K + 32K x chips either way.
Test Recipes
U10 shown throughout. Change the segment for other chips — see the card table above.
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-A14
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
# 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 chip
Fill, compare the halves, repeat with the opposite pattern.
# Fill the chip with 55:
F 4000:0000 L8000 55
# Compare the two halves — no output means good:
C 4000:0000 L4000 4000:4000
# Fill the chip with AA:
F 4000:0000 L8000 AA
# Compare the two halves again:
C 4000:0000 L4000 4000:4000
4. Chip select
A write to the next chip must not land in this one.
# Mark this chip:
E 4000:0000 11
# Mark the next chip:
E 4800:0000 22
# Check this chip — it must still be 11:
D 4000:0000 L1
5. Empty space
# See what the bus returns where nothing answers — slot 2, not on this card:
D A000:0000 L20
After DEBUG
# Check what DOS counted:
CHKDSK
The bytes total memory line is the number that matters.
| Memory | bytes total memory |
|---|---|
| 256K (stock) | 262144 |
| 288K | 294912 |
| 320K | 327680 |
| 384K | 393216 |
| 512K | 524288 |
| 640K | 655360 |
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
Power-on test failed 000C | chips not fitted in fours | fit U10-U13, U14-U17 or U18-U21 as a set, or press Return |
| Status LEDs change after a write | wrote to B800 | it is the LEDs, not video RAM — write only in 40000-9FFFF |
| Saved configuration changed | wrote to BC00 | it is the CMOS RAM — reconfigure, then keep out |
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 | chip select not decoding | check U1 (U6 for U18-U21) |
| 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 |
| Floppy unreadable after DEBUG | W with sector numbers | do not use raw W unless you mean it |
| CHKDSK total lower than expected | fewer chips answering than fitted | 256K + 32K per chip — test each chip's segment |
? gives an error | this DEBUG version lacks it | use the Quick Reference above |
| PC port number does nothing useful | HP 150 ports are not PC ports | look the port up in the HP manual |
Rule of thumb: read anywhere, write only in 40000-9FFFF, and fit the chips in fours.
