User Tools

Site Tools


base:using_a_running_vice_session_for_development

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
base:using_a_running_vice_session_for_development [2016-06-28 19:17] compyxbase:using_a_running_vice_session_for_development [2016-07-01 13:35] (current) compyx
Line 11: Line 11:
 This article attempts to explain that process. For now, only for *nix systems. This article attempts to explain that process. For now, only for *nix systems.
  
 +Please note that I use a SVN snapshot of VICE, installed into /usr/local, so you may have to adjust a few paths, such as the location of the C64 kernal image.
 + 
  
 ==== Requirements ==== ==== Requirements ====
Line 21: Line 23:
   * make for making things easier   * make for making things easier
  
-Obviously we need an assembler, one which can output VICE labels if you want to use that feature. I personally use 64tass (again, build a current version).+Obviously we need an assembler, one which can output VICE labels if you want to use that feature. I personally use 64tass (again, build a current version, r1184 added support for scoped labels, eg: .foo:bar).
  
-And of course a decent editor, one which can at least syntax highlight Makefile's and whatever assembler you use.+And of course a decent editor, one which can at least syntax highlight Makefile's and whatever assembler you use, and allows you to change tab settings on a per-buffer base: Makefile's require tabs for indentation.
  
  
Line 61: Line 63:
  
 <code bash> <code bash>
-cp /usr/lib/vice/C64/kernal kernal-quick-memtest+cp /usr/local/lib64/vice/C64/kernal kernal-quick-memtest
 echo "1d69: 9f" | xxd -r - kernal-quick-memtest echo "1d69: 9f" | xxd -r - kernal-quick-memtest
 </code> </code>
 Any method of altering a binary can be used, I prefer to do it this way, so I can stick it in a Makefile and never have to worry about whether I patched the KERNAL or not. Any method of altering a binary can be used, I prefer to do it this way, so I can stick it in a Makefile and never have to worry about whether I patched the KERNAL or not.
  
-This makes the BASIC memtest finish immediately and still report the correct number of bytes free. (Thanks a lot to iAN CooG for suggesting this!)+This makes the BASIC memtest finish almost immediately and still report the correct number of bytes free. (Thanks a lot to iAN CooG for suggesting this!)
  
 VICE still needs to know about this new KERNAL, so the command to start VICE becomes: VICE still needs to know about this new KERNAL, so the command to start VICE becomes:
Line 83: Line 85:
    
 <code make> <code make>
-# x64 binary +VICE'x64 binary 
-X64 = /usr/local/bin/x64+X64=/usr/local/bin/x64 
 +# Standard flags to pass to VICE during startup 
 +X64_FLAGS=
  
 # Original KERNAL # Original KERNAL
-KERNAL=/usr/lib/vice/C64/kernal+KERNAL=/usr/local/lib64/vice/C64/kernal
 # Patched KERNAL # Patched KERNAL
 KERNAL_PATCHED=kernal-quick-memtest KERNAL_PATCHED=kernal-quick-memtest
Line 120: Line 124:
 </code> </code>
  
 +== Access VICE's output ==
 +
 +If you want to see VICE's messages, you redirect stdout and stderr to log files, which you inspect later, or just ''tail -f'' them.
 +
 +<code make>
 +# VICE's x64 binary
 +X64=/usr/local/bin/x64
 +# Standard flags to pass to VICE during startup
 +X64_FLAGS=
 +
 +# Log file for x64's stdout (VICE's warning/error messages also go here)
 +X64_STDOUT=vice.log
 +# Log file for x64's stderr
 +X64_STDERR=vice.err (useful when debug VICE itself)
 +
 +
 +# Rule to start VICE with remote monitor, with patched KERNAl for quicker
 +# reset and running it in the background with any output of VICE redirected to
 +# log files
 +session: $(KERNAL_PATCHED)
 + $(X64) $(X64_FLAGS) -remotemonitor -kernal $(KERNAL_PATCHED) \
 + 1>$(X64_STDOUT) 2>$(X64_STDERR) &
 +</code>
  
 ==== Setting up the client side ==== ==== Setting up the client side ====
