Today marks a significant milestone for the GMS/359 project: we have started the asm359 project, a standalone assembler with a fully functional macro preprocessor.
What is asm359?
It's an assembler for GMS/359 — my FPGA-based computing system inspired by IBM System/360. The key word is inspired: GMS/359 deliberately breaks compatibility with the original architecture to create something cleaner and more modern.
The Preprocessor
The heart of asm359 is its NASM-style macro preprocessor. Over ~4500 lines of carefully modularized C code, it supports:
- Single-line macros:
%define,%xdefine,%idefine - Multi-line macros:
%macro/%endmacrowith parameters - Conditional assembly:
%if,%ifdef,%ifndef,%elif,%else - Repeat blocks:
%rep/%endrep - String operations:
%strlen,%strcat,%substr - Context stack:
%push,%popwith local macros - File inclusion:
%includewith search paths
The code is organized into clean, focused modules:
pp_token.c — Tokenizer
pp_macro.c — Macro storage and lookup
pp_expand.c — Macro expansion engine
pp_directive.c — Directive dispatcher
pp_context.c — Context and state management
pp_main.c — Public interface
Design Philosophy: Not Your Father's S/360
While implementing the assembler syntax, I crystallized the GMS/359 design principles:
| IBM System/360 | GMS/359 |
|---|---|
| Big-endian | Little-endian |
| Opcode last in instruction | Opcode first |
| Source, Destination in ST | Destination first (always) |
| Base+Displacement addressing | PC-relative / Direct |
BALR R12,0 + USING *,R12 |
Not needed! |
That last point deserves explanation. In S/360, there was no way to read the program counter directly. Programs had to use BALR Rx,R0 to capture the current address into a register, then tell the assembler about it with USING. This was necessary because all memory references were encoded as base register + 12-bit displacement.
GMS/359 doesn't have this limitation. With PC-relative or direct 24-bit addressing, the assembler handles address resolution automatically. No more base register juggling!
Assembly Syntax
The syntax follows modern conventions:
; Destination first, like x86/ARM/RISC-V
LR R5,R6 ; R5 ← R6
ST [BUFFER],R3 ; memory ← R3
; Square brackets for memory references
LA R2,[MSG] ; Load address of MSG
; Hex suffix, no leading zero required
%define CONSOLE 10h
; NASM-style data directives
DB 01h ; Define Byte
DW 1234h ; Define Word (2 bytes)
DD value ; Define Doubleword (4 bytes)
DQ value ; Define Quadword (8 bytes)
What's Next?
The preprocessor is complete. Next steps:
- Instruction encoding — RR, RX, RS, SI, SS formats
- Symbol table — Labels and forward references
- Output generation — Raw binary for now, maybe RDOFF later
- Integration — Feed directly to GMS/359 via IPL
The Bigger Picture
asm359 is part of a larger vision: a complete, self-consistent computing system that takes the best ideas from 1960s mainframe architecture and implements them with modern sensibilities. Channel I/O? Yes. Big-endian byte swapping headaches? No thank you.
The GMS 2050 CPU, GMS 2870 Multiplexor Channel, and GMS 2291 Video Controller are already running on my Cologne Chip GateMate FPGA. Soon they'll be executing code written in asm359.
No comments:
Post a Comment