--- title: "RAMPager" id: 56707 type: "computer_media" slug: "rampager" url: "http://localhost/computer_media/rampager/" markdown_url: "http://localhost/computer_media/rampager.md" published_at: "2024-09-22T23:31:48+00:00" modified_at: "2026-04-03T07:58:57+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/09/RAMPager.png" excerpt: "A full-featured RAM text editor built around a Z80 machine code payload hidden inside a single REM statement — with block-graphics title art and a live command reference screen." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" indiv: - name: "Dan Tandberg" slug: "dan-tandberg" taxonomy: "indiv" url: "http://localhost/indiv/dan-tandberg/" genre: - name: "Programming" slug: "programming" taxonomy: "genre" url: "http://localhost/type/programming/" media_contents: - id: 57780 title: "CassFile2" type: "computer_media" url: "http://localhost/computer_media/cassfile2-2/" media_type: "Program" programmers: - name: "Dan Tandberg" slug: "dan-tandberg" taxonomy: "indiv" url: "http://localhost/indiv/dan-tandberg/" download_url: "https://archive.org/download/timex-sinclair-software-archive/RAMPager%20%281984%29%28Calliope%20Software%29%28TS1000%29%28US%29%28Cassette%29.zip" mediadate: "1984" producer_company: - id: 10718 title: "Calliope Software" type: "company" url: "http://localhost/company/calliope-software/" images: - url: "http://localhost/wp-content/uploads/2024/09/RAMPager.png" - url: "http://localhost/wp-content/uploads/2024/09/RAMPager.jpg" related_products: - id: 13746 title: "Rampager" type: "product" url: "http://localhost/product/rampager/" media_type_tags: "Programming" --- # RAMPager RAMPAGE-R is a machine-code-driven RAM text editor that loads and runs a substantial Z80 routine embedded in the REM statement at line 1. The program displays a title screen rendered in block graphics alongside a command reference listing read/write operations such as address jump, page navigation, copy, insert, and kill. After the user presses ENTER, control is transferred to the machine code via RAND USR 30720 (line 250). A separate save routine at line 1000 uses RAND USR 16526 to invoke the system’s SAVE entry point, preserving the program including its embedded binary payload. The REM block at line 1 contains several hundred bytes of Z80 machine code that implements the full editor logic, including keyboard scanning, screen memory manipulation, and cursor movement. *** ## Program Analysis ### Program Structure The listing divides into two functional blocks: 1. **Lines 1–260**: Title/splash screen, command reference, and launch sequence. 2. **Lines 1000–1030**: A self-save utility that preserves the program (including machine code) back to tape. Line 1 is a `REM` statement whose body is not human-readable text but rather a dense stream of Z80 opcodes. The BASIC portion is purely a loader/UI shell; every meaningful operation of the editor is performed by the machine code. ### Machine Code Payload The `REM` at line 1 contains several hundred bytes of Z80 machine code. The entry point is reached by `RAND USR 30720` at line 250. The hex address 30720 (0x7800) places the entry inside the REM body, which in a 16 KB RAM machine sits in a predictable location given a freshly loaded program. Significant Z80 patterns visible in the payload include: - `ED B0` — `LDIR` block-copy instructions, used for moving screen data and initialising memory regions. - `ED 42` / `ED 52` — `SBC HL,BC` / `SBC HL,DE`, used for 16-bit comparisons to determine cursor position boundaries and direction. - `CD BB 02` — repeated `CALL 0x02BB`, the ROM keyboard-scan routine that returns a key row/column result; used throughout the main edit loop for polled input. - `CD BD 07` — `CALL 0x07BD`, the ROM routine that converts a character address to a display-file address. - `CD 1C 7A` — an internal subroutine (within the REM body) called repeatedly; likely the routine that writes nibble-encoded characters to the display file. - Structured `CALL cc / JP cc` chains implementing a multi-key dispatch table for the editor commands (A, 6, 7, Z, W, L, S6, S7, I, K). - `CB 44`, `CB 5D`, `CB 65` — `BIT` tests on B and E registers, used to decode the two-byte keyboard port result into individual key states. ### Title Screen Rendering Lines 20–40 use zmakebas block-graphic escape sequences to draw a decorative logo in the BASIC `PRINT` statements. The logo is composed entirely of the eight 2×2 block characters (codes 128–135), requiring no UDG definitions or machine code for the title art. Line 100 uses inverse-video characters (percent-encoded as `%R%A%M%P%A%G%E%R` etc.) to render the heading “RAMPAGE-R COMMAND LIST” with alternating highlighted letters, a common Sinclair BASIC display technique. Lines 120 uses repeated `\~~` sequences (inverse tilde / pound-sign characters) to draw separator lines, producing a ruled appearance. ### Command Reference Table The on-screen command list documents the following editor operations: | Mode | Key | Function | | --- | --- | --- | | Read | A | Address (jump to address) | | Read | 6 | Next page | | Read | 7 | Last page | | Read | Z | Copy | | Read | W | Write (enter write mode) | | Write | L | Last (go to last) | | Write | S6 | Scroll down | | Write | S7 | Scroll up | | Write | I | Insert | | Write | K | Kill (delete) | | Both | ENTER | Return to Read mode | | Both | BREAK | Return to BASIC | ### Input Handling (BASIC side) Line 230 implements a busy-wait on `INKEY$` comparing against `CHR$ 118` (the ENTER key, character code 0x76 in the Sinclair character set) before launching the machine code. This is the standard BASIC polling idiom for waiting on a specific keypress without halting execution. ### Save Routine Lines 1000–1030 constitute a self-contained save block. `RAND USR 16526` at line 1020 calls the ROM SAVE entry point (address 0x408E / 16526), causing the entire BASIC program — including the REM-embedded machine code — to be saved to tape under the name `RAMPAGE-R` (rendered with inverse R via `%R`). After saving, `RUN` at line 1030 restarts the program from line 1, returning to the splash screen. ### Memory Map Observations Several 16-bit addresses appear repeatedly in the machine code as operands to `LD HL,(nn)`, `LD (nn),HL`, and `LD DE,(nn)`: - `0x400C` — likely the PROG/E-LINE system variable area, used to locate the start of the BASIC program in RAM. - `0x407B` — an internal workspace variable storing the current editor cursor or buffer pointer. - `0x403C` / `0x403E` / `0x4036` — additional editor state variables (page start, write position, etc.). - `0x400E` — a further pointer, possibly the current line pointer within the editor buffer. The machine code performs arithmetic on these pointers (adding fixed offsets like `+5`, `+0x10`, `+0x13`, `+0x17`, `+0x18`) consistent with navigating a fixed-width screen of 24 lines × 33 columns, matching the ZX81/TS1000 32-column display with a one-byte attribute or end marker. ### Notable Techniques - The entire editor binary is self-contained in a `REM` line, requiring no separate code loading; the BASIC program *is* the binary. - The use of `RAND USR` (rather than `GO TO` or `GOTO`) to invoke machine code is idiomatic: it discards the USR return value silently and avoids needing a variable assignment. - Keyboard scanning via direct `CALL 0x02BB` (ROM KEYBOARD) is more responsive than BASIC `INKEY$` and allows multi-key combinations (e.g. SHIFT+6 for S6, SHIFT+7 for S7). - The `LDIR` instruction is used for both bulk memory initialisation and text scrolling, avoiding slow byte-by-byte BASIC loops. - The copyright notice (line 70) credits Dan Tandberg, MD of Calliope Software, Albuquerque, New Mexico, 1983. ## Source Code ``` 1 REM B37263235262C2A37B767621824011DF771235EDB02107822440CD9614C9FD362202AC4023CD2679227B40CDB379CD2E7ACDBB21FEFBAFE5ED42E1203CDFB7C1EFDFAFE5ED42CCE77AE11EFEFAFE5ED42CC287BE117FFDAFE5ED42E1C81FDFDAFE5ED42E128B71FBFBAFE5ED42E120BD2AC401110019223C407EC680772A7B40223E402AC40111B0193EB177233EA677233EB877233EB977233E9477CD707BCDBB21BFFDAFE5ED42E1CAE7817FFDAFE5ED42E1C81BFFBAFE5ED42CC8D7BE11EFDEAFE5ED42CCA47BE11EFEEAFE5ED42CCD77BE11DFF7AFE5ED42CC17CE11BFF7AFE5ED42CC287CE1CB4428AECB5D2843CB65283F1FDFDAFE5ED42E1283517FDFAFE5ED42E1282B1FEEFAFE5ED42E128211FDF7AFE5ED42E128171FBF7AFE5ED42E128D1FDEFAFE5ED42E1283C38878C34F7C00E53EA677233EA977233EA977233EB777233E8F77E165C5E5CDBB27CFEFF28F8CB4728F47DCB5F284CB6720EB444DCDBD77EE177E5CDBB27DFEFF20F8E123C110D3652B7ED61CF510F92100111027F147FE02831910FD11E83F147FE02831910FD11640F147FE02831910FD11A0F147FE02831910FD1110F147FE02831910FDC92AC40115019E5617C5E5E51121019EBE1D5150EDB8E17EFE7628B3CFE26205361C2B18F177E11121019C110D8E12323ED4B7B4078CD1C7A2379CD1C7A617C5E5E51121019EBE1D5140EDB8E17E3CFE2C205361C2B18F577E11121019C110DCC9F5E6F0FFFFC61C7723F1E6FC61C77C9ED4B7B402AC4011C019D5C5E53E1C77237723772B2BAA7D664387F57E3C77F118F5C664A723D6A387F57E3C77F118F5C6AA723D61387F57E3C77F118F5E11121019C13D1147AFE1828218B92AC401110019ED5B7B40618D5E51ACD1C7AE11121019D11310F1ED4B7B402AC401113019D5C5E5C5AF66772310FCC1E122E40AFEC038DFEC32819FDCB1C6CD4B91810FE40388FE4338EFFE803842AE40771121019C13D1147AFE1820C1C92AC4011FC219657EF52B10FB2AC402365F1772310FB7EFE02032B18F8FE7628B3CFE26205361C2B18EA772A7B401118019227B40CDB379CD2E7AC92AC40115019E5ED5B7B406181BE57EFE02032B18F8FE7628B3DFE1B20536252B18EA77E110E4ED537B40E1657EF52B10FB2AC402365F1772310FBCDB379CD2E7AC911A1CDF58ED5BE402101E150EDB0ED4B3640CD2015CD55BC92AC40113C019CD2679223640C9CDBB27DFEFF20F8C92A7B401117019ED5B3E40AFED52206CDE77AC357782A3C407EC680771121019223C407EC680772A3E4023223E40CD9B7BC92A7B40ED5B3E40AFED52C82A3C407EC6807711210AFED52223C407EC680772A3E402B223E40CD9B7BC92A3640ED5B3E40AFED52D8444D2A3640545D2BEDB82A3E4077CD2E7A2A3C407EC68077CD9B7BC92A3640ED5B3E40AFED52D8444D2A3E40545D23EDB02A364077CD2E7A2A3C407EC68077CD9B7BC9444DCDBD77E2A3C4077D61C7777F5237EC68077E5CD9B7BCDBB2CB4428F9CB5D2843CB65283F1FDFDAFE5ED42E1283517FDFAFE5ED42E1282B1FEEFAFE5ED42E128211FDF7AFE5ED42E128171FBF7AFE5ED42E128D1FDEFAFE5ED42E128318B30444DCDBD77EE177D61CC1802A3E4077CD2E7A2A7B401117019ED5B3E40AFED52206CDE77AC357782A3E4023223E402A3C401121019223C407EC68077CD9B7BC388781618C36B800 20 PRINT " ' ' :'''. .''. :. .: :''. .''. .''. :''' :'''. ' '" 30 PRINT " :...' :..: : ' : :..' :..: : .. :.. :...'" 40 PRINT " : '. : : : : : : : '..' :... : '." 50 PRINT 60 PRINT " COPYRIGHT 1983" 70 PRINT " DAN TANDBERG, MD" 80 PRINT " CALLIOPE SOFTWARE" 90 PRINT " ALBUQUERQUE, NEW MEXICO",,, 100 PRINT "% % % % % % %R%A%M%P%A%G%E%R% %C%O%M%M%A%N%D% %L%I%S%T% % % % % " 110 PRINT " READ: WRITE:" 120 PRINT " ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~" 130 PRINT " A ADDRESS L LAST" 140 PRINT " 6 NEXT PAGE S6 DOWN" 150 PRINT " 7 LAST PAGE S7 UP" 160 PRINT " Z COPY I INSERT" 170 PRINT " W WRITE K KILL" 180 PRINT 190 PRINT " ENTER: RETURN TO READ" 200 PRINT " BREAK: RETURN TO BASIC" 210 PRINT "================================" 220 PRINT " (PRESS ENTER TO BEGIN)" 230 IF INKEY$<>CHR$ 118 THEN GOTO 230 240 CLS 250 RAND USR 30720 260 STOP 1000 REM % %S%A%V%E% %R%O%U%T%I%N%E% 1010 SAVE "RAMPAGE%R" 1020 RAND USR 16526 1030 RUN ```