Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > alt.sys.pdp10 > #9946

Re: Fizz Buzz

From Rich Alderson <news@alderson.users.panix.com>
Newsgroups alt.sys.pdp10, alt.lang.asm
Subject Re: Fizz Buzz
Date 2026-07-23 23:19 -0400
Organization PANIX Public Access Internet and UNIX, NYC
Message-ID <mdd33x9cbvq.fsf@panix5.panix.com> (permalink)
References <87wlulwflh.fsf@atr2.ath.cx>

Cross-posted to 2 groups.

Show all headers | View raw


jayjwa <jayjwa@atr2.ath.cx.invalid> writes:

> As I continue on with MACRO-20, I thought I'd share my Fizz Buzz
> solution for TOPS-10 and TOPS-20. I wanted the solution where you stuff
> pointers to const char in a buffer, then dump the buffer once at the end
> but I couldn't get it working with PSOUT% on T20. Maybe it's not
> possible. Oddly, T10 won't take TDNE and branch properly so I had to use
> CAIN instead. This works on TOPS-20 (see code and comments). Both
> systems are KL.

I call bullshit.

TDNE is a hardware instruction.

Tops-10 is software.

There is no way that a hardware instruction is blocked by the operating system.
You did something else wrong.

> T20 can .cont if you HALTF% and JRST START. How can I restart the
> program in a similar fashion on TOPS-10? I only see EXIT instead of
> HALTF%, which doesn't allow .cont restarting.

You don't read manuals very well, do you?  I find the following in the
Monitor Calls Reference manual:

|   22.46  EXIT [CALLI 12]
|
|   FUNCTION
|
|   Stops job execution and optionally resets the job.
|
|   CALLING SEQUENCE
|
|             EXIT    fcn-code,
|             continue return
|
|   In the calling sequence, the program supplies the following variables:
|
|         o  fcn-code is one of the function codes described below.
|
|            For either code, when you EXIT from a job in an auto-pushed
|            context, you are returned to the superior context and the inferior
|            one is deleted.
|
|         o  continue return is the instruction to be executed if the user
|            issues a valid CONTINUE monitor command.

Notice that the description of the EXIT call includes a function code.  What do
you suppose they might mean for the execution of the instruction?  Oh, here we go.

|   The function codes and their meanings are:
|
|   Code      Function
|
|   0         Performs the following:
|
|             o  Releases all I/O devices, closing files if necessary.
|             o  Unlocks the job from core.
|             o  Sets the user-mode write-protect bit for the high segment.
|             o  Resets APR traps to zero.
|             o  Clears PC flags.
|             o  Performs a RESET and stops the job.
|
|            If timesharing was stopped by a TRPSET monitor call, the monitor
|            resumes timesharing.  A RESET monitor call is executed, and the
|            word EXIT is typed on your terminal, and the terminal is left in
|            monitor mode.  You cannot continue with the CONT or CCONT monitor
|            command.

OK, leaving off a function code is equivalent to coding a 0, right?
Moving on...

|   1         Performs the following:
|
|             o  Clears PC flags.
|             o  Stops the job.
|
|            EXIT is not printed on your terminal, and you can continue program
|            execution with the CONT or CCONT monitor command.  If you use
|            function code 1, you should first RELEASE all devices and
|            channels; a convenient way to do this is to use the RESET monitor
|            call.  The symbol for EXIT 1, is MONRT.

Hmm.  That looks like exactly what you want, doesn't it?

|   2-17      Reserved for use by DIGITAL.

Stingy bastards.

> If other alt.lang.asm'ers want to do Fizz Buzz, don't forget to remove
> the pdp10 newsgroup from your reply if it's not about the pdp10.

> .dir fizasm.*
> FIZASM  REL     2  <057>   23-Jul-99    DSKB:   [30,1,DEV]
> FIZASM  EXE     8  <057>   23-Jul-99
> FIZASM  MAC     5  <057>   23-Jul-99
>   Total of 15 blocks in 3 files on DSKB: [30,1,DEV]

> .run fizasm
> 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fiz
> z 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz
>  41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz 
> EXIT

> @vdir fizasm.*
>    DSK1:<PROGRAMMING>
>  FIZASM.EXE.2;P777700       2 1024(36)   22-Jul-2026 21:06:10 JAYJWA    
>    .MAC.87;P676742          2 2781(7)    22-Jul-2026 21:48:11 JAYJWA    
>    .REL.82;P777700          1 166(36)    22-Jul-2026 21:48:15 JAYJWA    