Line 139: Line 166:
 </code> </code>
  
-Again, this becomes tedious, having to type this again and again, so we update our Makefile:+Again, this becomes tedious, having to type this again and again, so we update our Makefile (just the new parts for now):
 <code make> <code make>
 +ASM=64tass
 +
 +
 +# Default make target: just assemble the program:
 +all: demo.prg
 +
 +
 # Assemble program # Assemble program
 demo.prg: demo.s demo.prg: demo.s
-        $(X64) -a -C -o demo.prg demo.s+        $(ASM) -a -C -o demo.prg demo.s
  
 +
 +# Inject program into VICE session and run it
 run: demo.prg run: demo.prg
         # we need to wait one second for the reset to finish, so we use -q 1         # we need to wait one second for the reset to finish, so we use -q 1
Line 153: Line 189:
         echo 'g 080d' | netcat localhost 6510         echo 'g 080d' | netcat localhost 6510
 </code> </code>
 +
 +The `-q 1` argument to netcat is required to allow the reset to properly finish. netcat does not wait for VICE to complete its task, it immediately exits on EOF, so we use `-q 1` to tell netcat to wait one second after EOF. You could also use `sleep 1` after issuing 'reset 0', it has the same effect (adjust to sleep 3 when using a non-patched KERNAL).
 +
 +Since the 'run' target depends on 'demo.prg', that file automatically gets (re)built whenever we issue `make run`, and when the building fails no data is inserted into VICE.
 +
 +
 +=== Loading labels into VICE ===
 +
 +The same goes for loading labels into VICE: since we use a running instance, when we do 'load_labels', the old labels are still there, so when we've altered our binary, the labels might be different, but VICE keeps the old ones. So we do:
 +<code bash>
 +echo 'clear_labels' | netcat -q 1 localhost 6510
 +echo 'load_labels "labels.txt"' | netcat localhost 6510
 +</code>
 +Again giving VICE time to process the 'clear_labels' command before sending the 'load_labels' command. Obviously not needed when issuing these commands from the shell, but using a Makefile, this is required.
 +
 +So, lets update our Makefile once again (nearly complete Makefile now):
 +<code make>
 +# vim: noet ts=8 sw=8 sts=8
 +#
 +# Makefile for CB64 article 'Using a running VICE session for development'
 +
 +# This uses an SVN build of VICE, so adjust the paths to the x64 binary and
 +# the KERNAL if using the 2.4 stable build (which is way too old)
 +
 +
 +# Assembler (Soci's 64tass)
 +ASM=64tass
 +# Assembler flags (see the 64tass manual)
 +ASM_FLAGS=--ascii --case-sensitive --shadow-check --m6502
 +# Flags needed to output VICE labels (see the 64tass manual)
 +ASM_LABELS=--vice-labels -l $(LABEL_FILE)
 +
 +# file to output VICE labels to
 +LABEL_FILE=labels.txt
 +
 +
 +# VICE's x64 binary
 +X64=/usr/local/bin/x64
 +# Standard flags to pass to VICE during startup
 +X64_FLAGS=
 +# Log file for x64's stdout output
 +X64_STDOUT=vice.log
 +# Log file for x64's stderr output
 +X64_STDERR=vice.err
 +
 +
 +# Our demo binary
 +TARGET=demo.prg
 +
 +# Original KERNAL
 +KERNAL=/usr/local/lib64/vice/C64/kernal
 +# Patched KERNAL
 +KERNAL_PATCHED=kernal-quick-memtest
 +
 +
 +# Default make target, just our binary
 +all: $(TARGET)
 +
 +
 +# Rule to assemble our binary and output labels for VICE
 +$(TARGET): demo.s
 + $(ASM) $(ASM_FLAGS) $(ASM_LABELS) -o $@ $<
 +
 +
 +# Rule to patch the KERNAL for quicker reset
 +$(KERNAL_PATCHED): $(KERNAL)
 + cp $(KERNAL) $(KERNAL_PATCHED)
 + echo "1d69: 9f" | xxd -r - $(KERNAL_PATCHED)
 +
 +
 +# Rule to start VICE with remote monitor, with patched KERNAl for quicker
 +# reset and running it in the background with any output of VICE redirected to
 +# log file files
 +session: $(KERNAL_PATCHED)
 + $(X64) $(X64_FLAGS) -remotemonitor -kernal $(KERNAL_PATCHED) \
 + 1>$(X64_STDOUT) 2>$(X64_STDERR) &
 +
 +
 +# Rule to inject the program file and run it
 +run: $(TARGET)
 + # reset machine and wait for 1 second after EOF from machine
 + echo 'reset 0' | netcat -q1 localhost 6510
 +
 + # optional: load labels (we have to wait for one second to allow the
 + # command to complete)
 + echo 'clear_labels' | netcat -q1 localhost 6510
 + echo 'load_labels "$(LABEL_FILE)"' | netcat localhost 6510
 +
 + # load binary
 + echo 'l "$(TARGET)" 0' | netcat localhost 6510
 +        # execute binary, ignoring BASIC interpreter
 +        echo 'g 080d' | netcat localhost 6510
 +
 +
 +# Clean up
 +.PHONY: clean
 +clean:
 +        rm -f demo.prg
 +        rm -f $(KERNAL_PATCHED)
 +</code>
 +
 +There you have it, running and debugging code with a live VICE session, avoiding a lot of start up time. Unfortunately, when using this for code that **doesn't** set up IRQ's, we have a little problem.
 +
 +
 +== Proper BASIC initialization ==
 +
 +Since we bypass the C64's OS (the BASIC interpreter), when we execute code using the above method, the C64 doesn't know we executed a program and keeps the IRQ of the interpreter running, resulting in a nice blinking cursor.
 +
 +So we need a way to do a proper 'RUN' after injecting our program. We can do this with a simple SYS line and some tweaking of the <del>BASIC end-of-program pointer and</del> keyboard buffer.
 +
 +Let's assume our demo.s looks like this:
 +<code 6502tasm>
 +        * = $0801
 +        
 +        ; BASIC section: this becomes "2016 sys2061"
 +        .word (+), 2016
 +        .null $9e, ^start
 ++       .word 0
 +
 +start   ; this is $080d
 +        lda #0
 +        sta $d020
 +        sta $d021
 +        rts
 +</code>
 +
 +When we run this using the Makefile shown, the border and background turn black, but we get a blinking cursor. So we need to somehow force BASIC to properly run this SYS line. This can be done with a little tweaking:
 +(Thanks to Groepaz for coming up with the suggestion of simply putting 'RUN' into the keyboard buffer!)
 +
 +First we load the binary into VICE, then we set the end-of-basic pointer to $080d, fill the keyboard buffer with "RUN\r" and let the magic happen:
 +<code bash>
 +# reset, and wait, otherwise the BASIC start-of-basic pointer gets overwritten to $0000 while loading
 +echo 'reset 0' | netcat -q 1 localhost 6510
 +# load binary
 +echo 'l "demo.prg" 0' localhost 6510
 +# put 'RUN\r' into the keyboard buffer
 +echo 'f 0277 027a 52 55 4e 0d' | netcat localhost 6510
 +# set keyboard buffer size to $04 -> strlen("RUN\r")
 +echo 'f 00c6 00c6 04' | netcat localhost 6510
 +</code>
 +
 +Putting this in our Makefile, we end up with this:
 +<code make>
 +# vim: noet ts=8 sw=8 sts=8
 +#
 +# Makefile for CB64 article 'Using a running VICE session for development'
 +
 +# This uses an SVN build of VICE, so adjust the paths to the x64 binary and
 +# the KERNAL if using the 2.4 stable build (which is way too old)
 +
 +
 +# Assembler (Soci's 64tass)
 +ASM=64tass
 +# Assembler flags (see the 64tass manual)
 +ASM_FLAGS=--ascii --case-sensitive --shadow-check --m6502
 +# Flags needed to output VICE labels (see the 64tass manual)
 +ASM_LABELS=--vice-labels -l $(LABEL_FILE)
 +
 +# file to output VICE labels to
 +LABEL_FILE=labels.txt
 +
 +
 +# VICE's x64 binary
 +X64=/usr/local/bin/x64
 +# Standard flags to pass to VICE during startup
 +X64_FLAGS=
 +# Log file for x64's stdout output
 +X64_STDOUT=vice.log
 +# Log file for x64's stderr output
 +X64_STDERR=vice.err
 +
 +
 +# Our demo binary
 +TARGET=demo.prg
 +
 +# Original KERNAL
 +KERNAL=/usr/local/lib64/vice/C64/kernal
 +# Patched KERNAL
 +KERNAL_PATCHED=kernal-quick-memtest
 +
 +
 +# Default make target, just our binary
 +all: $(TARGET)
 +
 +
 +# Rule to assemble our binary and output labels for VICE
 +$(TARGET): demo.s
 + $(ASM) $(ASM_FLAGS) $(ASM_LABELS) -o $@ $<
 +
 +
 +# Rule to patch the KERNAL for quicker reset
 +$(KERNAL_PATCHED): $(KERNAL)
 + cp $(KERNAL) $(KERNAL_PATCHED)
 + echo "1d69: 9f" | xxd -r - $(KERNAL_PATCHED)
 +
 +
 +# Rule to start VICE with remote monitor, with patched KERNAl for quicker
 +# reset and running it in the background with any output of VICE redirected to
 +# log file files
 +session: $(KERNAL_PATCHED)
 + $(X64) $(X64_FLAGS) -remotemonitor -kernal $(KERNAL_PATCHED) \
 + 1>$(X64_STDOUT) 2>$(X64_STDERR) &
 +
 +
 +# Rule to inject the program file and run it
 +run: $(TARGET)
 + # reset machine and wait for 1 second after EOF from machine
 + echo 'reset 0' | netcat -q1 localhost 6510
 +
 + # optional: load labels (we have to wait for one second to allow the
 + # command to complete)
 + echo 'clear_labels' | netcat -q1 localhost 6510
 + echo 'load_labels "$(LABEL_FILE)"' | netcat localhost 6510
 +
 + # load binary
 + echo 'l "$(TARGET)" 0' | netcat localhost 6510
 + # run binary by putting 'RUN\r' into the keyboard buffer
 + echo 'f 0277 027a 52 55 4e 0d' | netcat localhost 6510
 + echo 'f 00c6 00c6 04' | netcat localhost 6510
 +        # now the BASIC interpreter notices it has data in its buffer and parses that,
 +        # resulting in a proper RUN being executed for our program. Even the KERNAL
 +        # itself does it, just look at $e5ee, the handler for Shift+Run/Stop
 +
 +
 +.PHONY: clean
 +clean:
 + rm -f $(KERNAL_PATCHED)
 + rm -f $(LABEL_FILE) $(X64_STDOUT) $(X64_STDERR)
 + rm -f $(TARGET)
 +</code>
 +
 +
 +More later..
 +
 +TODO:
 +  * attaching disk images
 +  * debugging via telnet
 +  * <del>writing a proper Makefile (perhaps putting all those echo's into a file, updating it with sed)</del>
 +  * VIM integration
 +
base/using_a_running_vice_session_for_development.1467134241.txt.gz · Last modified: 2016-06-28 19:17 by compyx