diff --git a/.go-version b/.go-version index bae5c7f..20a1265 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.21.3 +1.21.4 diff --git a/docs/DEVGUIDE.txt b/docs/DEVGUIDE.txt index d28649d..0e2d8b2 100644 --- a/docs/DEVGUIDE.txt +++ b/docs/DEVGUIDE.txt @@ -51,10 +51,10 @@ ELSIE has the following dependencies: - optionally, golangci-lint to check Go coding style. As a learning tool, ELSIE has a design goal that its development should simple -and easy. To that end, dependencies are restricted to only tools, packages, and +and easy. To that end, dependencies are restricted to tools, packages, and methods that are supported by the Go Development Team. This includes Go and its -standard library, of course, but also includes modules in the "golang.org/x" -namespace, modules for dependency management, and simple text file formats. +standard library, of course, but also modules in the "golang.org/x" namespace, +using modules for dependency management, and simple text file formats. Each design decision that introduces a dependency adds complexity, limits portability, and requires another skill or trivial knowledge from future @@ -63,9 +63,7 @@ makes things unexpectedly more difficult over longer time scales. So, we limit ourselves to essential tools only. Notably, this excludes some very common and standard tools like make, shell and YAML. -Go is not perfect, nor are its developer's or corporate sponsors infallible; far -from it in fact. However, by acknowledging its flaws and yet embracing -minimalism and Normhaus design, we make space for essential understanding and -creativity to form and we build things that have a better chance of standing the -tests of time. So long as Go is maintained, we can expect some motivated people -to be able to fix its problems. +My acknowledging its flaws and embracing minimalism and Normhaus design, we make +space for essential understanding and creativity to form and we build things +that have a better chance of standing the tests of time. So long as Go is +maintained, we can expect some motivated people to be able to fix its problems. diff --git a/docs/README.txt b/docs/README.txt index 6c9e2f4..555f276 100644 --- a/docs/README.txt +++ b/docs/README.txt @@ -1,25 +1,26 @@ - ELSIE: A Pedagogical LC-3 Emulator + π”Όπ•ƒπ•Šπ•€π”Ό: A Pedagogical LC-3 Emulator ================================================================================ The path is made in the walking of it. -- Zhuangzi -This is ELSIE, an exploration of the LC-3: a little computer that is simple, -comprehensive, and imaginary. +This is π”Όπ•ƒπ•Šπ•€π”Ό, an exploration of the LC-3: a little computer that is simple and +imaginary. The project includes: - - a virtual machine, that executes instructions; - - an assembler, for translating from LCASM source to machine code; - - a loader, that puts programs into memory; - - a system monitor or BIOS, that implements system calls; - - virtual devices for display and keyboard I/O; + - a virtual machine that executes instructions; + - an assembler for translating LCASM source to machine code; + - a loader that puts programs into memory; + - a system monitor that implements system calls; + - virtual devices for display and keyboard I/O; - many unnecessary words by your author; and - maybe, more to come… -As a technical project, ELSIE is not useful: it isn't complete and it doesn't -work. In those terms, it is not good software. To the author, however, ELSIE -feels more like a story, a performance, or maybe even a convalescence. As such, -it is software useful for more than mere utility and is essential. +As a technical project, π”Όπ•ƒπ•Šπ•€π”Ό is not useful: it isn't complete and it doesn't +work. In those terms, it is not good software. However, to the author, the +project is not intended to be solely utilitarian -- it is also a story, a +performance, or maybe even a trail through a cozy wood. As such, it is software +that is essential and invaluable. ----------------------------- Background @@ -41,12 +42,11 @@ The LC-3 instruction set and architecture includes: - an instruction set compact enough to fit on a single page. Far from an abstract machine, the text begins with transistors and digital -logic. From there, it builds upon the titular bits and bytes and describes in -detail the entire computer architecture including the control-unit -state-machine, data and I/O paths. It is fascinating. As far as I know, a -complete implementation has never been physically built but, I can imagine, the -text will be invaluable when humanity has to recreate computers from first -principles. +logic. From there, it builds upon the titular bits and bytes and describes an +entire computer architecture in detail including the control-unit state-machine, +data and I/O paths. It is fascinating. As far as I know, a complete +implementation has never been physically built but, I can imagine, the text will +be invaluable when humanity has to recreate computers from first principles. While similar in many respects to the x86 or ARM ISAs, the LC-3 is radically simpler in almost every way. Unlike the sprawling x86, with thousands of @@ -62,7 +62,7 @@ enough to write programs. Project Goals ----------------------------- -ELSIE is not novel: hardware simulators already exist for the LC-3 architecture, +π”Όπ•ƒπ•Šπ•€π”Ό is not novel: hardware simulators already exist for the LC-3 architecture, of course. The textbook publishers provide one and there are many others freely available online.[1] This one is admittedly a mere reinvention of the wheel. That said, the gift the design and engineering process affords is that sometimes @@ -136,6 +136,6 @@ This work is dedicated to the MCM/70[2] and its pioneering designers. ----------------------------- -ELSIE Β© 2023 by Scott Moynes is licensed under CC BY-SA 4.0. +π”Όπ•ƒπ•Šπ•€π”Ό Β© 2023 by Scott Moynes is licensed under CC BY-SA 4.0. See LICENCE.txt for terms. Send your lawyers here: https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1 diff --git a/docs/TUTORIAL.md b/docs/TUTORIAL.md index 22c583a..39e8270 100644 --- a/docs/TUTORIAL.md +++ b/docs/TUTORIAL.md @@ -1,25 +1,31 @@ # Tutorial: Building and Running Programs # -In this tutorial you will learn more about: +In this tutorial you will learn how to: - - installing ELSIE; - - writing simple machine code programs and executing them; - - building a few more complicated programs in assembly language. + - install ELSIE; + - executing a hard-coded demo. + - running a simple program; + - translate a program from LC3ASM assembly language to machine language; + - run the resulting program. ## Installing ELSIE ## -- You will need Go version 1.21, or greater, installed. -- Visit the Go download page: https://go.dev/dl/ +You will need Go version 1.21, or greater, installed: + +- Visit the Go download page: https://go.dev/dl/; - Install a version greater than 1.21. -You can check if you have a good version, run: +Alternatively, you might be able to use a package manager for your platform to +install a compatibly Go version. + +You can check if you have a good version; Run: ```console $ go version -go version go1.21.1 darwin/amd64 +go version go1.21.4 darwin/amd64 ``` -Finally, you can now download, build, and install ELSIE. Run: +With Go installed, you can now download, build, and install ELSIE. Run: ```console $ go install github.com/smoynes/elsie @@ -30,116 +36,107 @@ Say hello: ```console $ elsie -ELSIE is a virtual machine for the LC-3 educational computer. +ELSIE is a virtual machine and programming tool for the LC-3 educational computer. Usage: elsie [option]... [arg]... Commands: - demo run demo program + exec run a program asm assemble source code into object code + demo run demo program help display help for commands Use `elsie help ` to get help for a command. +exit status 1 ``` ## Running the demo ## -ELSIE includes a silly demo. Run it: +ELSIE includes a silly, hard-coded demo. You can run it with the demo command. +You should see a few characters printed. This is what success looks like: ```console $ elsie demo +⍀⍀ ``` -You should see a bunch of debug output spammed to your terminal. Do not be -alarmed. You should see towards the end of the output a message that the `Demo -completed`. That is what success looks like: +It's not much but it's an honest program. The demo initialize the machine, does +some basic I/O with system calls, and halts the machine. It is not much, but it +is an honest program. + +You can also run the demo with additional logging enabled. You will see logs for +machine startup and its state after executing each instruction. ```console - TIMESTAMP : 2023-10-10T23:00:50-04:00 +$ elsie demo -log + TIMESTAMP : 2023-11-10T22:11:56.720592-05:00 LEVEL : INFO - SOURCE : exec.go:39 - FUNCTION : vm.(*LC3).Run - MESSAGE : HALTED (HCF) - STATE : - VM : - PC : 0x1003 - IR : 0x7040 (OP: STR) - PSR : 0x0002 (N:false Z:true P:false PR:0 PL:0) - USP : 0xfe00 - SSP : 0x3000 - MCR : 0x0000 (STOP) - MAR : 0xfffe - MDR : 0x0000 - INT : - PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2362)} - REG : - R0 : 0x0000 - R1 : 0xfffe - R2 : 0xfff0 - R3 : 0xf000 - R4 : 0xff00 - R5 : 0x0f00 - R6 : 0xfdfe - R7 : 0x00f0 + SOURCE : demo.go:73 + FUNCTION : cmd.demo.Run + MESSAGE : Initializing machine + + TIMESTAMP : 2023-11-10T22:11:56.721381-05:00 + LEVEL : INFO + SOURCE : demo.go:84 + FUNCTION : cmd.demo.Run +... -TIMESTAMP : 2023-10-10T23:00:50-04:00 + TIMESTAMP : 2023-11-10T22:12:10.90828-05:00 LEVEL : INFO - SOURCE : demo.go:132 + SOURCE : demo.go:147 FUNCTION : cmd.demo.Run MESSAGE : Demo completed ``` -
+
Full output… ```console -$ elsie demo - TIMESTAMP : 2023-10-11T10:25:48-04:00 +$ elsie demo -log + TIMESTAMP : 2023-11-10T22:12:48.711731-05:00 LEVEL : INFO - SOURCE : demo.go:57 + SOURCE : demo.go:73 FUNCTION : cmd.demo.Run MESSAGE : Initializing machine - TIMESTAMP : 2023-10-11T10:25:48-04:00 - LEVEL : INFO - SOURCE : demo.go:60 - FUNCTION : cmd.demo.Run - MESSAGE : Loading trap handlers - - TIMESTAMP : 2023-10-11T10:25:48-04:00 + TIMESTAMP : 2023-11-10T22:12:48.712469-05:00 LEVEL : INFO - SOURCE : demo.go:113 + SOURCE : demo.go:84 FUNCTION : cmd.demo.Run MESSAGE : Loading program - TIMESTAMP : 2023-10-11T10:25:48-04:00 + TIMESTAMP : 2023-11-10T22:12:48.712496-05:00 LEVEL : INFO - SOURCE : demo.go:125 - FUNCTION : cmd.demo.Run + SOURCE : demo.go:128 + FUNCTION : cmd.demo.Run.func4 MESSAGE : Starting machine - TIMESTAMP : 2023-10-11T10:25:48-04:00 + TIMESTAMP : 2023-11-10T22:12:48.71252-05:00 LEVEL : INFO - SOURCE : exec.go:17 + SOURCE : exec.go:20 FUNCTION : vm.(*LC3).Run MESSAGE : START STATE : - VM : + !BADKEY : PC : 0x3000 IR : 0x0000 (OP: BR) - PSR : 0x0007 (N:true Z:true P:true PR:0 PL:0) + PSR : 0x0300 (N:false Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3000 - MDR : 0xf025 + MAR : 0xffff + MDR : 0x0ff0 + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff + R0 : 0x2364 R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 @@ -148,34 +145,35 @@ $ elsie demo R6 : 0xfe00 R7 : 0x00f0 - TIMESTAMP : 2023-10-11T10:25:48-04:00 - LEVEL : ERROR - SOURCE : exec.go:105 - FUNCTION : vm.(*LC3).Step - MESSAGE : instruction raised interrupt - OP : TRAP: 0x25 - INT : INT: TRAP (0x0000:0x0025) - HANDLE : INT: TRAP (0x0000:0x0025) + TIMESTAMP : 2023-11-10T22:12:48.712542-05:00 + LEVEL : INFO + SOURCE : demo.go:109 + FUNCTION : cmd.demo.Run.func3 + MESSAGE : Starting display - TIMESTAMP : 2023-10-11T10:25:48-04:00 + TIMESTAMP : 2023-11-10T22:12:48.712618-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : - VM : - PC : 0x1000 - IR : 0xf025 (OP: TRAP) - PSR : 0x0007 (N:true Z:true P:true PR:0 PL:0) + !BADKEY : + PC : 0x0420 + IR : 0xf021 (OP: TRAP) + PSR : 0x0300 (N:false Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x0025 - MDR : 0x1000 + MAR : 0x0021 + MDR : 0x0420 + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff + R0 : 0x2364 R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 @@ -184,802 +182,681 @@ $ elsie demo R6 : 0xfdfe R7 : 0x00f0 - TIMESTAMP : 2023-10-11T10:25:48-04:00 + TIMESTAMP : 2023-11-10T22:12:48.712663-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : - VM : - PC : 0x1001 - IR : 0x5020 (OP: AND) - PSR : 0x0002 (N:false Z:true P:false PR:0 PL:0) + !BADKEY : + PC : 0x0421 + IR : 0x1dbf (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x1000 - MDR : 0x5020 + MAR : 0x0420 + MDR : 0x1dbf + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0x0000 + R0 : 0x2364 R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfdfe + R6 : 0xfdfd R7 : 0x00f0 - TIMESTAMP : 2023-10-11T10:25:48-04:00 + TIMESTAMP : 2023-11-10T22:12:48.7127-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : - VM : - PC : 0x1002 - IR : 0xe201 (OP: LEA) - PSR : 0x0002 (N:false Z:true P:false PR:0 PL:0) + !BADKEY : + PC : 0x0422 + IR : 0x7380 (OP: STR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x1003 - MDR : 0xfffe + MAR : 0xfdfd + MDR : 0x0000 + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0x0000 - R1 : 0xfffe + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfdfe + R6 : 0xfdfd R7 : 0x00f0 - TIMESTAMP : 2023-10-11T10:25:48-04:00 + TIMESTAMP : 2023-11-10T22:12:48.712732-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : - VM : - PC : 0x1003 - IR : 0x7040 (OP: STR) - PSR : 0x0002 (N:false Z:true P:false PR:0 PL:0) + !BADKEY : + PC : 0x0423 + IR : 0x1dbf (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 - MCR : 0x0000 (STOP) - MAR : 0xfffe - MDR : 0x0000 + MCR : 0x8000 (RUN) + MAR : 0x0422 + MDR : 0x1dbf + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0x0000 - R1 : 0xfffe + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfdfe + R6 : 0xfdfc R7 : 0x00f0 - TIMESTAMP : 2023-10-11T10:25:48-04:00 + TIMESTAMP : 2023-11-10T22:12:48.712762-05:00 LEVEL : INFO - SOURCE : exec.go:39 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run - MESSAGE : HALTED (HCF) + MESSAGE : EXEC STATE : - VM : - PC : 0x1003 - IR : 0x7040 (OP: STR) - PSR : 0x0002 (N:false Z:true P:false PR:0 PL:0) + !BADKEY : + PC : 0x0424 + IR : 0x7580 (OP: STR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 - MCR : 0x0000 (STOP) - MAR : 0xfffe - MDR : 0x0000 + MCR : 0x8000 (RUN) + MAR : 0xfdfc + MDR : 0xfff0 + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0x0000 - R1 : 0xfffe + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfdfe + R6 : 0xfdfc R7 : 0x00f0 - TIMESTAMP : 2023-10-11T10:25:48-04:00 - LEVEL : INFO - SOURCE : demo.go:132 - FUNCTION : cmd.demo.Run - MESSAGE : Demo completed -``` - - -
- -The demo does not do much and is quite noisy about it. It loads a `HALT` -instruction into program memory, initializes a trap service routine that stops -the VM, and then runs the program. - -Notice, in particular, the value for `PC` when the machine halted: `0x1003`. -This means the next instruction to be executed, had the machine not stopped, is -held at address `0x1003`. This is notable because our program started execution -at a different address, `0x3000`: it seems our machine did a bit of work to stop -doing any more. - -## Assemble a program ## - -You, my dear reader, have already accomplished so much. If you have reached this -point in our tutorian journey, you have: - - - downloaded source code to ELSIE (and, incidentally, the code on which it - depends); - - compiled the code to create a virtual computer; - - had the machine execute a hard-coded program. - -Consider, none of that would have been possible, not even imaginable, one -hundred years ago. Only a few researchers, defence organizations, and spies had -this capability eighty years ago. A decade later, perhaps, large commercial -organizations started writing and running their own programs on their own -machines[^1]. - -Yet, it is not really quite what we imagined computing to be. Next, you will -create machine code from source. In this directory you will find an assembly -program. To translate the source to an object file containing machine code, run: - -```console -$ elsie asm COUNTDOWN.asm -``` - -Well, that isn't satisfying, but no output means success in this case. - -```console -$ elsie help asm -Usage: - - elsie asm [-o file.out] file.asm - -Assemble source into object code. - -Options: - -debug - enable debug logging - -o filename - output filename (default "a.o") -``` - -```console -$ elsie asm -debug COUNTDOWN.asm - TIMESTAMP : 2023-10-11T11:51:30-04:00 - LEVEL : DEBUG - SOURCE : asm.go:66 - FUNCTION : cmd.(*assembler).Run - MESSAGE : Parsed source - SYMBOLS : 4 - SIZE : 10 - ERR : - - TIMESTAMP : 2023-10-11T11:51:30-04:00 - LEVEL : DEBUG - SOURCE : asm.go:88 - FUNCTION : cmd.(*assembler).Run - MESSAGE : Writing object - FILE : a.o - - TIMESTAMP : 2023-10-11T11:51:30-04:00 - LEVEL : DEBUG - SOURCE : gen.go:56 - FUNCTION : asm.(*Generator).WriteTo - MESSAGE : Wrote object header - ORIG : 0x3000 - - TIMESTAMP : 2023-10-11T11:51:30-04:00 - LEVEL : DEBUG - SOURCE : asm.go:103 - FUNCTION : cmd.(*assembler).Run - MESSAGE : Compiled object - OUT : a.o - SIZE : 20 - SYMBOLS : 4 - SYNTAX : 10 -``` - -Ah ha -- we can now see that the assembler has successfully compiled source to -object code. - -## Running a program ## - -Before running the countdown program, let's take a look at the source code to -get an idea what it is going to do. - -``` -;;; COUNTDOWN.asm : a program for a tutorial that counts down to blast off -;;; Inputs: R0 is the address of counter. - - .ORIG x3000 ; Start at the beginning of user-space memory. - ST R1,SAVER1 ; Set aside the R1 for the counter value. - LD R1,COUNT ; Load the counter value from the pointer. - - ;; - ;; Main program loop - ;; -LOOP: - BRz EXIT ; If counter is zero, exit program. - ADD R1,R1,#-1 ; Decrement counter. - BRnzp LOOP ; Loop - - ;; - ;; Exit program. - ;; -EXIT: - LD R1,SAVER1 - HALT - - ;; - ;; Program data - ;; -COUNT: ; - .FILL 10 - -SAVER1 .DW x0000 - .END -``` - -If you have never looked at assembly code, do not be intimidated: what it lacks -in grace and expressiveness it makes up with cold, hard directness. On the one -hand one must communicate to the computer what to do in excruciating detail -without familiar abstractions. On the other, it is all laid bare and nothing is -hidden. - -Maybe with the comments and some familiar names in the source you can make a -guess what this program does. It counts down from 10 and then stops. That's it. - -You can now try running the program. There is quite a lot of output, arguably -too much, so let is just focus on a single value: the `PC` or _program counter_. -This value points to the next instruction the CPU will execute. Examine its -the value as the program executes: - -```console -$ elsie exec countdown.bin 2>&1 | grep 'PC : ' - PC : 0x3000 - PC : 0x3001 - PC : 0x3002 - PC : 0x3003 - PC : 0x3004 - PC : 0x3002 - PC : 0x3003 - PC : 0x3004 - PC : 0x3002 - PC : 0x3003 - PC : 0x3004 - PC : 0x3002 - PC : 0x3003 - PC : 0x3004 - PC : 0x3002 - PC : 0x3003 - PC : 0x3004 - PC : 0x3002 - PC : 0x3003 - PC : 0x3004 - PC : 0x3002 - PC : 0x3003 - PC : 0x3004 - PC : 0x3002 - PC : 0x3003 - PC : 0x3004 - PC : 0x3002 - PC : 0x3003 - PC : 0x3004 - PC : 0x3002 - PC : 0x3003 - PC : 0x3004 - PC : 0x3002 - PC : 0x3005 - PC : 0x3006 - PC : 0x1000 - PC : 0x1001 - PC : 0x1002 - PC : 0x1003 - PC : 0x1003 -``` - -The attentive reader will notice that it starts at address `0x3000`, proceeds -take the values `0x3002`, `0x3003`, and `0x3004` in sequence, repeatedly. -Finally, it moves to `0x3005` and `0x3006` before a big jump backwards to -`0x1000` and proceeding to `0x1003`. This little routine, like the steps in a -terrible square dance, are our countdown loop. - -
Full output… - -If you are curious, take note of the value of R1 throughout the execution -of the program: - -``` -$ elsie exec -loglevel info exec - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.712805-05:00 LEVEL : INFO - SOURCE : exec.go:17 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run - MESSAGE : START + MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3000 - IR : 0x0000 (OP: BR) - PSR : 0x0300 (N:false Z:false P:false PR:0 PL:3) + PC : 0x0425 + IR : 0x1dbf (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0xffff - MDR : 0x0ff0 + MAR : 0x0424 + MDR : 0x1dbf + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff + R0 : 0x2364 R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.712835-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3001 - IR : 0x3207 (OP: ST) - PSR : 0x0300 (N:false Z:false P:false PR:0 PL:3) + PC : 0x0426 + IR : 0x7780 (OP: STR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3008 - MDR : 0x0000 + MAR : 0xfdfb + MDR : 0xf000 + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff + R0 : 0x2364 R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.712874-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3002 - IR : 0x2205 (OP: LD) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0427 + IR : 0xa210 (OP: LDI) + PSR : 0x0301 (N:false Z:false P:true PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3007 - MDR : 0x000a + MAR : 0xfffc + MDR : 0x0304 + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x000a + R0 : 0x2364 + R1 : 0x0304 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.712913-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3003 - IR : 0x0402 (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0428 + IR : 0x240e (OP: LD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3002 - MDR : 0x0402 + MAR : 0x0436 + MDR : 0xbfff + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x000a - R2 : 0xfff0 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0xbfff R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.712947-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3004 - IR : 0x127f (OP: ADD) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0429 + IR : 0x5442 (OP: AND) + PSR : 0x0301 (N:false Z:false P:true PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3003 - MDR : 0x127f + MAR : 0x0428 + MDR : 0x5442 + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0009 - R2 : 0xfff0 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.712981-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3002 - IR : 0x0ffd (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x042a + IR : 0xb20d (OP: STI) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3004 - MDR : 0x0ffd + MAR : 0xfffc + MDR : 0x0304 + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0009 - R2 : 0xfff0 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713022-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3003 - IR : 0x0402 (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x042b + IR : 0xb40c (OP: STI) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3002 - MDR : 0x0402 + MAR : 0xfffc + MDR : 0x0304 + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0009 - R2 : 0xfff0 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713063-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3004 - IR : 0x127f (OP: ADD) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x042c + IR : 0xa60c (OP: LDI) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3003 - MDR : 0x127f + MAR : 0xfe04 + MDR : 0x8000 + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0008 - R2 : 0xfff0 - R3 : 0xf000 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 + R3 : 0x8000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713099-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3002 - IR : 0x0ffd (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x042d + IR : 0x07fd (OP: BR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3004 - MDR : 0x0ffd + MAR : 0x042c + MDR : 0x07fd + DDR : 0x2368 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0008 - R2 : 0xfff0 - R3 : 0xf000 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 + R3 : 0x8000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713135-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3003 - IR : 0x0402 (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x042e + IR : 0xb00b (OP: STI) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3002 - MDR : 0x0402 + MAR : 0xfe06 + MDR : 0x2364 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0008 - R2 : 0xfff0 - R3 : 0xf000 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 + R3 : 0x8000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 +⍀ TIMESTAMP : 2023-11-10T22:12:48.713171-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3004 - IR : 0x127f (OP: ADD) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x042f + IR : 0xb208 (OP: STI) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3003 - MDR : 0x127f + MAR : 0xfffc + MDR : 0x0304 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0007 - R2 : 0xfff0 - R3 : 0xf000 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 + R3 : 0x8000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713208-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3002 - IR : 0x0ffd (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0430 + IR : 0x6780 (OP: LDR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3004 - MDR : 0x0ffd + MAR : 0xfdfb + MDR : 0xf000 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0007 - R2 : 0xfff0 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713239-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3003 - IR : 0x0402 (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0431 + IR : 0x1da1 (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3002 - MDR : 0x0402 + MAR : 0x0430 + MDR : 0x1da1 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0007 - R2 : 0xfff0 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfc R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713268-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3004 - IR : 0x127f (OP: ADD) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0432 + IR : 0x6580 (OP: LDR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3003 - MDR : 0x127f + MAR : 0xfdfc + MDR : 0xfff0 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0006 + R0 : 0x2364 + R1 : 0x0304 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfc R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.71331-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3002 - IR : 0x0ffd (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0433 + IR : 0x1da1 (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3004 - MDR : 0x0ffd + MAR : 0x0432 + MDR : 0x1da1 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0006 + R0 : 0x2364 + R1 : 0x0304 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfd R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713339-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3003 - IR : 0x0402 (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0434 + IR : 0x6380 (OP: LDR) + PSR : 0x0302 (N:false Z:true P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3002 - MDR : 0x0402 + MAR : 0xfdfd + MDR : 0x0000 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0006 + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfd R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713382-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3004 - IR : 0x127f (OP: ADD) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0435 + IR : 0x1da1 (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3003 - MDR : 0x127f + MAR : 0x0434 + MDR : 0x1da1 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0005 + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfe R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713419-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3002 - IR : 0x0ffd (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x3001 + IR : 0x8000 (OP: RTI) + PSR : 0x0300 (N:false Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3004 - MDR : 0x0ffd + MAR : 0xfdff + MDR : 0x0300 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0005 + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 @@ -987,619 +864,1318 @@ $ elsie exec -loglevel info exec R6 : 0xfe00 R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713455-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3003 - IR : 0x0402 (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0420 + IR : 0xf021 (OP: TRAP) + PSR : 0x0300 (N:false Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3002 - MDR : 0x0402 + MAR : 0x0021 + MDR : 0x0420 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0005 + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfe R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713486-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3004 - IR : 0x127f (OP: ADD) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0421 + IR : 0x1dbf (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3003 - MDR : 0x127f + MAR : 0x0420 + MDR : 0x1dbf + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0004 + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfd R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713529-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3002 - IR : 0x0ffd (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0422 + IR : 0x7380 (OP: STR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3004 - MDR : 0x0ffd + MAR : 0xfdfd + MDR : 0x0000 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0004 + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfd R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713563-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3003 - IR : 0x0402 (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0423 + IR : 0x1dbf (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3002 - MDR : 0x0402 + MAR : 0x0422 + MDR : 0x1dbf + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0004 + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfc R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713594-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3004 - IR : 0x127f (OP: ADD) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0424 + IR : 0x7580 (OP: STR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3003 - MDR : 0x127f + MAR : 0xfdfc + MDR : 0xfff0 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0003 + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfc R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713629-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3002 - IR : 0x0ffd (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0425 + IR : 0x1dbf (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3004 - MDR : 0x0ffd + MAR : 0x0424 + MDR : 0x1dbf + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0003 + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713661-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3003 - IR : 0x0402 (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0426 + IR : 0x7780 (OP: STR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3002 - MDR : 0x0402 + MAR : 0xfdfb + MDR : 0xf000 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0003 + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713691-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3004 - IR : 0x127f (OP: ADD) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0427 + IR : 0xa210 (OP: LDI) + PSR : 0x0301 (N:false Z:false P:true PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3003 - MDR : 0x127f + MAR : 0xfffc + MDR : 0x0304 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0002 + R0 : 0x2364 + R1 : 0x0304 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:11-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713724-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3002 - IR : 0x0ffd (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0428 + IR : 0x240e (OP: LD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3004 - MDR : 0x0ffd + MAR : 0x0436 + MDR : 0xbfff + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0002 - R2 : 0xfff0 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0xbfff R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:12-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713753-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3003 - IR : 0x0402 (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x0429 + IR : 0x5442 (OP: AND) + PSR : 0x0301 (N:false Z:false P:true PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3002 - MDR : 0x0402 + MAR : 0x0428 + MDR : 0x5442 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0002 - R2 : 0xfff0 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:12-04:00 + TIMESTAMP : 2023-11-10T22:12:48.7138-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3004 - IR : 0x127f (OP: ADD) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x042a + IR : 0xb20d (OP: STI) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3003 - MDR : 0x127f + MAR : 0xfffc + MDR : 0x0304 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0001 - R2 : 0xfff0 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:12-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713841-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3002 - IR : 0x0ffd (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x042b + IR : 0xb40c (OP: STI) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3004 - MDR : 0x0ffd + MAR : 0xfffc + MDR : 0x0304 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0001 - R2 : 0xfff0 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:12-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713876-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3003 - IR : 0x0402 (OP: BR) - PSR : 0x0301 (N:false Z:false P:true PR:0 PL:3) + PC : 0x042c + IR : 0xa60c (OP: LDI) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3002 - MDR : 0x0402 + MAR : 0xfe04 + MDR : 0x8000 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0001 - R2 : 0xfff0 - R3 : 0xf000 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 + R3 : 0x8000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:12-04:00 + TIMESTAMP : 2023-11-10T22:12:48.713905-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3004 - IR : 0x127f (OP: ADD) - PSR : 0x0302 (N:false Z:true P:false PR:0 PL:3) + PC : 0x042d + IR : 0x07fd (OP: BR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3003 - MDR : 0x127f + MAR : 0x042c + MDR : 0x07fd + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0000 - R2 : 0xfff0 - R3 : 0xf000 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 + R3 : 0x8000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:12-04:00 +⍀ TIMESTAMP : 2023-11-10T22:12:48.793738-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3002 - IR : 0x0ffd (OP: BR) - PSR : 0x0302 (N:false Z:true P:false PR:0 PL:3) + PC : 0x042e + IR : 0xb00b (OP: STI) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3004 - MDR : 0x0ffd + MAR : 0xfe06 + MDR : 0x2364 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0000 - R2 : 0xfff0 - R3 : 0xf000 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 + R3 : 0x8000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:12-04:00 + TIMESTAMP : 2023-11-10T22:12:48.793857-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3005 - IR : 0x0402 (OP: BR) - PSR : 0x0302 (N:false Z:true P:false PR:0 PL:3) + PC : 0x042f + IR : 0xb208 (OP: STI) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3002 - MDR : 0x0402 + MAR : 0xfffc + MDR : 0x0304 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0000 - R2 : 0xfff0 - R3 : 0xf000 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 + R3 : 0x8000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:12-04:00 + TIMESTAMP : 2023-11-10T22:12:48.793936-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x3006 - IR : 0x2202 (OP: LD) - PSR : 0x0302 (N:false Z:true P:false PR:0 PL:3) + PC : 0x0430 + IR : 0x6780 (OP: LDR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x3008 - MDR : 0x0000 + MAR : 0xfdfb + MDR : 0xf000 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0000 - R2 : 0xfff0 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfe00 + R6 : 0xfdfb R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:12-04:00 - LEVEL : INFO - SOURCE : exec.go:105 - FUNCTION : vm.(*LC3).Step - MESSAGE : instruction raised interrupt - OP : TRAP: 0x25 - INT : INT: TRAP (0x0000:0x0025) - - TIMESTAMP : 2023-10-12T10:12:12-04:00 + TIMESTAMP : 2023-11-10T22:12:48.794014-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x1000 - IR : 0xf025 (OP: TRAP) - PSR : 0x0302 (N:false Z:true P:false PR:0 PL:3) + PC : 0x0431 + IR : 0x1da1 (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x0025 - MDR : 0x1000 + MAR : 0x0430 + MDR : 0x1da1 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0xffff - R1 : 0x0000 - R2 : 0xfff0 + R0 : 0x2364 + R1 : 0x0304 + R2 : 0x0304 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfdfe + R6 : 0xfdfc R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:12-04:00 + TIMESTAMP : 2023-11-10T22:12:48.794077-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x1001 - IR : 0x5020 (OP: AND) - PSR : 0x0302 (N:false Z:true P:false PR:0 PL:3) + PC : 0x0432 + IR : 0x6580 (OP: LDR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x1000 - MDR : 0x5020 + MAR : 0xfdfc + MDR : 0xfff0 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0x0000 - R1 : 0x0000 + R0 : 0x2364 + R1 : 0x0304 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfdfe + R6 : 0xfdfc R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:12-04:00 + TIMESTAMP : 2023-11-10T22:12:48.794133-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x1002 - IR : 0xe201 (OP: LEA) - PSR : 0x0302 (N:false Z:true P:false PR:0 PL:3) + PC : 0x0433 + IR : 0x1da1 (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 MCR : 0x8000 (RUN) - MAR : 0x1003 - MDR : 0xfffe + MAR : 0x0432 + MDR : 0x1da1 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0x0000 - R1 : 0xfffe + R0 : 0x2364 + R1 : 0x0304 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfdfe + R6 : 0xfdfd R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:12-04:00 + TIMESTAMP : 2023-11-10T22:12:48.794213-05:00 LEVEL : INFO - SOURCE : exec.go:31 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run MESSAGE : EXEC STATE : !BADKEY : - PC : 0x1003 - IR : 0x7040 (OP: STR) - PSR : 0x0302 (N:false Z:true P:false PR:0 PL:3) + PC : 0x0434 + IR : 0x6380 (OP: LDR) + PSR : 0x0302 (N:false Z:true P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 - MCR : 0x0000 (STOP) - MAR : 0xfffe + MCR : 0x8000 (RUN) + MAR : 0xfdfd MDR : 0x0000 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0x0000 - R1 : 0xfffe + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 - R6 : 0xfdfe + R6 : 0xfdfd R7 : 0x00f0 - TIMESTAMP : 2023-10-12T10:12:12-04:00 + TIMESTAMP : 2023-11-10T22:12:48.79428-05:00 LEVEL : INFO - SOURCE : exec.go:39 + SOURCE : exec.go:40 FUNCTION : vm.(*LC3).Run - MESSAGE : HALTED (HCF) + MESSAGE : EXEC STATE : !BADKEY : - PC : 0x1003 - IR : 0x7040 (OP: STR) - PSR : 0x0302 (N:false Z:true P:false PR:0 PL:3) + PC : 0x0435 + IR : 0x1da1 (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) USP : 0xfe00 SSP : 0x3000 - MCR : 0x0000 (STOP) - MAR : 0xfffe - MDR : 0x0000 + MCR : 0x8000 (RUN) + MAR : 0x0434 + MDR : 0x1da1 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff INT : PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} REG : - R0 : 0x0000 - R1 : 0xfffe + R0 : 0x2364 + R1 : 0x0000 R2 : 0xfff0 R3 : 0xf000 R4 : 0xff00 R5 : 0x0f00 R6 : 0xfdfe R7 : 0x00f0 -``` - -
- -## Writing a program ## -_Watch this space.__ - -### Footnotes ### - -[^1]: In practice, most machines were rented, I guess. In any case, the ability -to write one's own programs for one's own machine is, perhaps, one of the -essential catalysts of change in the Twentieth-Century post-war period, _IMHO_. + TIMESTAMP : 2023-11-10T22:12:48.794343-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x3002 + IR : 0x8000 (OP: RTI) + PSR : 0x0300 (N:false Z:false P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0xfdff + MDR : 0x0300 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x2364 + R1 : 0x0000 + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfe00 + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.794421-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0520 + IR : 0xf025 (OP: TRAP) + PSR : 0x0300 (N:false Z:false P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0x0025 + MDR : 0x0520 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x2364 + R1 : 0x0000 + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfe + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.794528-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0521 + IR : 0xe006 (OP: LEA) + PSR : 0x0300 (N:false Z:false P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0x0520 + MDR : 0xe006 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x236a + R1 : 0x0000 + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfe + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.794593-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0460 + IR : 0xf022 (OP: TRAP) + PSR : 0x0300 (N:false Z:false P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0x0022 + MDR : 0x0460 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x236a + R1 : 0x0000 + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfc + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.794666-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0461 + IR : 0x1dbf (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0x0460 + MDR : 0x1dbf + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x236a + R1 : 0x0000 + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfb + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.794723-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0462 + IR : 0x7180 (OP: STR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0xfdfb + MDR : 0x236a + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x236a + R1 : 0x0000 + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfb + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.794765-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0463 + IR : 0x1dbf (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0x0462 + MDR : 0x1dbf + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x236a + R1 : 0x0000 + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfa + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.794824-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0464 + IR : 0x7380 (OP: STR) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0xfdfa + MDR : 0x0000 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x236a + R1 : 0x0000 + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfa + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.794862-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0465 + IR : 0x1220 (OP: ADD) + PSR : 0x0301 (N:false Z:false P:true PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0x0464 + MDR : 0x1220 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x236a + R1 : 0x236a + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfa + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.794905-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0466 + IR : 0x6040 (OP: LDR) + PSR : 0x0302 (N:false Z:true P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0x236a + MDR : 0x0000 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x0000 + R1 : 0x236a + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfa + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.794957-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x046b + IR : 0x0404 (OP: BR) + PSR : 0x0302 (N:false Z:true P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0x0466 + MDR : 0x0404 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x0000 + R1 : 0x236a + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfa + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.794993-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x046c + IR : 0x1da1 (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0x046b + MDR : 0x1da1 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x0000 + R1 : 0x236a + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfb + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.795032-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x046d + IR : 0x6180 (OP: LDR) + PSR : 0x0301 (N:false Z:false P:true PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0xfdfb + MDR : 0x236a + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x236a + R1 : 0x236a + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfb + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.795076-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x046e + IR : 0x1da1 (OP: ADD) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0x046d + MDR : 0x1da1 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x236a + R1 : 0x236a + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfc + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.795119-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0522 + IR : 0x8000 (OP: RTI) + PSR : 0x0300 (N:false Z:false P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0xfdfd + MDR : 0x0300 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x236a + R1 : 0x236a + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfe + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.795163-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0523 + IR : 0xa00a (OP: LDI) + PSR : 0x0304 (N:true Z:false P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0xfffe + MDR : 0x8000 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x8000 + R1 : 0x236a + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfe + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.79521-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0524 + IR : 0x220a (OP: LD) + PSR : 0x0301 (N:false Z:false P:true PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0x052e + MDR : 0x7fff + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x8000 + R1 : 0x7fff + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfe + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.795247-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0525 + IR : 0x5001 (OP: AND) + PSR : 0x0302 (N:false Z:true P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x8000 (RUN) + MAR : 0x0524 + MDR : 0x5001 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x0000 + R1 : 0x7fff + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfe + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.795289-05:00 + LEVEL : INFO + SOURCE : exec.go:40 + FUNCTION : vm.(*LC3).Run + MESSAGE : EXEC + STATE : + !BADKEY : + PC : 0x0526 + IR : 0xb007 (OP: STI) + PSR : 0x0302 (N:false Z:true P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x0000 (STOP) + MAR : 0xfffe + MDR : 0x0000 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x0000 + R1 : 0x7fff + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfe + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.795335-05:00 + LEVEL : INFO + SOURCE : exec.go:54 + FUNCTION : vm.(*LC3).Run + MESSAGE : HALTED (TRAP) + STATE : + !BADKEY : + PC : 0x0526 + IR : 0xb007 (OP: STI) + PSR : 0x0302 (N:false Z:true P:false PR:System PL:3) + USP : 0xfe00 + SSP : 0x3000 + MCR : 0x0000 (STOP) + MAR : 0xfffe + MDR : 0x0000 + DDR : 0x2364 + DSR : 0x8000 + KBDR : 0x2368 + KBSR : 0x7fff + INT : + PL3 : ISR{0xff:Keyboard(status:0x7fff,data:0x2368)} + REG : + R0 : 0x0000 + R1 : 0x7fff + R2 : 0xfff0 + R3 : 0xf000 + R4 : 0xff00 + R5 : 0x0f00 + R6 : 0xfdfe + R7 : 0x00f0 + + TIMESTAMP : 2023-11-10T22:12:48.795387-05:00 + LEVEL : INFO + SOURCE : demo.go:147 + FUNCTION : cmd.demo.Run + MESSAGE : Demo completed + +``` + +## Writing a program ## + +_Watch this space.__ diff --git a/internal/cli/cmd/demo.go b/internal/cli/cmd/demo.go index e927518..a97a29a 100644 --- a/internal/cli/cmd/demo.go +++ b/internal/cli/cmd/demo.go @@ -15,14 +15,15 @@ import ( "github.com/smoynes/elsie/internal/vm" ) -// Demo is a demonstration command. +// Demo is a demonstration command. It serves as a smoke test for the VM and an example for +// developers. func Demo() cli.Command { return new(demo) } type demo struct { + log bool debug bool - quiet bool } func (demo) Description() string { @@ -32,9 +33,9 @@ func (demo) Description() string { func (d demo) Usage(out io.Writer) error { var err error _, err = fmt.Fprintln(out, ` -demo [ -debug | -quiet ] +demo [ -log | -debug ] -Run demonstration program while displaying VM state.`) +Run demonstration program.`) return err } @@ -42,59 +43,67 @@ Run demonstration program while displaying VM state.`) func (d *demo) FlagSet() *cli.FlagSet { fs := flag.NewFlagSet("demo", flag.ExitOnError) - fs.BoolVar(&d.debug, "debug", false, "enable debug logging") - fs.BoolVar(&d.quiet, "quiet", false, "enable quiet output, machine display only") + fs.BoolVar(&d.log, "log", false, "log execution state") + fs.BoolVar(&d.debug, "debug", false, "verbose execution state") return fs } func (d demo) Run(ctx context.Context, args []string, out io.Writer, _ *log.Logger) int { + // When the context is cancelled the machine will stop running. ctx, done := context.WithCancel(ctx) defer done() + // We expect it to take much less than 1 second to run the demo. If it takes much longer, + // something is wrong. ctx, cancelTimeout := context.WithTimeout(ctx, 5*time.Second) defer cancelTimeout() - if d.quiet { - log.LogLevel.Set(log.Error) - } - - if d.debug { - log.LogLevel.Set(log.Debug) - } - - logger := log.NewFormattedLogger(os.Stdout) - log.SetDefault(logger) - log.DefaultLogger = func() *log.Logger { - return logger - } + // For the demo, we log to the error stream. + logger := d.configureLogger(os.Stderr) logger.Info("Initializing machine") + // Use a channel to send displayed values to a background thread. dispCh := make(chan uint16) + + // Create virtual machine. machine := vm.New( + // Use default BIOS. + monitor.WithDefaultSystemImage(), + + // Log using the configured logger. vm.WithLogger(logger), + + // Write displayed values to the display channel. vm.WithDisplayListener(func(displayed uint16) { dispCh <- displayed }), - monitor.WithDefaultSystemImage(), ) logger.Info("Loading program") + // Load the demo program. loader := vm.NewLoader(machine) + machine.REG[vm.R0] = 0x2364 // ⍀ code := vm.ObjectCode{ Orig: 0x3000, Code: []vm.Word{ vm.Word(vm.NewInstruction(vm.TRAP, uint16(vm.TrapOUT))), vm.Word(vm.NewInstruction(vm.TRAP, uint16(vm.TrapOUT))), - vm.Word(vm.NewInstruction(vm.TRAP, uint16(vm.TrapOUT))), - vm.Word(vm.NewInstruction(vm.TRAP, uint16(vm.TrapOUT))), - vm.Word(vm.NewInstruction(vm.TRAP, uint16(vm.TrapOUT))), - vm.Word(vm.NewInstruction(vm.TRAP, uint16(vm.TrapOUT))), - vm.Word(vm.NewInstruction(vm.TRAP, uint16(vm.TrapOUT))), - vm.Word(vm.NewInstruction(vm.TRAP, uint16(vm.TrapOUT))), + vm.Word(vm.NewInstruction(vm.LEA, 0x0002)), + vm.Word(vm.NewInstruction(vm.TRAP, uint16(vm.TrapPUTS))), vm.Word(vm.NewInstruction(vm.TRAP, uint16(vm.TrapHALT))), + vm.Word('\n'), + vm.Word('t'), + vm.Word('h'), + vm.Word('a'), + vm.Word('n'), + vm.Word('k'), + vm.Word('s'), + vm.Word('!'), + vm.Word('\n'), + vm.Word(0x0000), }, } @@ -103,13 +112,7 @@ func (d demo) Run(ctx context.Context, args []string, out io.Writer, _ *log.Logg return 2 } - machine.REG[vm.R0] = 0x2364 - - if _, err := loader.Load(code); err != nil { - logger.Error("error loading code:", err) - return 2 - } - + // Start a background thread to displays each character after a brief delay. go func() { logger.Info("Starting display") @@ -121,11 +124,10 @@ func (d demo) Run(ctx context.Context, args []string, out io.Writer, _ *log.Logg case disp := <-dispCh: r := rune(disp) fmt.Printf("%c", r) + <-timer.C case <-ctx.Done(): return } - - <-timer.C } }() @@ -149,7 +151,35 @@ func (d demo) Run(ctx context.Context, args []string, out io.Writer, _ *log.Logg close(dispCh) - logger.Info("Demo completed") + if err := ctx.Err(); errors.Is(err, context.DeadlineExceeded) { + logger.Error("Demo timeout!") + return 2 + } else if errors.Is(err, context.Canceled) { + logger.Info("Demo completed") + return 0 + } else if err != nil { + logger.Error("Demo error!", "ERR", err) + return 2 + } return 0 } + +func (d demo) configureLogger(out io.Writer) *log.Logger { + logger := log.NewFormattedLogger(out) + log.SetDefault(logger) + log.DefaultLogger = func() *log.Logger { + return logger + } + + switch { + case d.debug == true: + log.LogLevel.Set(log.Debug) + case d.log == true: + log.LogLevel.Set(log.Info) + default: + log.LogLevel.Set(log.Error) + } + + return logger +} diff --git a/internal/monitor/traps.go b/internal/monitor/traps.go index 434c37b..df43278 100644 --- a/internal/monitor/traps.go +++ b/internal/monitor/traps.go @@ -17,9 +17,9 @@ var TrapHalt = Routine{ Orig: 0x0520, Symbols: asm.SymbolTable{ "RETRY": 0x0521, - "HALTMESSAGE": 0x0526, - "MCR": 0x052c, - "MASK": 0x052d, + "MCR": 0x0526, + "MASK": 0x0527, + "HALTMESSAGE": 0x0528, }, Code: []asm.Operation{ // Print a message. Alert the media. @@ -42,9 +42,9 @@ var TrapHalt = Routine{ }, // Routine data. - /* 0x0527 + 6 */ &asm.STRINGZ{LITERAL: "HALT!"}, // HALTMESSAGE. - /* 0x052d */ &asm.FILL{LITERAL: uint16(vm.MCRAddr)}, // I/O address of MCR. - /* 0x052e */ &asm.FILL{LITERAL: 0x7fff}, // MASK to clear top bit. + /* 0x0527 */ &asm.FILL{LITERAL: uint16(vm.MCRAddr)}, // I/O address of MCR. + /* 0x0528 */ &asm.FILL{LITERAL: 0x7fff}, // MASK to clear top bit. + /* 0x0529 */ &asm.STRINGZ{LITERAL: "\n\nMACHINE HALTED!\n\n"}, }, } @@ -53,6 +53,7 @@ var TrapHalt = Routine{ // - Table: 0x0000 // - Vector: 0x21 // - Handler: 0x0420 +// - Input: R0, character to display. // // Adapted from Fig. 9.22, 3/e. var TrapOut = Routine{ @@ -141,13 +142,13 @@ var TrapPuts = Routine{ Vector: vm.TrapTable + vm.Word(vm.TrapPUTS), Orig: 0x0460, Symbols: asm.SymbolTable{ - "LOOP": 0x0465, + "LOOP": 0x0464, "RETURN": 0x046a, "DSR": 0x0429, "DDR": 0x0435, }, Code: []asm.Operation{ - // Push R0,R1 onto the stack. + // Push R0, R1 onto the stack. /*0x0460*/ &asm.ADD{DR: "R6", SR1: "R6", LITERAL: 0xffff}, &asm.STR{SR1: "R0", SR2: "R6"}, @@ -181,7 +182,7 @@ var TrapPuts = Routine{ &asm.RTI{}, // Trap-scoped variables. - /*0x0438 */ &asm.FILL{LITERAL: uint16(vm.DSRAddr)}, // display status-, and - /*0x0439 */ &asm.FILL{LITERAL: uint16(vm.DDRAddr)}, // data-registers. + /*0x046f */ &asm.FILL{LITERAL: uint16(vm.DSRAddr)}, // display status-, and + /*0x0470 */ &asm.FILL{LITERAL: uint16(vm.DDRAddr)}, // data-registers. }, } diff --git a/internal/monitor/traps_test.go b/internal/monitor/traps_test.go index 3b0c09e..af0461b 100644 --- a/internal/monitor/traps_test.go +++ b/internal/monitor/traps_test.go @@ -276,8 +276,8 @@ func TestTrap_Puts(tt *testing.T) { } for i := range vals { - if vals[i] != 0x0021 { - t.Errorf("vals[%d] != 0x0021, got: %04X", i, vals[i]) + if vals[i] != 0x0021+uint16(i) { + t.Errorf("vals[%d] != 0x0022, got: %04x", i, vals[i]) } } } diff --git a/internal/vm/io.go b/internal/vm/io.go index 3fe901a..556764e 100644 --- a/internal/vm/io.go +++ b/internal/vm/io.go @@ -139,12 +139,12 @@ func (mmio MMIO) PSR() ProcessorStatus { } // DDR returns the value of the display data register, if it has been mapped. -func (mmio MMIO) DDR() rune { - ddr := rune('⍝') +func (mmio MMIO) DDR() Register { + ddr := Register('⍝') if dev := mmio.devs[DDRAddr]; dev != nil { val := dev.(*DisplayDriver) - ddr = rune(val.handle.device.ddr) + ddr = val.handle.device.ddr } return ddr diff --git a/internal/vm/log.go b/internal/vm/log.go index 2f33555..e76e3f1 100644 --- a/internal/vm/log.go +++ b/internal/vm/log.go @@ -33,10 +33,10 @@ func (vm *LC3) LogValue() log.Value { log.String("MCR", vm.MCR.String()), log.String("MAR", vm.Mem.MAR.String()), log.String("MDR", vm.Mem.MDR.String()), - log.Any("DDR", vm.Mem.Devices.DDR()), - log.Any("DSR", vm.Mem.Devices.DSR()), - log.Any("KBDR", vm.Mem.Devices.KBDR()), - log.Any("KBSR", vm.Mem.Devices.KBSR()), + log.String("DDR", vm.Mem.Devices.DDR().String()), + log.String("DSR", vm.Mem.Devices.DSR().String()), + log.String("KBDR", vm.Mem.Devices.KBDR().String()), + log.String("KBSR", vm.Mem.Devices.KBSR().String()), log.Any("INT", vm.INT), log.Any("REG", vm.REG), ) diff --git a/internal/vm/ops.go b/internal/vm/ops.go index a312f2f..698d256 100644 --- a/internal/vm/ops.go +++ b/internal/vm/ops.go @@ -360,6 +360,7 @@ func (op *lea) Decode(vm *LC3) { } func (op *lea) Execute() { + op.vm.REG[op.dr] = Register(op.vm.PC) op.vm.REG[op.dr].Offset(op.offset) } diff --git a/internal/vm/types.go b/internal/vm/types.go index 57d333a..50e71ed 100644 --- a/internal/vm/types.go +++ b/internal/vm/types.go @@ -60,7 +60,8 @@ func (r Register) String() string { // Offset adds an offset value to a register. The offset is taken as a func (r *Register) Offset(offset Word) { - *r = Register(Word(*r) + offset) + val := Word(*r) + offset + *r = Register(val) } // Instruction is a value that encodes a single CPU operation and is stored in a special purpose