>  Total of 5 pages in 3 files

> @time fizasm
> 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fiz
> z 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz
>  41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz 
>         0.04 real         0.01 user         0.00 sys

> C (KCC) "const char pointers to buffer" version runs about the same.
> @time fizz
> 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fiz
> z 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz
>  41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz 
>         0.04 real         0.01 user         0.00 sys

comment $
Fizz Buzz for PDP-10 TOPS-10
For 1..N, check if each integer is evenly divisible by 3, if so, print
"Fizz". If by 5, print "Buzz". If by both print "FizzBuzz". If neither,
print the bare number.
$
|         title   fizasm
|         search  monsym,macsym
|         STDAC.                                  ; Labels accums for us
| 
|         size==62                                ; Number of terms to see (50)
|                                                 ; Only <= 99 is supported
| fizz:   asciz   /Fizz /                         ; Tag for N mod 3 == 0
| buzz:   asciz   /Buzz /                         ; Tag for N mod 5 == 0
| fzbz:   asciz   /FizzBuzz /                     ; Tag for N mod 15 == 0
| flags:  0
| crlf:   15B6+12B13                              ; Bit-pack a \r\n

OK, usually we allow the assembler to do the work:

  CRLF:   BYTE(7) 15,12f

or

  CRLF:   ASCIZ/
  /

|         subttl  Main
| start:  setz    cx,                             ; Zero counter for loop
| st.1:   addi    cx,1                            ; Examine next number
| chk15:  move    q1,cx                           ; Number to examine in Q1
|         idivi   q1,17                           ; Div by 15, rem in ac+1
|         jumpn   q2,chk3                         ; N mod 15 != 0, don't print
|         movei   q3,1                            ; Set bit 35 to indicate that
|         iorm    q3,flags                        ; we've output a word

Can FLAGS have a value other than 0 or 1?  A much better solution in that case
is to use 0 and -1, and the SETO/SETZ instructions.  Here, use

          SETOM   FLAGS

|         outstr  fzbz                            ; T10 has OUTSTR, not PSOUT%
|         jumpa   chkn.1                          ; to output string to TTY
| 
| chk3:   move    q1,cx                           ; Re-get number to examine, Q1
|         idivi   q1,3                            ; Divide by 3, remainder ac+1
|         jumpn   q2,chk5                         ; N mod 3 != 0, don't print
|         movei   q3,1                            ; Set bit 35 to indicate that
|         iorm    q3,flags                        ; we've output a word already
	  SETOM   FLAGS
|         outstr  fizz                            ; Output fizz tag to TTY
| 
| chk5:   move    q1,cx                           ; Reload number because IDIVI
|         idivi   q1,5                            ; in CHK3 blanked it
|         jumpn   q2,chknum                       ; N mod 5 != 0, don't print
|         movei   q3,1                            ; Ready flags setting
|         iorm    q3,flags                        ; Set bit 35, indicating we
	  SETOM   FLAGS
|         outstr  buzz                            ; printed a tag to TTY
|         jumpa   chkn.1                          ; Printed at least one tag so
|                                                 ; skip printing num itself
| chknum: move    q3,flags                        ; Examine flags
| ; TOPS-10 won't work correctly with TDNE Q3,1 unlike on TOPS-20. Use CAIN
| ; instead to avoid printing a tag and its number. No idea why this is.
|         cain    q3,1                            ; If anything set this then
|           jrst  chkn.1                          ; skip printing the bare num

Well, of course TDNE does not work here.  READ THE HARDWARE MANUAL.

The Test Direct instructions compare the contents of the AC to THE CONTENTS OF
THE EFFECTIVE ADDRESS, not to the immediate value in the instruction, unlike
all the other Test instructions.  What you are saying in TDNE Q3,1 is that the
processor should bitwise compare the value you've loaded into Q3 WITH THE VALUE
CURRENTLY IN AC 1.  What would have worked is TDNE Q3,[1] with a literal
containing the value 1.

But even better is using the -1/0 trick from above, and coding

	  SKIPN   FLAGS
	   JRST   CHKN.1

|         move    q1,cx                           ; Fetch number to convert
|         jsr     numout                          ; Print bare num

Worst possible subroutine call choice you can make.  It's the 1980s, for crying
out loud--use a stack and PUSHJ/POPJ.

| chkn.1: setzm   flags                           ; Reset flags to zero
|         caige   cx,size                         ; More numbers to check?
|           jrst  st.1                            ; Yes (increment above)
|         outstr  crlf                            ; No, done, tidy output
|         exit

