[ This document is in wiki markup ] === Hello, world === This is a minimal programming example in Nova assembly language. It is designed to run under [[RDOS]] and prints the string "[[Hello_world|Hello, world]]." on the console. ; a "hello, world" program for Nova running RDOS, by Toby Thain ; uses PCHAR system call .titl hello .nrel .ent start start: dochar: lda 0,@pmsg ; load ac0 with next character, mov# 0,0,snr ; test ac0; skip if nonzero (don't load result) jmp done .systm .pchar ; print first jmp er ; skipped if OK movs 0,0 ; swap bytes .systm .pchar ; print second jmp er ; skipped if OK isz pmsg ; point to next word jmp dochar ; go around again done: .systm ; normal exit .rtn er: .systm ; error exit .ertn halt pmsg: .+1 ; pointer to first word of string ; note bytes are packed right-to-left by default .txt /Hello, world.<15><12>/ ; that's CR LF 0 ; flag word to end string .end start === 16-bit multiply === Some models of the Nova lacked hardware multiply and divide. Here is a routine to multiply two 16-bit words to produce a 16-bit word result (overflow is ignored). It demonstrates combined use of ALU op, shift, and test (skip). Note that when this routine is called by jsr, AC3 holds the return address. This is used by the return instruction jmp 0,3. An idiomatic way to clear an accumulator is sub 0,0. Other single instructions can be arranged to load a specific set of useful constants (e.g. -2, -1, or +1). mpy: ; multiply AC0 <- AC1 * AC2, by Toby Thain sub 0,0 ; clear result mbit: movzr 1,1,szc ; shift multiplier, test lsb add 2,0 ; 1: add multiplicand movzl 2,2,szr ; shift and test for zero jmp mbit ; not zero, do another bit jmp 0,3 ; return === Print accumulator in binary === The following routine prints the value of AC1 as a 16 digit binary number, on the RDOS console. It reveals further quirks of the Nova instruction set. For instance, there is no instruction to load an arbitrary "immediate" value into an accumulator (although memory reference instructions do encode such a value to form an effective address). Accumulators must generally be loaded from initialised memory locations (e.g. n16). Other contemporary machines such as the [[PDP-11]], and practically all modern architectures, allow for immediate loads. Because AC3 is not preserved by the RDOS .systm call, a temporary location is needed to preserve the return address. (For a recursive or otherwise re-entrant routine, the stack must be used instead.) The return instruction becomes jmp @ retrn which exploits the Nova's indirect addressing mode to load the return PC. The constant definitions at the end show two assembler features: the assembler radix is octal by default (20 = sixteen), and character constants could be encoded as e.g. "0. pbin: ; print AC1 on console as 16 binary digits, by Toby Thain sta 3,retrn ; save return addr lda 2,n16 ; set up bit counter loop: lda 0,chr0 ; load ASCII '0' movzl 1,1,szc ; get next bit in carry inc 0,0 ; bump to '1' .systm .pchar ; AC0-2 preserved jmp err ; if error inc 2,2,szr ; bump counter jmp loop ; loop again if not zero lda 0,spc ; output a space .systm .pchar jmp err ; if error jmp @ retrn spc: " ;that's a space chr0: "0 n16: -20 retrn: 0 === Using simh to emulate a Nova === Nova assembly language programs can be run under Bob Supnik's [http://simh.trailing-edge.com/ simh] emulator, in RDOS. Of the above examples, only ''Hello, world'' is a complete program. It includes the necessary directives for a successful assembly and runnable program. Start the Nova emulation and boot RDOS following the instructions under ''Nova and Eclipse RDOS'' in file src/simh_swre.txt in the simh distribution. The command prompt is R. The first step is to create the assembly source file under RDOS. The xfer command will accept input at the console and copy it to a disk file named test.sr. After entering the command above, copy and paste or type in a complete assembly language program, and finish with ''control''-Z: xfer/a $tti test.sr Next, run the '''macro assembler''' on test.sr to create the object file test.rb; the /l (slash-ell) option enables the listing file, test.lst. The listing can be copied to the console using the command type test.lst mac/l test The '''relocatable loader,''' rldr, takes the object file and creates the executable test.sv: rldr test Now run it: test Good luck! If you plan to do much experimentation, it can be convenient to check your program using a compatible cross-assembler such as [http://www.telegraphics.com.au/sw/#dpa dpa] before taking it to the RDOS environment.