Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main Page
Community Portal
Village Pump
Recent Changes
Upload File
Help
Help Contents
Editing Guide
Repair Guide Template
Sandbox
Browse Wiki
š Service Manuals
š Schematics
š Apple
š® Nintendo
š Sega
ā” Troubleshooting
Search
Search
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
IBM PALM processor
(section)
Page
Discussion
English
Read
Edit
Edit source
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
Edit source
View history
General
What links here
Related changes
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Native Instruction Set == PALM has a '''16-bit native instruction set''' ā all instructions are exactly one halfword (16 bits). The top 4 bits (the high nibble of the first byte) select the opcode group. The bottom 12 bits encode operands, addressing modes, and condition codes. {| class="wikitable styled-table" style="width:100%; text-align:center;" |+'''PALM native opcode groups (top nibble of the instruction word)''' ! Top nibble !! Mnemonic family !! Operation |- | '''0''' || ALU register-register || ADD, SUB, AND, OR, XOR, MOVE, INC, DEC, MHL (move high to low), MLH (move low to high), GETB (get byte), GETADD (get address), ADDH, etc. |- | '''1''' || CTL || Control byte to device (I/O write of a control byte) |- | '''2''' || LDHD || Load halfword direct (from a direct address) |- | '''3''' || STHD || Store halfword direct |- | '''4''' || PUTB || Put byte to I/O device |- | '''5''' || STHI || Store halfword indirect via register Ry |- | '''6''' || LDBI || Load byte indirect |- | '''7''' || STBI || Store byte indirect |- | '''8''' || EMIT / LBI || Load byte immediate |- | '''9''' || CLRI || Clear bits immediate (mask off bits) |- | '''A''' || ADDI || Add immediate (value +1, so ADDI 0 means add 1) |- | '''B''' || SETI || Set bits immediate (OR a mask) |- | '''C''' || Jump / Skip || Conditional skip family ā '''there are no traditional jump instructions''' |- | '''D''' || LDHI / LWI || Load halfword indirect; LWI synthetic load-word-immediate |- | '''E''' || ROTR / SHFTR / GETB / STAT || Rotate right, shift right, get byte from register, get status |- | '''F''' || SUBI || Subtract immediate (value +1, so SUBI 0 means subtract 1) |} This top-nibble table is reconstructed by the Stuttgart Computer Museum from a recovered IBM-internal "Chapter 2" PALM machine-language document held by the IBM Museum in Sindelfingen, cross-referenced with '''Appendix C of the SY31-0405 5100 Maintenance Information Manual''' (which contains the same opcode set with abbreviated descriptions, and which was '''omitted''' from the 5110 MIM SY31-0550).<ref>Corti, C. Stuttgart Computer Museum IBM 5110 hardware pages, "Opcodes" section.</ref><ref>IBM. ''IBM 5100 Maintenance Information Manual'' SY31-0405-3, October 1979, Appendix C "Microinstructions".</ref> === IBM Chapter 2 Mnemonics (Full Detail) === The IBM internal "Chapter 2" microinstruction reference (transcribed in full by Corti at the Stuttgart Computer Museum) and SY31-0405-3 Appendix C together document every native PALM opcode with IBM's own mnemonics. The encoding pattern: all instructions are 16-bit halfwords; the top 4 bits select the opcode class; opcode '''0''' is overloaded ā the low 4 bits of byte 0 (the "AM modifier") select one of 16 ALU / move / halfword operations. {| class="wikitable styled-table" style="width:100%;" |+'''IBM Chapter 2 native PALM microinstruction set (SY31-0405-3 Appendix C / IBM Sindelfingen Chapter 2)''' ! Opcode pattern !! IBM mnemonic !! Function |- | '''0xy0ā4''' || '''MVM2 / MVM1 / MVP1 / MVP2 / MOVE''' || Move halfword (with optional pre-decrement / pre-increment of ±1 or ±2 on the source pointer) |- | '''0xy5ā7''' || '''AND / ORB / XOR''' || 8-bit logical operations on the low byte |- | '''0xy8 / 0xy9''' || '''ADD / SUB''' || 8-bit arithmetic with carry / borrow propagation into the high byte |- | '''0xyA / 0xyB''' || '''ADDS1 / ADDS2''' || "Add special" ā multi-byte carry / borrow propagation for synthesised wider arithmetic |- | '''0xyC / 0xyD''' || '''HTL / LTH''' || Byte swap ā High-to-Low / Low-to-High within a register |- | '''0xyE / 0xyF''' || '''GETR / GETA''' || I/O get-to-register; '''GETA''' performs an 8-way priority decode of Bus In bits to add 0 / 2 / 4 / 6 / 8 / A / C / E to the destination ā see ''GETA priority encoder'' below |- | '''1ijj''' || '''CTL''' || I/O control command (sends a control byte to a device) |- | '''2xii / 3xii''' || '''LDHD / STHD''' || Direct halfword load / store ā direct addresses are limited to the first 256 halfwords (the page-0 region) |- | '''4ix?''' || '''PUTB''' || I/O put-byte, with auto-modification of an indirect register if specified |- | '''5xy? / 7xy?''' || '''STHI / STBI''' || Indirect store, halfword / byte (uses Ry as pointer with optional pre/post inc/dec) |- | '''6xy? / Dxy?''' || '''LDBI / LDHI''' || Indirect load, byte / halfword |- | '''8xii''' || '''EMIT''' || Load 8-bit immediate into the low byte of register Rx |- | '''9xii''' || '''CLRI''' || Clear bits via 8-bit mask (logical AND-NOT immediate) |- | '''Axii''' || '''ADDI''' || Add 8-bit immediate '''with implicit +1''' (so ADDI 0x00 adds 1, ADDI 0xFF adds 256) |- | '''Bxii''' || '''SETI''' || Set bits via 8-bit mask (logical OR immediate) |- | '''Cxy?''' || '''JLE / JLO / JEQ / JNO / JALL / JALLM / JNOM / JHAM / JHI / JHE / JHL / JSB / JSN / JSNM / JSM / JHSNM''' || Test-and-skip family. Modifier bits 8āF flip each test to its "skip-on-false" variant. There are no real jumps ā all flow control is built from these conditional skips |- | '''E0x?''' || '''SHFTR / ROTR''' || Shift / rotate the low byte (rotate-by-4 = nibble swap; rotate-by-3, -1 also encodable) |- | '''Eix?''' || '''GETB / GETRB''' || I/O byte fetch / status fetch |- | '''Fxii''' || '''SUBI''' || Subtract 8-bit immediate '''with implicit ā1''' (so SUBI 0x00 subtracts 1) |} === No Hardware Stack, No Conditional Branch === PALM has '''no PUSH / POP, no CALL / RET, no JMP / Bcc''' in its native instruction set. All flow control is built from: * '''Conditional skip''' (opcode group C) ā skips the next halfword if the test passes. * '''Direct write to R0''' (the program counter / IAR) ā by `MOVE R0, Rx`, `LDHI R0, *(Ry)`, or `ADDI R0, imm` / `SUBI R0, imm`. Subroutine calls are an IBM idiom: increment R0 by 2 into a "link register" (any register the programmer designates ā R1 by IBM convention) to capture the return address, then overwrite R0 with the call target. Return is `MOVE R0, R1`. Recursive or nested calls require the programmer to build their own stack in RWS ā there is no hardware stack pointer. This skip-and-write model is uncommon among 1970s ISAs and reflects PALM's strict role as a microcode interpreter rather than a general-purpose programming target. The interpreters running on top of PALM (the System/360 emulator and the System/3 emulator) provide higher-level control flow to their code. === GETA Priority Encoder (8-Way Hardware Dispatch) === The '''GETA''' instruction (opcode `0xyF`) is one of PALM's most distinctive hardware features. GETA performs an 8-way priority decode of the 8 bits on Bus In, mapping the position of the leftmost zero into an addend of 0, 2, 4, 6, 8, A, C, or E (always even), which is then added to the destination register. When the destination register is '''R0''' (the IAR), GETA becomes an '''8-way computed dispatch in a single instruction''' ā the canonical "jump table in hardware" mechanism used throughout the executable ROS to dispatch I/O interrupts and emulated S/360 opcode classes. Without GETA the same dispatch would require a longer skip-chain. === Per-Instruction Timing (SY31-0405-3 Figure 11) === The 5100 MIM Figure 11 (transcribed by Corti from the IBM Sindelfingen archive) gives the per-instruction execution time when fetching from RWS. The bracketed values are the equivalent times when executing out of executable ROS ā '''ROS execution is faster than RWS''' because the storage timing differs. {| class="wikitable styled-table" style="width:100%; text-align:center;" |+'''Native PALM per-instruction execution time (from RWS; bracketed values from ROS)''' ! Instruction !! From RWS !! From ROS |- | MOVE, MVM1, MVM2, MVP1, MVP2 || 3.97 µs || 1.52 µs |- | AND, ORB, XOR, ADD, SUB, ADDS1, ADDS2, HTL, LTH, GETR, GETA || 4.63 µs || 1.72 µs |- | CTL || 2.65 µs || 1.13 µs |- | PUTB || 3.97 µs || 2.05 µs |- | GETB, LDHI, LDBI, STHI, STBI || 4.63 µs || 2.05 µs |- | LDHD, STHD || 3.97 µs || 1.52 µs |- | EMIT || 2.65 µs || 1.13 µs |- | CLRI, ADDI, SUBI, SETI || 3.97 µs || 1.52 µs |- | All jumps (C-group skips) || 5.30 µs || 1.92 µs |- | Shift / rotate (E0xCāF) || 1.72 µs || ā |} ROS execution is 2ā3Ć faster than RWS execution for the same opcodes, which is part of why so much of the executive ROS is structured as monolithic ROS-resident code rather than RWS-loaded routines. === PALM Is Self-Hosting === PALM is sufficiently capable as a programming target that '''it can host its own assembler'''. IBM's GENASM PALM (H. J. Myers, 1977) is a macro-assembler generator that runs on the 5100 itself and produces PALM machine code from PALM assembly source. The full assembler build time from source on a 5100 is reported at approximately 45 minutes. This means that within IBM, PALM was used as a self-hosting development platform for its own microcode ā a notable property for a 1973-era board-level processor. The modern equivalent is '''Alfred Arnold's Macro Assembler AS''' (build 1.42 Bld 231, October 2022), which adds PALM as a target architecture with synthetic pseudo-opcodes ā BRA, RET, CALL, JMP, LWI ā layered over the IBM Chapter 2 mnemonics, giving restorers and emulator developers a modern toolchain for PALM code. === Branching by Skip, Not by Jump === A defining feature of the PALM native instruction set is that '''there are no JUMP, BRANCH or CALL opcodes'''. The opcode group C (Jump/Skip) provides '''conditional skips''' ā instructions that conditionally skip the next instruction. Branching is therefore synthesised in microcode and in software: * '''Short relative jumps''' (±256 bytes) ā ADD or SUB an immediate to R0 (the program counter) under a condition mask. The ADDI / SUBI groups (top nibble A / F) take an 8-bit immediate with an implicit +1 (so ADDI 0 means add 1, ADDI 255 means add 256), giving the ±256-byte range. * '''Long jumps''' ā load R0 with the target address using LDHI or LWI. * '''CALL / RETURN''' ā software convention: push the return address onto a software stack (managed in R1 by convention), then load R0 with the target. RETURN pops and restores R0. This is consistent with the architecture's bias toward implementing higher-level languages in microcode rather than in native code: the native instruction set is deliberately small and orthogonal, and the interpreters above it (APL, BASIC, the S/370 / S/3 emulators) provide the higher-level control flow.
Summary:
Please note that all contributions to RetroTechCollection may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
RetroTechCollection:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Search
Search
Editing
IBM PALM processor
(section)
Add topic