And as you've now learned, this should be

	  EXIT 1,
or even better
	  MONRT

|         jrst    start                           ; Does restart work on T10?


|         subttl  Number Out Subroutine
| ; TOPS-10 has no NOUT% like TOPS-20 does, so convert the system number
| ; by hand to ASCII printing characters for display on the TTY. Only 
| ; supports up to double-digit numbers.
| ; Input: Q1 (Q1, Q2 could be overwritten)
| ; Output: Prints ASCII char(s) equal to the number to the TTY
| numout: 0                                       ; Save return address spc
|         idivi   q1,12                           ; Convert to printable char
|         addi    q1,60                           ; In first position
|         caie    q1,60                           ; Don't print leading zero
|           outchr q1                             ; Print first character
|         addi    q2,60                           ; Convert second char
|         outchr  q2                              ; And print to TTY
|         outchr  [.CHSPC]                        ; Emit space character
|         jrst    @numout                         ; Return to caller

<hrrk!>

|         lit                                     ; Debugger to expand literals
|         end     start                           ; Assembler is done


| And the TOPS-20 version:
| comment $
| Fizz Buzz for PDP-10 TOPS-20
| For 1..N, check if each integer is evenly divisible by 3, if so, print
| "Fizz". If by 5, print "Buzz". If by both print "FizzBuzz". If neither,
| print the bare number.
| $
|         title   fizasm
|         search  monsym,macsym
|         STDAC.                                  ; Labels accums for us
|                                                 ; cx = iterator for loopage
| ; Set number of terms you want, in octal. Currently 50 decimal
|         size==62                                ; How far to go with this
| fizz:   asciz   /Fizz /                         ; Tag for N mod 3 == 0
| buzz:   asciz   /Buzz /                         ; Tag for N mod 5 == 0
| fzbz:   asciz   /FizzBuzz /                     ; Tag for N mod 15 == 0
| flags:  0                                       ; Bit 35 set if word output
| crlf:   15B6+12B13                              ; Bit-pack a \r\n

See above.

| start:  setz    cx,                             ; Zero counter for loop
| st.1:   addi    cx,1                            ; Examine next number
| chk15:  move    q1,cx                           ; The number to examine in Q1
|         idivi   q1,17                           ; Div by 15, rem in ac+1
|         jumpn   q2,chk3                         ; N mod 15 != 0, don't print
|         movei   q3,1                            ; Set bit 35 to indicate that
|         iorm    q3,flags                        ; we've output a word

See above.

|         hrroi   t1,fzbz                         ; Output fzbz tag to TTY
|         psout%
|         jumpa   chkn.1                          ; No more printing now

It is preferable always to use JRST rather than JUMPA, because the latter
invokes the comparison hardware even when the intent is to branch unconditionally.

| chk3:   move    q1,cx                           ; Re-get number to examine, Q1
|         idivi   q1,3                            ; Divide by 3, remainder ac+1
|         jumpn   q2,chk5                         ; N mod 3 != 0, don't print
|         movei   q3,1                            ; Set bit 35 to indicate that
|         iorm    q3,flags                        ; we've output a word

See above.

|         hrroi   t1,fizz
|         psout%                                  ; Output fizz tag to TTY
| 
| chk5:   move    q1,cx                           ; Reload number because IDIVI
|         idivi   q1,5                            ; in CHK3 blanked it
|         jumpn   q2,chknum                       ; N mod 5 != 0, don't print
|         movei   q3,1
|         iorm    q3,flags                        ; Set bit 35, indicate we

See above.

|         hrroi   t1,buzz                         ; printed a tag
|         psout%                                  ; Output buzz tag to TTY
|         jumpa   chkn.1                          ; Printed at least one tag, so
|                                                 ; skip printing the num itself
| chknum: move    q3,flags                        ; Examine flags
|         tdne    q3,^B1                          ; If anything set this then
|           jrst  chkn.1                          ; skip printing the bare num

OK, I refuse to believe that this worked, just because you declared that the
integer 1 was a binary value.  Something in AC 1 was ACCIDENTALLY of a shape to
work.  Singlestep it in DDT and look at the values in T1 and Q3.

And the same thing is still true as above in the Tops-10 version.  Use SKIPE/SKIPN
and the 0/-1 values.

|         move    t1,[.priou]                     ; Else print bare number

Usually MOVEI T1,.PRIOU

