diff --git a/_posts/2017-03-21-the-macro-10-assembler-50-years-later.md b/_posts/2017-03-21-the-macro-10-assembler-50-years-later.md index 5708998d2..fcc2cd23c 100644 --- a/_posts/2017-03-21-the-macro-10-assembler-50-years-later.md +++ b/_posts/2017-03-21-the-macro-10-assembler-50-years-later.md @@ -21,7 +21,7 @@ falls into these categories: Floating-point is the biggest chunk of work, which I'm going to save for last, with the hope that most PDP-10 software didn't use floating-point. However, if all PDP-10 systems included floating-point hardware (which I haven't been able to -confirm yet), I may have no choice. Floating-point emulation in JavaScript isn't hard -- PCjs already includes an +confirm yet), I may have no choice. Floating-point emulation in JavaScript isn't hard -- PCjs already includes [8087 Coprocessor Emulation](/modules/pcx86/lib/x86fpu.js) -- but getting all the details right is time-consuming. The PDP-10 has a lot of instructions, and I quickly had far more instructions than I was willing or able to write tests for. @@ -57,10 +57,10 @@ The Debugger invokes the MACRO-10 mini-assembler whenever the argument following As previously described in the section on [PDPjs PDP-10 Opcode Tests](/apps/pdp10/tests/opcodes/), the Debugger already allowed you to assemble instructions directly into memory (eg, `a 100 hrli 1,111111`). This "immediate mode" feature is provided -exclusively by the Debugger; MACRO-10 mini-assembler features are not available in that mode. +exclusively by the Debugger; MACRO-10 features are not available in that mode. However, one feature that *is* available in both the Debugger and the mini-assembler is full MACRO-10-style expression evaluation, -since they share the same expression parser. Here are some examples, using the Debugger's 'print' command: +since they share the same expression parser. Here are some examples, using the Debugger's "print" command: >> print 27 23. 0o000027 @@ -100,10 +100,26 @@ so: >> print 5K 0o000000005000 2560. + >> print 5M + 0o000005000000 1310720. + + >> print 5G + 0o005000000000 671088640. + >> print ^D5K 0o000000011610 5000. + + >> print ^D5M + 0o000023045500 5000000. + + >> print ^D5G + 0o045201371000 5000000000. -Binary shifting using a B suffix is also supported: +Binary shifting using a **B** suffix is also supported. Note that MACRO-10 binary shifting is a "bit" unusual by today's +standards, because the value after the **B**, *n*, is not a count but rather the desired bit position of the right-most bit of +the original value. Moreover, MACRO-10 considers bit 0 the left-most bit, and bit 35 the right-most bit. Last but not least, +*n* is always interpreted as a decimal value, regardless of the current base (radix). *n* can be converted to a shift count +by calculating (35 - n): if the count is positive, it's a left-shift, and if it's negative, it's a right-shift. >> print 1B0 0o400000000000 -34359738368. @@ -123,8 +139,8 @@ Binary shifting using a B suffix is also supported: >> print -1B70 0o000000000001 1. -And as the MACRO-10 ASSEMBLER PROGRAMMER'S REFERENCE MANUAL (June 1972), p. 1-17, points out, all the following expressions are -equivalent: +And as the [MACRO-10 Assembler Programmer's Reference Manual (June 1972)](http://archive.pcjs.org/pubs/dec/pdp10/tops10/Macro_Assembler_Reference_Manual-Jun72.pdf), +p. 1-17, points out, all the following expressions are equivalent: >> print 10B32 0o000000000100 64. '@' @@ -142,7 +158,8 @@ equivalent: 0o000000000100 64. '@' "Left arrow" shifting is also supported, although the character that the original MACRO-10 manuals referred to as a "left arrow" -is actually an underscore; later manuals refer to this as "underscore shifting": +is actually an underscore; later manuals refer to this as "underscore shifting". Underscore shifting uses straightforward shift +counts: if the count is positive, it's a left-shift, and if it's negative, it's a right-shift. >> print 1_^D18 0o000001000000 262144. @@ -150,8 +167,12 @@ is actually an underscore; later manuals refer to this as "underscore shifting": >> print -1_^D-18 0o000000777777 262143. -Character-based constants are also supported, in the both 7-bit ASCII the 6-bit SIXBIT formats. Use double-quotes -for 7-bit right-justified character constants and single-quotes for 6-bit right-justified character constants: +Character constants are also supported, in both the 7-bit ASCII and 6-bit SIXBIT formats. If more than 5 7-bit characters +or more than 6 6-bit characters are specified, an error will be reported, since the value cannot fit in a 36-bit word. The +character values will be stored in the same order that they are listed, but unlike values generated by MACRO-10 pseudo-ops +**ASCII**, **ASCIZ**, and **SIXBIT**, the final value will be right-justified instead of left-justified. + +Use double-quotes for ASCII constants and single-quotes for SIXBIT constants: >> print +'SIXBIT' 0o635170425164 -13255955852. @@ -159,20 +180,27 @@ for 7-bit right-justified character constants and single-quotes for 6-bit right- >> print +"HELLO" 0o221054623117 19473311311. -NOTE: When using the PCjs debugger, the constant must be preceded by an arithmetic operator, otherwise it interprets the -quoted argument as a string. This is an idiosyncrasy of the "print" command, not the expression parser. +NOTE: When using the PCjs debugger, the constant must be preceded by an arithmetic operator (eg, '+'), otherwise it interprets +the quoted argument as a string. This is an idiosyncrasy of the "print" command, not the expression parser. -All MACRO-10 logical and arithmetic operators are supported, including: +Most MACRO-10 logical and arithmetic operators are supported, including: - Unary arithmetic operators (+ and -) - Unary complement operator (^-, aliased to ~) - Unary base overrides (^D, ^O, and ^B) +- Unary zero-bit-count operator (^L) - Binary shifting (B) and underscore shifting (_) operators - Logical binary operations (! for OR, ^! for XOR, and & for AND) - Multiplication and division (* and /) - Addition and subtraction (+ and -) - Angle brackets for expression grouping (< and >) +Unfortunately, since the PCjs expression parser predates MACRO-10 support, there are bound to be differences that I +haven't ironed out yet. One known difference involves numeric constants with a trailing period (decimal point): PCjs +historically treats such constants as decimal *integers*, whereas MACRO-10 treats numeric constants with either a +leading, embedded, or trailing period as a decimal *floating-point* number. I've chosen to ignore this difference for +now, since I'm holding off on all floating-point support for as long as possible. + Much more work is needed to make the MACRO-10 "Mini-Assembler" a general-purpose assembler, but it's already proved itself useful in assembling the following tests: