====== 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**.