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