|         move    t2,cx                           ; Ready NOUT%'s num
|         movei   t3,12                           ; Base is decimal
|         nout%                                   ; Print num to TTY
|           erjmp [hrroi t1,[asciz /IO error on NOUT%. Exiting./]
|                  psout%
|                  haltf%]                        ; Error? Can't continue, exit
|         move    t1,[point 7,[asciz / /]]        ; Emit space char, tidy output
|         psout%
| 
| chkn.1: setzm   flags                           ; Reset flags to zero
|         caige   cx,size                         ; More numbers to check?
|           jrst  st.1                            ; Yes (increment above)
|         hrroi   t1,crlf                         ; No, done, tidy output
|         psout%                                  ; with a \r\n
|         haltf%                                  ; Exit to monitor
|         jrst    start                           ; Want to see that again?
| 
|         lit                                     ; DDT to expand literals
|         end     start                           ; Assembler is done

It's nice tht you want to teach folks PDP-10 assembler programming, but don't
you think you should do that when you know what you're doing?

                                                                Rich

-- 
Rich Alderson					  news@alderson.users.panix.com
      Audendum est, et veritas investiganda; quam etiamsi non assequamur,
	  omnino tamen proprius, quam nunc sumus, ad eam perveniemus.
									--Galen

Back to alt.sys.pdp10 | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Fizz Buzz jayjwa <jayjwa@atr2.ath.cx.invalid> - 2026-07-23 17:39 -0400
  Re: Fizz Buzz Rich Alderson <news@alderson.users.panix.com> - 2026-07-23 23:19 -0400
    Re: Fizz Buzz jayjwa <jayjwa@atr2.ath.cx.invalid> - 2026-07-25 12:00 -0400
      Re: Fizz Buzz Rich Alderson <news@alderson.users.panix.com> - 2026-07-25 18:05 -0400
        Re: Fizz Buzz jayjwa <jayjwa@atr2.ath.cx.invalid> - 2026-07-26 11:12 -0400
      Accumulator naming Rich Alderson <news@alderson.users.panix.com> - 2026-07-29 18:10 -0400
        Re: Accumulator naming scott@slp53.sl.home (Scott Lurndal) - 2026-07-30 15:14 +0000
          Re: old architectures, was Accumulator naming John Levine <johnl@taugh.com> - 2026-07-30 20:40 +0000
          Re: Accumulator naming Rich Alderson <news@alderson.users.panix.com> - 2026-07-30 18:41 -0400
        Re: Accumulator naming jayjwa <jayjwa@atr2.ath.cx.invalid> - 2026-07-30 11:24 -0400
          Re: Accumulator naming scott@slp53.sl.home (Scott Lurndal) - 2026-07-30 16:03 +0000
          Re: Accumulator naming Rich Alderson <news@alderson.users.panix.com> - 2026-07-30 18:56 -0400
            Re: Accumulator naming cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-30 23:48 +0000
              Re: Accumulator naming John Levine <johnl@taugh.com> - 2026-07-31 01:31 +0000
                Re: Accumulator naming cross@spitfire.i.gajendra.net (Dan Cross) - 2026-07-31 02:52 +0000
                Re: Accumulator naming John Levine <johnl@taugh.com> - 2026-07-31 03:36 +0000
                Re: Accumulator naming Lars Brinkhoff <lars.spam@nocrew.org> - 2026-07-31 13:40 +0000
          Re: Accumulator naming Lars Brinkhoff <lars.spam@nocrew.org> - 2026-07-31 13:35 +0000
          the Ten Heavenly Stems (was Re: Accumulator naming) Kragen Javier Sitaker <kragen@canonical.org> - 2026-09-11 16:07 -0300
            Re: the Ten Heavenly Stems (was Re: Accumulator naming) Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-09-14 01:12 +0800
              Re: the Ten Heavenly Stems (was Re: Accumulator naming) Kragen Javier Sitaker <kragen@canonical.org> - 2026-09-14 14:40 -0300
                Re: the Ten Heavenly Stems (was Re: Accumulator naming) scott@slp53.sl.home (Scott Lurndal) - 2026-09-14 18:09 +0000
                Re: the Ten Heavenly Stems (was Re: Accumulator naming) quadibloc@invalid.com (John Savard) - 2026-10-26 03:00 +0000
  Re: Fizz Buzz "Kerr-Mudd, John" <admin@127.0.0.1> - 2026-08-21 13:27 +0100

csiph-web