summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-11-17 19:12:00 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2020-11-17 19:12:00 +0100
commit63d0944063b6f240fe0c68ef9b61d4dd906d9fc1 (patch)
treefb083c1284fd6d58944b1961297c652dc32b515d
download6502-63d0944063b6f240fe0c68ef9b61d4dd906d9fc1.tar.gz
6502-63d0944063b6f240fe0c68ef9b61d4dd906d9fc1.tar.bz2
initial checkin
-rw-r--r--.gitignore5
-rw-r--r--FINDINGS11
-rw-r--r--LINKS97
-rw-r--r--README100
-rw-r--r--TODOS3
-rw-r--r--doc/6502_org_source_general_clockfreq.txt201
-rw-r--r--doc/www.ganssle.com_articles_anmi.txt409
-rw-r--r--roms/7seg_counter_irq_timer.asm112
-rw-r--r--roms/7seg_counter_reset_on_irq.asm89
-rw-r--r--roms/7seg_counter_reset_on_irq_delay.asm106
-rw-r--r--roms/7seg_print_one.asm62
-rw-r--r--roms/7seg_print_one_subroutine.asm66
-rw-r--r--roms/7segment_rom.hex128
-rw-r--r--roms/README24
-rw-r--r--roms/blinken_lights.asm14
-rw-r--r--roms/blinken_lights.hex128
-rw-r--r--roms/clear_zero_page.asm132
-rw-r--r--roms/counting_lights.asm13
-rw-r--r--roms/entry.hex128
-rw-r--r--roms/irqs_with_lcd1.asm132
-rw-r--r--roms/irqs_with_via.asm137
-rw-r--r--roms/lcd_no_ram.asm132
-rw-r--r--roms/lcd_with_ram.asm82
-rw-r--r--roms/lcd_with_ram_busy_check.asm112
-rw-r--r--roms/lcd_with_ram_busy_check_and_string_print.asm112
-rw-r--r--roms/read_write.hex128
-rw-r--r--roms/simple_ram_test.asm16
-rw-r--r--roms/simple_ram_test2.asm162
-rw-r--r--roms/wait.hex128
-rw-r--r--sketches/6502_addr_read.ino48
-rw-r--r--vga/README19
31 files changed, 3036 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..11c8ee9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+orders/*
+other/*
+rom.bin
+specs/*
+vga/specs/*
diff --git a/FINDINGS b/FINDINGS
new file mode 100644
index 0000000..1fc834f
--- /dev/null
+++ b/FINDINGS
@@ -0,0 +1,11 @@
+minipro -r x -p HT24LC256
+(I2C version of the ROM, not really usable for our purposes as we
+can not go via I2C!)
+
+sodering sockets are not for breadbaords, pins too weak and too short
+ZIF sockets
+
+
+ZIF sockets on breadboards
+UART chips
+http://www.stuartconner.me.uk/tms9995_breadboard/tms9995_breadboard.htm
diff --git a/LINKS b/LINKS
new file mode 100644
index 0000000..fefd03f
--- /dev/null
+++ b/LINKS
@@ -0,0 +1,97 @@
+GeckOS, Unix on 6502:
+http://www.6502.org/users/andre/osa/index.html
+
+eater.net: 6502 kit
+https://github.com/dpm-343/6502-monitor/blob/master/6502-monitor.ino
+
+other 6052:
+http://lateblt.tripod.com/6502prj1.htm
+74LS138 decoder IC (3to8)
+
+XA cross assembler
+http://www.floodgap.com/retrotech/xa/xa-old.html
+
+http://srecord.sourceforge.net/
+VIM xxd (hex to bin and vice versa)
+
+TL866II+ eeprom programmer
+https://gitlab.com/DavidGriffith/minipro/
+
+other projects
+http://www.stuartconner.me.uk/tms9995_breadboard/tms9995_breadboard.htm
+
+differences 6502 and 65c02:
+http://www.6502.org/tutorials/65c02opcodes.html
+
+https://jacob.jkrall.net/ps2-on-65c02
+PS/2 keyboard
+
+interrupts:
+http://www.ganssle.com/articles/anmi.htm
+
+UART:
+https://www.jameco.com/z/6551-Major-Brands-IC-6551-Asynchronous-Communication-Interface-Adapter-DIP-28-pin_43318.html
+
+assemblers for 6502:
+http://sun.hasenbraten.de/vasm/
+
+emulators for ben6502:
+https://github.com/alimansfield2016/ATM65C02_EMU, nice idea, c++ code quite bad
+https://github.com/alimansfield2016/ATM65C02_EMU.git, sadly in Javascript
+https://github.com/chanmix51/soft65c02, sadly in rust
+
+other/todo:
+https://news.ycombinator.com/item?id=22077052
+https://www.instructables.com/DIY-Paper-TapePunch
+http://wilsonminesco.com/BenchCPU/ (VIAs for all kind of external stuff)
+https://github.com/mist64/msbasic
+https://www.pagetable.com/?p=46
+
+documentation on old 8-bit logic:
+http://www.zimmers.net/anonftp/pub/cbm/documents/chipdata/index.html
+
+Geck/OS:
+http://www.6502.org/users/andre/csa/
+http://www.6502.org/users/andre/osa/index.html
+
+OS:
+https://github.com/janroesner/sixty5o2, uses Arduino and serial for loading programs,
+ good example of a bootloader assembly code, interrupt handling
+http://www.6502.org/users/andre/osa/oa1.html: OS/A65
+http://danceswithferrets.org/geekblog/?p=808 (monitor, http://exifpro.com/utils.html, emulator)
+
+7-segment:
+https://www.robotshop.com/community/forum/t/explaining-the-7-segment-display-and-74hc595-shift-register/13139
+https://www.eevblog.com/forum/projects/7-segment-hex-bus-display-with-eproms/
+https://www.youtube.com/watch?v=BA12Z7gQ4P0
+
+6502 links:
+https://www.eiroca.net/wiki/archive/awesome/6502
+http://wilsonminesco.com/
+
+practical stuff:
+https://www.instructables.com/Fix-a-broken-pin-on-an-IC-chip/
+DRY ZIF with paper and tape (george foot)
+
+other projects:
+http://minus56.com/
+https://www.chrisward.org.uk/6502/dev.shtml
+https://www.heiko-pruessing.de/projects/hbc65/
+https://c74project.com/ (a full 6502 in 74xx logic gates on PCB)
+https://github.com/Klaus2m5/6502_65C02_functional_tests (format tests and verification)
+
+delay/timers:
+https://gist.github.com/superjamie/fd80fabadf39199c97de400213f614e9
+http://6502org.wikidot.com/software-delay
+http://wilsonminesco.com/6502primer/PgmTips.html
+http://6502.org/source/general/clockfreq.htm
+http://wilsonminesco.com/6502interrupts/ (use VIA and NMI to produce a 10ms timer)
+
+software archives:
+http://6502.org/source/
+
+os:
+http://6502.org/source/kernels/minikernel.txt (timer and time slicing)
+
+apple emulator:
+https://damian.pecke.tt/2015/04/06/turning-the-arduino-uno-into-an-apple-ii.html
diff --git a/README b/README
new file mode 100644
index 0000000..1e513b8
--- /dev/null
+++ b/README
@@ -0,0 +1,100 @@
+history
+-------
+
+11.9.2020
+- ordered set at eater.net
+
+23.10.2020:
+- started the clock module, finish 24.10. morning
+
+24.10.2020:
+nops and introspection using Arduino Mega 2560
+sadly Archlinux32 arduino builder (avr gcc) segfaults, needs investigation
+(on 64-bit for now)
+started to struggle with the EEPROM programmer and minipro, ok in the end
+thoughts on using cheap 2k ROMs first instead of the 32k ROM
+
+25.10.2020:
+managed to program 2k EPROM, also able to set reset vector and start
+PROM software at f800
+
+27.10.2020:
+VIA chip works with blinken lights
+
+28.10.2020:
+broken clock (a missing ground with funny effects on the CLK line)
+another light example (counter)
+
+29.10.2020:
+working rom-only LCD display
+
+30.10.2020:
+added ram for zero page and call stack (just A0-A8, left all others
+floating with nice effects!), working LCD example with subroutines
+and RAM.
+
+1.11.2020:
+playing with interrupts
+clear memory
+strange memory test, write 255 zeroes to zero page, read, bne,
+getting distorted output (though we are not using ram!)
+VIA IRQ handling with capacitance cheapo debouncer on interrupt button.
+
+2.11.2020:
+soldered a pin to the broken EPPROM, works :-)
+playing with I/O peripherial data bus
+zif dry for broken EEPROM, works fine
+
+3.11.2020:
+new parts order
+
+4.11.2020:
+new parts order (check)
+some thinking on transistors for feeding two LEDs from on PROM
+
+5.11.2020:
+new breadboard
+did the 2-digit 7-segment display, currently unbuffered on the
+I/O data bus
+
+6.11.2020:
+shift register for 7-bit output via the VIA
+opcode decoding (from Ben Eaters 6502 monitor project)
+almost working counter with reset (on IRQ)
+found a bug in encoding of hex 'C' (which means, redo the thing)
+
+7.11.2020:
+fixed 'C' in 7-digit EEPROM
+stange BRK interrupts and RTIs to strange addresses -> floating
+address lines on RAM (again!), IRQ on VIA has to be acknowledged,
+otherwise it triggers constantly (so the counter seems to stop).
+playing with delays to make counter work correctly (somewhat).
+
+
+8.11.2020:
+using via timer1 for 10ms ticks, time counter increment instead of delay
+weird issue with TICK on $1 and COUNTER on $0, works fine with TICK $10,
+so again, a SRAM issue?
+working more on a SRAM test
+ordered SRAM at Reichelt, waiting
+
+11.11.2020:
+VGA kit arrived, some weird issues with payment (UPS, as usual)
+
+17.11.2020:
+new RAM, same problems
+VCC on counters stabilize the circuit on slow clock
+
+commands
+--------
+
+xxd -r rom.hex > rom.bin
+hexdump -C rom.bin
+minipro -w rom.bin -p AT28C16@DIP24
+minipro -m rom.bin -p AT28C16@DIP24
+minipro -r x -p AT28C16@DIP24
+cmp x rom.bin
+
+# -wdc02 for extensions
+vasm6502_oldstyle -wdc02 -x -wfail -chklabels -dotdir -o rom.bin -Fbin rom.asm
+
diff --git a/TODOS b/TODOS
new file mode 100644
index 0000000..c70ee2d
--- /dev/null
+++ b/TODOS
@@ -0,0 +1,3 @@
+DS1685 Dallas RTC
+DS1813 reset button
+
diff --git a/doc/6502_org_source_general_clockfreq.txt b/doc/6502_org_source_general_clockfreq.txt
new file mode 100644
index 0000000..389d8a3
--- /dev/null
+++ b/doc/6502_org_source_general_clockfreq.txt
@@ -0,0 +1,201 @@
+ [1][Return to Main Page]
+
+ Calculation of Clock Frequency by Leo Nechaev
+ [2][Up to Source Code Repository]
+ __________________________________________________________________
+
+ This program calculates the clock frequency of 6502-based system. The
+ result is stored in location 'Ticks' to 'Ticks+3' in BCD representation
+ ('Ticks' - 2 symbols before decimal point, 'Ticks+1' to 'Ticks+3' - 6
+ symbols after point), then result is sent via UART to the host (usually
+ PC with some kind of terminal programm).
+
+ With minimal modifications (deleting 'SED' and 'CLD' instructions,
+ changing ticks constants [from BCD to binary format], deleting
+ 'terminal' subroutines) it may be used to determine real speed of
+ processor.
+rgConfig = $6000 ; write: D6=1 - NMI is off, D6=0 - NMI is on
+rgStatus = $6000 ; read: D6=0 - UART is busy
+rgTxD = $5000 ; write: data to send via UART
+
+vcNMI = $FFFA
+
+Refresh = 450 ; NMI rate in Hz
+
+ ldx #<NMI ; installing the NMI vector
+ ldy #>NMI
+ stx vcNMI
+ sty vcNMI+1
+ lda #$40 ; on start NMI is off
+ sta InUse
+
+Again
+ lda #0
+ sta Flag
+ sta Ticks ; initializing counter
+ sta Ticks+1
+ sta Ticks+2
+ sta Ticks+3
+ lda #$FE ; initializing NMI counter (zeropoint minus 2 ti
+cks)
+ sta Timer
+ lda #$FF
+ sta Timer+1
+ lda InUse ; turn on NMI
+ and #$BF
+ sta rgConfig
+ sta InUse
+
+- bit Flag ; waiting for zeropoint minus 1 tick
+ bpl -
+ lda #0
+ sta Flag
+
+- bit Flag ; waiting for true zeropoint
+ bpl -
+ lda #0
+ sta Flag
+
+Main ; main counting cycle
+;number of ticks per command sum of ticks
+; v v
+ lda Ticks ;4
+ clc ;2 6
+ sed ;2 8
+ adc #$53 ;2 10
+ sta Ticks ;4 14
+ lda Ticks+1 ;4 18
+ adc #0 ;2 20
+ sta Ticks+1 ;4 24
+ lda Ticks+2 ;4 28
+ adc #0 ;2 30
+ sta Ticks+2 ;4 34
+ lda Ticks+3 ;4 38
+ adc #0 ;2 40
+ sta Ticks+3 ;4 44
+ cld ;2 46
+ bit Flag ;4 50
+ bpl Main ;3 53
+
+ lda #0 ;2
+ sta Flag ;4 6
+ lda Ticks ;4 10
+ clc ;2 12
+ sed ;2 14
+ adc #$95 ;2 16
+ sta Ticks ;4 20
+ lda Ticks+1 ;4 24
+ adc #0 ;2 26
+ sta Ticks+1 ;4 30
+ lda Ticks+2 ;4 34
+ adc #0 ;2 36
+ sta Ticks+2 ;4 40
+ lda Ticks+3 ;4 44
+ adc #0 ;2 46
+ sta Ticks+3 ;4 50
+ cld ;2 52
+ lda Timer ;4 56
+ cmp #<Refresh ;2 58
+ bne Main ;3 61 + 34 (from NMI ISR) = 95
+ lda Timer+1 ; 4
+ cmp #>Refresh ; 2
+ bne Main ; 3
+
+ lda InUse ; turn off NMI
+ ora #$40
+ sta rgConfig
+ sta InUse
+
+ ldx #0 ; send first string to the host
+- lda Mes1,x
+ beq +
+ jsr Send
+ inx
+ jmp -
+
++ lda Ticks+3
+ pha
+ lsr
+ lsr
+ lsr
+ lsr
+ beq + ; delete non-significant zero (clock < 10MHz)
+ jsr PrintDigit
++ pla
+ and #15
+ jsr PrintDigit
+ lda #"." ; decimal point
+ jsr Send
+ lda Ticks+2
+ jsr PrintTwoDigits
+ lda Ticks+1
+ jsr PrintTwoDigits
+ lda Ticks
+ jsr PrintTwoDigits
+
+ ldx #0 ; send second string to the host
+- lda Mes2,x
+ beq +
+ jsr Send
+ inx
+ jmp -
++ jmp Again ; repeat process
+
+PrintTwoDigits
+ pha
+ lsr
+ lsr
+ lsr
+ lsr
+ jsr PrintDigit
+ pla
+ and #15
+ jsr PrintDigit
+ rts
+
+PrintDigit
+ ora #$30
+ jsr Send
+ rts
+
+Send
+ bit rgStatus
+ bvc Send
+ sta rgTxD
+ rts
+
+Mes1
+ .db 13
+ .tx "Current clock frequency is "
+ .db 0
+
+Mes2
+ .tx " MHz"
+ .db 0
+
+Ticks .br 4,0
+Timer .br 2,0
+InUse .db 0
+Flag .db 0
+
+NMI ;6
+ pha ;3 9
+ inc Timer ;6 15
+ bne + ;3 18
+ inc Timer+1 ; 5
++ lda #$80 ;2 20
+ sta Flag ;4 24
+ pla ;4 28
+ rti ;6 34
+
+ Test results:
+ * with chip oscillator "1.8432" the result is '1.843266 MHz'
+ * with chip oscillator "20.000000M" and divider by 10 the result is
+ '2.000040 MHz'
+
+ Last page update: December 27, 2000.
+
+References
+
+ 1. http://6502.org/
+ 2. http://6502.org/source
diff --git a/doc/www.ganssle.com_articles_anmi.txt b/doc/www.ganssle.com_articles_anmi.txt
new file mode 100644
index 0000000..034ffdf
--- /dev/null
+++ b/doc/www.ganssle.com_articles_anmi.txt
@@ -0,0 +1,409 @@
+ [1]The Ganssle Group logo
+ [2]The Ganssle Group logo
+ * [3]Click here for a navigation menu
+
+ * [4]Firmware
+ Classes
+ + [5]Public Training
+ + [6]On-Site Training
+ * [7]Newsletter
+ + [8]Subscribe
+ + [9]Back Issues
+ * [10]Expert
+ Witness
+ * [11]Blog
+ * [12]Videos
+ * [13]Tool & Book
+ Reviews
+ + [14]Tool Reviews
+ + [15]Jack's Books
+ + [16]Other Embedded Books
+ * [17]Special
+ Reports
+ + [18]Designing Ultra-Low Power Systems
+ + [19]Surprising Scope Probe Issues
+ + [20]2020 Salary Survey
+ + [21]Debouncing Contacts
+ + [22]Watchdog Timers
+ + [23]Microprocessor History
+ + [24]Being a Consultant
+ + [25]Write-only Memory
+ + [26]Process Improvement for the Boss
+ + [27]Commenting Code
+ + [28]Testing RAM
+ + [29]Getting Into Embedded Work
+ + [30]Code Inspections
+ + [31]Automatic Bug-Finding
+ + [32]eXtreme Instrumenting
+ + [33]Math Approximations - Trig
+ + [34]Math Approximations - Other Functions
+ + [35]Better Resumes
+ * [36]Articles
+ + [37]All Articles
+ + [38]Analog, Filtering, etc
+ + [39]Communications
+ + [40]Debugging
+ + [41]Fun Embedded Stuff
+ + [42]Hardware
+ + [43]Historical
+ + [44]Managing Projects
+ + [45]Math in Computers
+ + [46]Memory
+ + [47]Philosophical and Career
+ + [48]Real Time
+ + [49]Software & Firmware
+ + [50]Tools for Embedded Developers
+ + [51]Sailing!
+ * [52]Random
+ Rants
+ + [53]Electronics
+ + [54]Business Issues
+ + [55]Software Engineering
+ + [56]Products and Reviews
+ + [57]Philosophy of Engineering
+ + [58]Miscellaneous
+ + [59]History of Electronics and Embedded
+ + [60]Software
+ + [61]Random Thoughts
+ + [62]Fun Stuff
+ + [63]Real-Time Issues
+ * [64]Humor
+ * [65]Contact/Search
+ + [66]Contact Info
+ + [67]Advertise With Us
+ + [68]Search This Site
+ + [69]Jack's Bio
+ + [70]Expert Witness
+ + [71]Our Privacy Policy
+
+The Perils of NMI
+
+ NMI is a critical resource, yet all too often it's misused.
+
+ Published in Embedded Systems Programming, April 1991
+ For novel ideas about building embedded systems (both hardware and
+ firmware), join the 40,000+ engineers who subscribe to [72]The Embedded
+ Muse, a free biweekly newsletter. The Muse has no hype and no vendor
+ PR. [73]Click here to subscribe.
+ LA104 Logic Analyzer October's giveaway is a LA104 mini logic analyzer.
+ I reviewed it in [74]Muse 406. .Enter the contest [75]here.
+
+By Jack Ganssle
+
+ Wise amateurs fear [76]interrupts. Fools go where wise men fear to
+ tread. Normal sequential code is hard enough to understand, code, and
+ debug. Toss in a handful of asyncronous events that randomly change the
+ processor's execution path, perhaps thousands of times per second, and
+ you have a recipe for disaster.
+
+ Yet interrupts are an important fact of life for all real time systems.
+ No experienced programmer would dream of replacing a clean interrupt
+ service routine with polled I/O, particularly where fast I/O response
+ is required.
+
+ In fact, interrupts are the both the best and worse microprocessor
+ feature. Well thought out interrupt-driven code will be reasonably easy
+ to write, debug and maintain. A poorly conceived interrupt routine is
+ probably the worst possible software to work on. Because interrupts are
+ so important to embedded systems, it is vital to become proficient with
+ their use.
+
+ If interrupts are tough to work with, then the non-maskable interrupt
+ (NMI) is the true killer of the business. Be careful before you connect
+ a peripheral to your processor's NMI input - think through the problems
+ carefully.
+
+ Almost every processor has some sort of NMI signal, though it may be
+ called something else. On the 68000, a level 7 interrupt cannot be
+ masked, and is equivalent to NMI. Some 8051-family CPUs have no
+ non-maskable interrupt, an idea that is sort of appealing in terms of
+ enforcing interrupt discipline.
+
+ I'm a firm believer in restricting NMI to those conditions that are
+ truly unusual and of momentous importance. Quite a few designers use
+ NMI as a general purpose interrupt, a practice that usually spells
+ disaster.
+
+ When timing gets tight, the code can easily disable a conventional
+ interrupt. Indeed, the very assertion of an interrupt signal
+ automatically turns all interrupts off until the software explicitly
+ reenables them, giving the code a clean window to process a high
+ priority task. Not so with NMI. An NMI at any time will interrupt the
+ CPU - no ifs, ands or buts. As long as the hardware supplies NMIs to
+ the processor, it will stop whatever it's doing and vector through the
+ NMI handler.
+
+ The very fact that NMI can never be disabled makes it ideal for
+ handling a small but vital class of extremely high priority events.
+ Chief among these is a power failure. If a system must die gracefully,
+ then hardware that detects the imminent loss of power can assert NMI to
+ let the software park disk heads, put moving sensors into a "safe"
+ state, copy important variables from RAM to non-volitile storage, and
+ generally prepare for being down.
+
+ Modern power supplies have little reserve capacity. Old linear designs
+ had massive filtering capacitors that acted like batteries with several
+ seconds of reserve capacity. Today's off-line switchers use
+ comparatively tiny capacitors; smart electronics does the filtering.
+ When the AC power goes down, the switcher's output quickly follows
+ suit.
+
+ During the short time it takes for power to trail away the code may
+ very well be executing with interrupts disabled. Only NMI is guaranteed
+ to be available at all times. Power fail is such an important event,
+ that NMI is really the only option for notifying the software of
+ power's impending demise.
+
+ Perhaps more should be said about power fail circuits at this point,
+ since so many suffer from serious design flaws. Most embedded systems
+ ignore power fail conditions. Running ROM based code with no dangerous
+ or critical external hardware, they can restart without harm from the
+ top when power resumes. However, two types of systems require
+ power-fail management hardware and software. The first category are
+ those systems controlling moving objects; a disk controller should park
+ the head, a robot should stop all motors, and an X-ray system should
+ shut down the beam.
+
+ The other class are systems that preserve transient data through a
+ power-up cycle. A data acquisition system might need to keep logged
+ data even when power goes down, an instrument sometimes has to save
+ painfully collected calibration constants, and a video game should
+ remember high scoring individuals' initials and totals.
+
+Decaying Power
+
+ Far too many designs rely on nothing more than battery backed up static
+ RAMs or some true non-volitile device like an EEPROM to store data
+ through multiple on/off cycles. More often than not these schemes work,
+ but all will sooner or later fail. Let's consider what happens when the
+ AC power fails.
+
+ Without AC, the power supply stops working. The computer continues to
+ run from the energy stored in the supply's output capacitor. The amount
+ of time left before the computer goes haywire is proportional to the
+ size of the capacitor in microfarads and inversely proportional
+
+ Until the computer's 5 volts decays to about 4.75 it continues to run
+ properly. At the 4.75 volt level most of the system's chips are no
+ longer operating in their design region. No one can predict what will
+ happen with any certainty.
+
+ At about 4.8 to 4.9 volts the well-designed power fail circuit will
+ inject an NMI into the computer (some detect missing AC cycles, a
+ better but more expensive approach). Probably the system has only
+ milleseconds before Vcc decays to the 4.75 volt region of instability.
+ The NMI routine should quickly shut down external events and save
+ critical variables.
+
+ After processing the power fail condition, the computer and external
+ I/O is all in a safe state. The voltage level continues to decline past
+ 4.75 volts, eventually reaching zero. Unfortunately, the supply's
+ capacitor decays exponentially. It will provide something between zero
+ and 4.75 volts for a comparatively long time (perhaps seconds).
+
+ What does the CPU chip, memories, and glue logic do with, say, 4 volts
+ applied? No one knows. No vendor will guarantee any behavior under the
+ 4.75 volt level. Frequently the program just runs wild, executing
+ practically random instructions. Your carefully saved data or
+ meticulously protected I/O could be destroyed by rogue instructions!
+
+ No power fail circuit is complete unless it clamps the reset line
+ whenever power is less than the magic 4.75 volt level. A suitable
+ circuit keeps the CPU in a reset state, preventing wild execution from
+ corrupting the efforts of the NMI power save routine. Motorola sells a
+ 3-terminal reset controller for less than a dollar which will hold
+ reset down in low Vcc conditions.
+
+ Consider another case: suppose the power grid's sadly overload
+ summertime generating capacity experiences a brownout. If the line
+ drops from 110 VAC to, say, 80 volts, what happens to the +5 volt
+ output from your system's power supply? Most likely it will go out of
+ regulation, giving perhaps 3 or 4 volts until the 110 input level is
+ reestablished. Hopefully the power fail circuit will assert an NMI to
+ the processor chip. Using the conventional resistor/capacitor unclamped
+ reset circuit, the reset input will decline only to the 3-4 volt level,
+ not nearly low enough to force a reset when power comes back.
+
+ The reset clamping circuit will not only keep the CPU in a safe state;
+ in this brownout case it will also insure that the system restarts
+ properly when +5 volts is reestablished.
+
+ Regardless, NMI is the only reasonable interrupt choice for power fail
+ detection.
+
+NMI Abuse
+
+ Unfortunately, NMI is widely abused as a general purpose interrupt. Use
+ NMI only for events that occur infrequently. Never substitute it for
+ poor design.
+
+ It's not too unusual to see a divider circuit driving NMI, generating
+ hundreds or thousands of interrupts per seconds. Usually these designs
+ start life using a reasonable maskable interrupt. As the programmers
+ debug the system they find the CPU occasionally misses an interrupt, so
+ they switch over to NMI. This is a mistake. If the code misses
+ interrupts, there is a fundamental flaw in its design that NMI will not
+ cure.
+
+ Your code will miss interrupts only if some bottleneck keeps them
+ disabled for too long. Always design the code to keep interrupts
+ disabled only while servicing the hardware. Reenable them as soon as
+ possible. With good reentrant design, interrupts should never be off
+ for more than a few tens of microseconds.
+
+On the Edge
+
+ Quite a few processors implement NMI as an edge sensitive interrupt.
+ This guarantees that even a breathtakingly short pulse will set the
+ CPU's internal NMI flip flop, so the interrupt simply cannot be missed.
+ It might, however, cause several kinds of nasty problems.
+
+ Suppose the input comes from the real world, perhaps after having been
+ transmitted a few feet. Without proper pulse shaping circuitry, the
+ signal could easily have ragged edges or even multiple, closely spaced
+ transitions. Maskable interrupts live quite happily with short bouncing
+ on their lines, since the first transition will make the processor
+ disable the input and start the ISR. Even the fastest code will take a
+ few microseconds to service and reenable the interrupt, by which time
+ the transients will be long gone. NMI cannot be disabled; every bit of
+ bounce will reinitiate the NMI service routine. The result: one real
+ interrupt might masquerade as several independent NMIs, each one
+ pushing onto the stack and recalling the ISR.
+
+ Edge sensitive inputs respond when the input voltage crosses some
+ threshold. Imperfect digital circuits give a rather broad window to the
+ threshold. If the NMI input signal is perfectly clean but moves slowly
+ from the idle to the asserted state, it stays within the threshold
+ region for far too long, sometimes causing multiple NMI triggers.
+
+ Finally, the edge sensitive nature of the NMI signal renders it
+ susceptible to every stray bit of electrical noise. A clean NMI driven
+ by a gate on the other side of a circuit board might pick up unexpected
+ noise from other parts of the circuit.
+
+ Edge sensitive NMI inputs must be clean, noise free, and should switch
+ quickly and cleanly.
+
+ Remember that debugging NMI service routines is sometimes tough. How
+ will you single step in an NMI service routine if, while debugging,
+ dozens more NMIs keep coming? Most of us debug code by stopping at a
+ breakpoint and looking at the registers and variables. If, when
+ debugging the NMI handler, another comes along while we're stopped,
+ after resuming execution the service routine will re-invoke itself,
+ probably corrupting a non-reentrant value.
+
+ In summary, NMI is a valuable feature. Don't abuse it; restrict its use
+ to those few situations where only an NMI will solve a problem.
+
+ Do you need to eliminate bugs in your firmware? Shorten schedules? My
+ [77]Better Firmware Faster seminar will teach your team how to operate
+ at a world-class level, producing code with far fewer bugs in less
+ time. It's fast-paced, fun, and covers the unique issues faced by
+ embedded developers. [78]Here's information about how this class,
+ taught at your facility, will measurably improve your team's
+ effectiveness.
+
+ Free Embedded Muse newsletter - twice/monthly, hard-hitting technical
+ info that goes to 40,000+ engineers. Click [79]here to sign up or enter
+ your email here:
+ ____________________ Submit
+
+ Latest [80]Embedded Muse: Replies to 'Is Assembly Dead' and 'on Taking
+ Charge'.
+
+ Latest [81]blog: Is a heart rate of 72,123 beats per minute possible?
+
+ [82][ganssle-dot-com-ad.jpg] Advertise with us! Reach 200K embedded
+ developers per month. More info [83]here.
+ __________________________________________________________________
+
+ The Ganssle Group - [84]info@ganssle.com - copyright TGG, all rights
+ reserved. Contact info [85]here.
+
+References
+
+ 1. http://www.ganssle.com/
+ 2. http://www.ganssle.com/
+ 3. http://www.ganssle.com/navigation.html
+ 4. http://www.ganssle.com/onsite.htm
+ 5. http://www.ganssle.com/classes.htm
+ 6. http://www.ganssle.com/onsite.htm
+ 7. http://www.ganssle.com/tem-subunsub.html
+ 8. http://www.ganssle.com/tem-subunsub.html
+ 9. http://www.ganssle.com/tem-back.htm
+ 10. http://www.ganssle.com/expertwitness.html
+ 11. http://www.ganssle.com/blog/index.html
+ 12. http://www.ganssle.com/video/video-list.html
+ 13. http://www.ganssle.com/tools.htm
+ 14. http://www.ganssle.com/tools.htm
+ 15. http://www.ganssle.com/book.htm
+ 16. http://www.ganssle.com/bkreviews.htm
+ 17. http://www.ganssle.com/spcl_reports.htm
+ 18. http://www.ganssle.com/reports/ultra-low-power-design.html
+ 19. http://www.ganssle.com/item/perils-of-scope-probes.html
+ 20. http://www.ganssle.com/salsurv2020.html
+ 21. http://www.ganssle.com/item/debouncing-switches-contacts-code.htm
+ 22. http://www.ganssle.com/item/great-watchdog-timers.htm
+ 23. http://www.ganssle.com/item/history-of-the-microprocessor.html
+ 24. http://www.ganssle.com/item/becoming-a-consultant.htm
+ 25. http://www.ganssle.com/misc/wom.html
+ 26. http://www.ganssle.com/item/guide-to-managing-firmware-teams.htm
+ 27. http://www.ganssle.com/item/writing-great-comments-firmware.htm
+ 28. http://www.ganssle.com/item/how-to-test-ram.htm
+ 29. http://www.ganssle.com/item/becoming-an-embedded-developer.htm
+ 30. http://www.ganssle.com/inspections.htm
+ 31. http://www.ganssle.com/item/automatically-debugging-firmware.htm
+ 32. http://www.ganssle.com/item/instrumenting-firmware-for-debugging.htm
+ 33. http://www.ganssle.com/item/approximations-for-trig-c-code.htm
+ 34. http://www.ganssle.com/item/approximations-c-code-exponentiation-log.htm
+ 35. http://www.ganssle.com/item/creating-great-resumes.htm
+ 36. http://www.ganssle.com/articles-subj.htm
+ 37. http://www.ganssle.com/articles.htm
+ 38. http://www.ganssle.com/articles-subj.htm
+ 39. http://www.ganssle.com/articles-subj.htm#Communications
+ 40. http://www.ganssle.com/articles-subj.htm#Debugging
+ 41. http://www.ganssle.com/articles-subj.htm#Fun
+ 42. http://www.ganssle.com/articles-subj.htm#Hardware
+ 43. http://www.ganssle.com/articles-subj.htm#Historical
+ 44. http://www.ganssle.com/articles-subj.htm#Managing
+ 45. http://www.ganssle.com/articles-subj.htm#Math
+ 46. http://www.ganssle.com/articles-subj.htm#Memory
+ 47. http://www.ganssle.com/articles-subj.htm#Philosophical
+ 48. http://www.ganssle.com/articles-subj.htm#realtime
+ 49. http://www.ganssle.com/articles-subj.htm#Processes
+ 50. http://www.ganssle.com/articles-subj.htm#Tools
+ 51. http://www.ganssle.com/jack/
+ 52. http://www.ganssle.com/randomrants.htm
+ 53. http://www.ganssle.com/randomrants.htm#electronics
+ 54. http://www.ganssle.com/randomrants.htm#business
+ 55. http://www.ganssle.com/randomrants.htm#softwareengineering
+ 56. http://www.ganssle.com/randomrants.htm#products
+ 57. http://www.ganssle.com/randomrants.htm#philosophy
+ 58. http://www.ganssle.com/randomrants.htm#misc
+ 59. http://www.ganssle.com/randomrants.htm#history
+ 60. http://www.ganssle.com/randomrants.htm#software
+ 61. http://www.ganssle.com/randomrants.htm#random
+ 62. http://www.ganssle.com/randomrants.htm#fun
+ 63. http://www.ganssle.com/randomrants.htm#realtime
+ 64. http://www.ganssle.com/jokes.htm
+ 65. http://www.ganssle.com/contact.htm
+ 66. http://www.ganssle.com/contact.htm
+ 67. http://www.ganssle.com/advertise.html
+ 68. http://www.ganssle.com/search/search.html
+ 69. http://www.ganssle.com/bio.htm
+ 70. http://www.ganssle.com/expertwitness.html
+ 71. http://www.ganssle.com/privacy-policy.html
+ 72. http://www.ganssle.com/tem-subunsub.html
+ 73. http://www.ganssle.com/tem-subunsub.html
+ 74. http://www.ganssle.com/tem/tem406.html#article4
+ 75. http://www.ganssle.com/contest.html
+ 76. http://www.ganssle.com/articles/aintrp.htm
+ 77. http://www.ganssle.com/onsite.htm
+ 78. http://www.ganssle.com/onsite.htm
+ 79. http://www.ganssle.com/tem-subunsub.html
+ 80. http://www.ganssle.com/tem/tem407.html
+ 81. http://www.ganssle.com/blog/blog/heart-rate.html
+ 82. http://www.ganssle.com/advertise.html
+ 83. http://www.ganssle.com/advertise.html
+ 84. mailto:info@ganssle.com
+ 85. http://www.ganssle.com/contact.htm
diff --git a/roms/7seg_counter_irq_timer.asm b/roms/7seg_counter_irq_timer.asm
new file mode 100644
index 0000000..29a3b54
--- /dev/null
+++ b/roms/7seg_counter_irq_timer.asm
@@ -0,0 +1,112 @@
+PORTA = $6001
+DDRA = $6003
+T1LCL = $6004
+T1LCH = $6005
+ACR = $600b
+PCR = $600c
+IER = $600e
+IFR = $600f
+
+SER = %00000001
+RCLK = %00000010
+SRCLK = %00000100
+
+INTERVAL = 33 ; increase counter 3 times per scond
+
+COUNTER = $0 ; visible counter
+TICKS = $3 ; internal ticks counter (on overflow increment counter)
+
+ .org #$f800
+
+reset:
+ sei ; disallow interrupts during initialization
+
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ lda #%11000010 ; enable CA1 and timer1 interrupts
+ sta IER
+ lda #$0 ; negative edge triggering
+ sta PCR
+
+ lda ACR
+ AND #$7F
+ ORA #%01000000 ; setup timer for free running timer1, no PB7
+ sta ACR
+
+ lda #%00000111 ; set output on 7seg control pins of PORTA
+ sta DDRA
+
+ lda #$0 ; initialize 8-bit counter and tick counter
+ sta COUNTER
+ lda #INTERVAL
+ sta TICKS
+
+ lda ACR
+
+ lda #$0F ; initialize counter of VIA timer1 ($270f = 9999 at 1MHz)
+ sta T1LCL
+ lda #$27
+ sta T1LCH
+
+ cli ; allow interrupts now
+
+mainloop: ; main loop, just print value of counter
+ lda COUNTER
+ jsr print7seg
+ jmp mainloop
+
+print7seg:
+ ldy #$8 ; 8 bits to shift
+loop7seg:
+ rol a
+ bcc zerobit ; C=0, bang a zero to SER
+onebit:
+ ldx #(SER) ; C=1, bang a one to SER
+ stx PORTA
+ ldx #(SER | SRCLK)
+ stx PORTA
+ ldx #(SER)
+ stx PORTA
+ jmp next
+zerobit:
+ ldx #$0 ; C=0, bang a zero to SER
+ stx PORTA
+ ldx #SRCLK
+ stx PORTA
+ ldx #$0
+ stx PORTA
+ jmp next
+next:
+ dey
+ bne loop7seg
+ rol a ; restore A register
+output:
+ ldx #0 ; bang RCLK to store output in latch
+ stx PORTA
+ ldx #RCLK
+ stx PORTA
+ ldx #0
+ stx PORTA
+ rts
+
+nmi:
+ rti
+
+irq:
+ pha
+ bit T1LCL ; clear timer1 interrupt
+ bit PORTA ; clear CA1 interrupt
+ dec TICKS
+ bne irq_done
+ lda #INTERVAL
+ sta TICKS
+ inc COUNTER
+irq_done:
+ pla
+ rti
+
+ .org #$fffa
+ .word nmi
+ .word reset
+ .word irq
diff --git a/roms/7seg_counter_reset_on_irq.asm b/roms/7seg_counter_reset_on_irq.asm
new file mode 100644
index 0000000..b7581e8
--- /dev/null
+++ b/roms/7seg_counter_reset_on_irq.asm
@@ -0,0 +1,89 @@
+PORTA = $6001
+DDRA = $6003
+PCR = $600c
+IER = $600e
+
+SER = %00000001
+RCLK = %00000010
+SRCLK = %00000100
+
+COUNTER = $0
+
+ .org #$f800
+
+reset:
+ sei ; disallow interrupts during initialization
+
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ lda #%10000010 ; enable CA1 interrupt
+ sta IER
+ lda #$0 ; negative edge triggering
+ sta PCR
+
+ ldx #%00000111 ; set output on 7seg control pins of PORTA
+ stx DDRA
+
+ ldx $0 ; initialize 8-bit counter
+ stx COUNTER
+
+ cli ; allow interrupts now
+
+mainloop: ; main loop, load counter and print it
+ sei
+ inc COUNTER
+ lda COUNTER
+ cli
+ jsr print7seg
+ jmp mainloop
+
+print7seg:
+ ldy #$8 ; 8 bits to shift
+loop7seg:
+ rol a
+ bcc zerobit ; C=0, bang a zero to SER
+onebit:
+ ldx #(SER) ; C=1, bang a one to SER
+ stx PORTA
+ ldx #(SER | SRCLK)
+ stx PORTA
+ ldx #(SER)
+ stx PORTA
+ jmp next
+zerobit:
+ ldx #$0 ; C=0, bang a zero to SER
+ stx PORTA
+ ldx #SRCLK
+ stx PORTA
+ ldx #$0
+ stx PORTA
+ jmp next
+next:
+ dey
+ bne loop7seg
+ rol a ; restore A register
+output:
+ ldx #0 ; bang RCLK to store output in latch
+ stx PORTA
+ ldx #RCLK
+ stx PORTA
+ ldx #0
+ stx PORTA
+ rts
+
+nmi:
+ rti
+
+irq:
+ pha
+ bit PORTA ; clear interrupt on port A
+ lda #$0
+ sta COUNTER ; reset counter
+ pla
+ rti
+
+ .org #$fffa
+ .word nmi
+ .word reset
+ .word irq
diff --git a/roms/7seg_counter_reset_on_irq_delay.asm b/roms/7seg_counter_reset_on_irq_delay.asm
new file mode 100644
index 0000000..007402e
--- /dev/null
+++ b/roms/7seg_counter_reset_on_irq_delay.asm
@@ -0,0 +1,106 @@
+PORTA = $6001
+DDRA = $6003
+PCR = $600c
+IER = $600e
+
+SER = %00000001
+RCLK = %00000010
+SRCLK = %00000100
+
+COUNTER = $0
+
+ .org #$f800
+
+reset:
+ sei ; disallow interrupts during initialization
+
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ lda #%10000010 ; enable CA1 interrupt
+ sta IER
+ lda #$0 ; negative edge triggering
+ sta PCR
+
+ ldx #%00000111 ; set output on 7seg control pins of PORTA
+ stx DDRA
+
+ ldx #$0 ; initialize 8-bit counter
+ stx COUNTER
+
+ cli ; allow interrupts now
+
+mainloop: ; main loop, load counter and print it
+ jsr print7seg
+ ldx #0 ; ca 500'000 cycles, at 1 Mhz 2 ticks per second
+ ldy #0
+ lda #150
+ jsr delay
+ inc COUNTER
+ lda COUNTER
+ jmp mainloop
+
+print7seg:
+ ldy #$8 ; 8 bits to shift
+loop7seg:
+ rol a
+ bcc zerobit ; C=0, bang a zero to SER
+onebit:
+ ldx #(SER) ; C=1, bang a one to SER
+ stx PORTA
+ ldx #(SER | SRCLK)
+ stx PORTA
+ ldx #(SER)
+ stx PORTA
+ jmp next
+zerobit:
+ ldx #$0 ; C=0, bang a zero to SER
+ stx PORTA
+ ldx #SRCLK
+ stx PORTA
+ ldx #$0
+ stx PORTA
+ jmp next
+next:
+ dey
+ bne loop7seg
+ rol a ; restore A register
+output:
+ ldx #0 ; bang RCLK to store output in latch
+ stx PORTA
+ ldx #RCLK
+ stx PORTA
+ ldx #0
+ stx PORTA
+ rts
+
+; delay 18+13(65536Y+256A+X) cycles
+delay:
+ iny
+delay1:
+ nop
+ nop
+delay2:
+ cpx #$1
+ dex
+ sbc #$0
+ bcs delay1
+ dey
+ bne delay2
+ rts
+
+nmi:
+ rti
+
+irq:
+ pha
+ bit PORTA ; clear interrupt on port A
+ lda #$0
+ sta COUNTER ; reset counter
+ pla
+ rti
+
+ .org #$fffa
+ .word nmi
+ .word reset
+ .word irq
diff --git a/roms/7seg_print_one.asm b/roms/7seg_print_one.asm
new file mode 100644
index 0000000..00725ef
--- /dev/null
+++ b/roms/7seg_print_one.asm
@@ -0,0 +1,62 @@
+PORTA = $6001
+DDRA = $6003
+
+SER = %00000001
+RCLK = %00000010
+SRCLK = %00000100
+
+ .org #$f800
+
+reset:
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ ldx #%00000111 ; set output on 7seg control pins of PORTA
+ stx DDRA
+
+ lda #$a5 ; 10100101, data to show
+ ldy #$8 ; 8 bits to shift
+loop:
+ rol a
+ bcc zerobit ; C=0, bang a zero to SER
+onebit:
+ ldx #(SER) ; C=1, bang a one to SER
+ stx PORTA
+ ldx #(SER | SRCLK)
+ stx PORTA
+ ldx #(SER)
+ stx PORTA
+ jmp next
+zerobit:
+ ldx #$0 ; C=0, bang a zero to SER
+ stx PORTA
+ ldx #SRCLK
+ stx PORTA
+ ldx #$0
+ stx PORTA
+ jmp next
+next:
+ dey
+ bne loop
+
+output:
+ ldx #0 ; bang RCLK to store output in latch
+ stx PORTA
+ ldx #RCLK
+ stx PORTA
+ ldx #0
+ stx PORTA
+
+term:
+ jmp term
+
+nmi:
+ rti
+
+irq:
+ rti
+
+ .org #$fffa
+ .word nmi
+ .word reset
+ .word irq
diff --git a/roms/7seg_print_one_subroutine.asm b/roms/7seg_print_one_subroutine.asm
new file mode 100644
index 0000000..4a1839f
--- /dev/null
+++ b/roms/7seg_print_one_subroutine.asm
@@ -0,0 +1,66 @@
+PORTA = $6001
+DDRA = $6003
+
+SER = %00000001
+RCLK = %00000010
+SRCLK = %00000100
+
+ .org #$f800
+
+reset:
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ ldx #%00000111 ; set output on 7seg control pins of PORTA
+ stx DDRA
+
+ lda #$a5 ; 10100101, data to show
+ jsr print7seg
+
+print7seg:
+ ldy #$8 ; 8 bits to shift
+loop:
+ rol a
+ bcc zerobit ; C=0, bang a zero to SER
+onebit:
+ ldx #(SER) ; C=1, bang a one to SER
+ stx PORTA
+ ldx #(SER | SRCLK)
+ stx PORTA
+ ldx #(SER)
+ stx PORTA
+ jmp next
+zerobit:
+ ldx #$0 ; C=0, bang a zero to SER
+ stx PORTA
+ ldx #SRCLK
+ stx PORTA
+ ldx #$0
+ stx PORTA
+ jmp next
+next:
+ dey
+ bne loop
+ rol a ; restore A register
+output:
+ ldx #0 ; bang RCLK to store output in latch
+ stx PORTA
+ ldx #RCLK
+ stx PORTA
+ ldx #0
+ stx PORTA
+ rts
+
+term:
+ jmp term
+
+nmi:
+ rti
+
+irq:
+ rti
+
+ .org #$fffa
+ .word nmi
+ .word reset
+ .word irq
diff --git a/roms/7segment_rom.hex b/roms/7segment_rom.hex
new file mode 100644
index 0000000..6781ac3
--- /dev/null
+++ b/roms/7segment_rom.hex
@@ -0,0 +1,128 @@
+00000000: 7e48 3d6d 4b67 774c 7f6f 5f73 3679 3717 ................
+00000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000100: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000110: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000120: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000130: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000140: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000150: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000160: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000170: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000180: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000190: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000001a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000001b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000001c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000001d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000001e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000001f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000200: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000210: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000220: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000230: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000240: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000250: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000260: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000270: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000280: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000290: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000002a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000002b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000002c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000002d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000002e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000002f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000300: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000310: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000320: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000330: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000340: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000350: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000360: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000370: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000380: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000390: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000003a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000003b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000003c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000003d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000003e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000003f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000400: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000410: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000420: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000430: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000440: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000450: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000460: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000470: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000480: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000490: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000004a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000004b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000004c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000004d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000004e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000004f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000500: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000510: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000520: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000530: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000540: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000550: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000560: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000570: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000580: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000590: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000005a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000005b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000005c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000005d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000005e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000005f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000600: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000610: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000620: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000630: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000640: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000650: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000660: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000670: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000680: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000690: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000006a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000006b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000006c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000006d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000006e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000006f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000700: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000710: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000720: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000730: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000740: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000750: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000760: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000770: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000780: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+00000790: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000007a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000007b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000007c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000007d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000007e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
+000007f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
diff --git a/roms/README b/roms/README
new file mode 100644
index 0000000..9ba01d1
--- /dev/null
+++ b/roms/README
@@ -0,0 +1,24 @@
+entry.hex - base minimal, set reset vector to $f800 and execute only nops
+read_write.hex - read/write value on bus, to test Arduino Mega monitor
+blinken_lights.asm - alternating $55 and $aa patterns on via to test data port
+blinken_lights.hex - same as blinken_lights.asm in HEX only (no assembler)
+clear_zero_page.asm - deterministic LCD test with clearing zero page in RAM
+counting_lights.asm - binary counter, 8 LEDS on VIA
+irqs_with_lcd1.asm - IRQ/NMIs directly on button
+irqs_with_via.asm - IRQ handshaked on CA1
+lcd_no_ram.asm - primitive output on LCD, no RAM chip
+lcd_with_ram.asm - output on LCD, RAM chip with zero and stack page (512 bytes)
+lcd_with_ram_busy_check_and_string_print.asm - better code
+lcd_with_ram_busy_check.asm - busy check on LCD, needed for 1MHz to work
+simple_ram_test2.asm - test zero page by writting and reading to it, print ok/nok
+ result to LCD
+simple_ram_test.asm - test $ff ram address continuously by writing and reading
+ a counter variable from there (to debug RAM on Mega monitor)
+wait.hex - test 65C02 WAI special opcode
+7segment_rom.hex - ROM for 7-segment display, 16 digits from 0-f
+ address of EPROM is binary input, output is
+ pins of 7-segment display
+7seg_print_one.asm - print $a5 (10100101) on 7-seg display
+7seg_print_one_subroutine.asm - same as 7seg_print_one.asm with a subroutine
+7seg_counter_reset_on_irq.asm - counter, reset on IRQ (usable at 1 KHz)
+7seg_counter_reset_on_irq_delay.asm - counter, reset on ORQ (usable at 1 MHz)
diff --git a/roms/blinken_lights.asm b/roms/blinken_lights.asm
new file mode 100644
index 0000000..90f04e8
--- /dev/null
+++ b/roms/blinken_lights.asm
@@ -0,0 +1,14 @@
+ .org #$f800
+reset:
+ lda #$ff
+ sta $6002
+loop:
+ lda #$55
+ sta $6000
+ lda #$aa
+ sta $6000
+ jmp loop
+
+ .org #$fffc
+ .word reset
+ .word $0000
diff --git a/roms/blinken_lights.hex b/roms/blinken_lights.hex
new file mode 100644
index 0000000..ea347e2
--- /dev/null
+++ b/roms/blinken_lights.hex
@@ -0,0 +1,128 @@
+00000000: a9ff 8d02 60a9 558d 0060 a9aa 8d00 604c ................
+00000010: 05f8 eaea eaea eaea eaea eaea eaea eaea ................
+00000020: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000030: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000040: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000050: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000060: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000070: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000080: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000090: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000100: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000110: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000120: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000130: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000140: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000150: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000160: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000170: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000180: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000190: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000200: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000210: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000220: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000230: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000240: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000250: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000260: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000270: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000280: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000290: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000300: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000310: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000320: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000330: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000340: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000350: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000360: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000370: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000380: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000390: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000400: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000410: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000420: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000430: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000440: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000450: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000460: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000470: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000480: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000490: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000500: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000510: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000520: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000530: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000540: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000550: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000560: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000570: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000580: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000590: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000600: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000610: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000620: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000630: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000640: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000650: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000660: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000670: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000680: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000690: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000700: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000710: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000720: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000730: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000740: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000750: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000760: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000770: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000780: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000790: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007f0: eaea eaea eaea eaea eaea eaea 00f8 eaea ................
diff --git a/roms/clear_zero_page.asm b/roms/clear_zero_page.asm
new file mode 100644
index 0000000..36fa1df
--- /dev/null
+++ b/roms/clear_zero_page.asm
@@ -0,0 +1,132 @@
+PORTB = $6000
+PORTA = $6001
+DDRB = $6002
+DDRA = $6003
+
+E = %10000000
+RW = %01000000
+RS = %00100000
+
+ .org #$f800
+
+reset:
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ lda #%11111111 ; set output on all pins of PORTB
+ sta DDRB
+
+ lda #%11100000 ; set output on LCD control pins of PORTA
+ sta DDRA
+
+ lda #%00111000 ; set 8-bit, 2-line display, 5x8 font
+ jsr lcd_send_command
+
+ lda #%00001110 ; display on, cursor on, no blink
+ jsr lcd_send_command
+
+ lda #%00000001 ; clear display
+ jsr lcd_send_command
+
+ lda #%00000010 ; return home
+ jsr lcd_send_command
+
+ lda #%00000110 ; set entry mode: increment, no shift
+ jsr lcd_send_command
+
+clear_memory_start:
+ lda #0
+ ldx #$FF
+ ldy #0
+clear_memory_loop:
+ sta $0, y
+ iny
+ dex
+ bne clear_memory_loop
+
+ ldx #0
+msg_loop:
+ lda message_memory_clear, x
+ beq msg_end
+ jsr lcd_send_data
+ inx
+ jmp msg_loop
+msg_end:
+
+finish:
+ jmp finish
+
+term:
+ jmp term
+
+lcd_wait:
+ pha
+ lda #%00000000 ; port B to all input
+ sta DDRB
+
+lcd_wait_loop:
+ lda #RW
+ sta PORTA
+
+ lda #(RW | E)
+ sta PORTA
+
+ lda PORTB
+ and #%10000000
+ bne lcd_wait_loop
+
+ lda #RW
+ sta PORTA
+ lda #%11111111 ; port B back to output
+ sta DDRB
+
+ pla
+ rts
+
+lcd_send_command:
+
+ jsr lcd_wait
+
+ sta PORTB
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #E ; clear RS/RW, set E, send instruction
+ sta PORTA
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ rts
+
+lcd_send_data:
+
+ jsr lcd_wait
+
+ sta PORTB ; data to send to port B
+
+ lda #RS ; clear RW, E, set RS for data
+ sta PORTA
+
+ lda #( E | RS ) ; clear RW, set E/RS, send data
+ sta PORTA
+
+ lda #RS ; clear RS, E, keep RS
+ sta PORTA
+
+ rts
+
+nmi:
+ rti
+
+irq:
+ rti
+
+message_memory_clear:
+ .asciiz "memory cleared"
+
+ .org #$fffa
+ .word nmi
+ .word reset
+ .word irq
diff --git a/roms/counting_lights.asm b/roms/counting_lights.asm
new file mode 100644
index 0000000..30423cf
--- /dev/null
+++ b/roms/counting_lights.asm
@@ -0,0 +1,13 @@
+ .org #$f800
+reset:
+ lda #$ff
+ sta $6002
+ ldx #$0
+loop:
+ stx $6000
+ inx
+ jmp loop
+
+ .org #$fffc
+ .word reset
+ .word $0000
diff --git a/roms/entry.hex b/roms/entry.hex
new file mode 100644
index 0000000..35e2c57
--- /dev/null
+++ b/roms/entry.hex
@@ -0,0 +1,128 @@
+00000000: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000010: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000020: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000030: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000040: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000050: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000060: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000070: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000080: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000090: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000100: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000110: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000120: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000130: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000140: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000150: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000160: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000170: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000180: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000190: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000200: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000210: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000220: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000230: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000240: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000250: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000260: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000270: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000280: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000290: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000300: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000310: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000320: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000330: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000340: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000350: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000360: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000370: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000380: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000390: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000400: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000410: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000420: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000430: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000440: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000450: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000460: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000470: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000480: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000490: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000500: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000510: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000520: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000530: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000540: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000550: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000560: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000570: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000580: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000590: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000600: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000610: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000620: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000630: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000640: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000650: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000660: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000670: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000680: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000690: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000700: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000710: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000720: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000730: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000740: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000750: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000760: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000770: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000780: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000790: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007f0: eaea eaea eaea eaea eaea eaea 00f8 eaea ................
diff --git a/roms/irqs_with_lcd1.asm b/roms/irqs_with_lcd1.asm
new file mode 100644
index 0000000..0abb040
--- /dev/null
+++ b/roms/irqs_with_lcd1.asm
@@ -0,0 +1,132 @@
+PORTB = $6000
+PORTA = $6001
+DDRB = $6002
+DDRA = $6003
+
+E = %10000000
+RW = %01000000
+RS = %00100000
+
+ .org #$f800
+
+reset:
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ lda #%11111111 ; set output on all pins of PORTB
+ sta DDRB
+
+ lda #%11100000 ; set output on LCD control pins of PORTA
+ sta DDRA
+
+ lda #%00111000 ; set 8-bit, 2-line display, 5x8 font
+ jsr lcd_send_command
+
+ lda #%00001110 ; display on, cursor on, no blink
+ jsr lcd_send_command
+
+ lda #%00000001 ; clear display
+ jsr lcd_send_command
+
+ lda #%00000010 ; return home
+ jsr lcd_send_command
+
+ lda #%00000110 ; set entry mode: increment, no shift
+ jsr lcd_send_command
+
+ cli ; allow interrupts now, LCD is ready
+
+msg_again:
+ ldx #0
+msg_loop:
+ lda message, x ; string to send
+ beq msg_end
+ jsr lcd_send_data
+ inx
+ jmp msg_loop
+msg_end:
+
+ jmp msg_again
+
+term:
+ jmp term
+
+lcd_wait:
+ pha
+ lda #%00000000 ; port B to all input
+ sta DDRB
+
+lcd_wait_loop:
+ lda #RW
+ sta PORTA
+
+ lda #(RW | E)
+ sta PORTA
+
+ lda PORTB
+ and #%10000000
+ bne lcd_wait_loop
+
+ lda #RW
+ sta PORTA
+ lda #%11111111 ; port B back to output
+ sta DDRB
+
+ pla
+ rts
+
+lcd_send_command:
+
+ jsr lcd_wait
+
+ sta PORTB
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #E ; clear RS/RW, set E, send instruction
+ sta PORTA
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ rts
+
+lcd_send_data:
+
+ jsr lcd_wait
+
+ sta PORTB ; data to send to port B
+
+ lda #RS ; clear RW, E, set RS for data
+ sta PORTA
+
+ lda #( E | RS ) ; clear RW, set E/RS, send data
+ sta PORTA
+
+ lda #RS ; clear RS, E, keep RS
+ sta PORTA
+
+ rts
+
+nmi:
+ pha
+ lda #'I'
+ jsr lcd_send_data
+ pla
+ rti
+
+irq:
+ pha
+ lda #'i'
+ jsr lcd_send_data
+ pla
+ rti
+
+message:
+ .asciiz "6502 "
+
+ .org #$fffa
+ .word nmi
+ .word reset
+ .word irq
diff --git a/roms/irqs_with_via.asm b/roms/irqs_with_via.asm
new file mode 100644
index 0000000..4a8d5f8
--- /dev/null
+++ b/roms/irqs_with_via.asm
@@ -0,0 +1,137 @@
+PORTB = $6000
+PORTA = $6001
+DDRB = $6002
+DDRA = $6003
+PCR = $600c
+IFR = $600d
+IER = $600e
+
+E = %10000000
+RW = %01000000
+RS = %00100000
+
+ .org #$f800
+
+reset:
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ lda #%10000010 ; enable CA1 interrupt
+ sta IER
+ lda #$0 ; negative edge triggering
+ sta PCR
+
+ lda #%11111111 ; set output on all pins of PORTB
+ sta DDRB
+
+ lda #%11100000 ; set output on LCD control pins of PORTA
+ sta DDRA
+
+ lda #%00111000 ; set 8-bit, 2-line display, 5x8 font
+ jsr lcd_send_command
+
+ lda #%00001110 ; display on, cursor on, no blink
+ jsr lcd_send_command
+
+ lda #%00000001 ; clear display
+ jsr lcd_send_command
+
+ lda #%00000010 ; return home
+ jsr lcd_send_command
+
+ lda #%00000110 ; set entry mode: increment, no shift
+ jsr lcd_send_command
+
+ cli ; allow interrupts now, LCD is ready
+
+msg_again:
+ ldx #0
+msg_loop:
+ lda message, x ; string to send
+ beq msg_end
+ jsr lcd_send_data
+ inx
+ jmp msg_loop
+msg_end:
+
+ jmp msg_again
+
+term:
+ jmp term
+
+lcd_wait:
+ pha
+ lda #%00000000 ; port B to all input
+ sta DDRB
+
+lcd_wait_loop:
+ lda #RW
+ sta PORTA
+
+ lda #(RW | E)
+ sta PORTA
+
+ lda PORTB
+ and #%10000000
+ bne lcd_wait_loop
+
+ lda #RW
+ sta PORTA
+ lda #%11111111 ; port B back to output
+ sta DDRB
+
+ pla
+ rts
+
+lcd_send_command:
+
+ jsr lcd_wait
+
+ sta PORTB
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #E ; clear RS/RW, set E, send instruction
+ sta PORTA
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ rts
+
+lcd_send_data:
+
+ jsr lcd_wait
+
+ sta PORTB ; data to send to port B
+
+ lda #RS ; clear RW, E, set RS for data
+ sta PORTA
+
+ lda #( E | RS ) ; clear RW, set E/RS, send data
+ sta PORTA
+
+ lda #RS ; clear RS, E, keep RS
+ sta PORTA
+
+ rts
+
+nmi:
+ rti
+
+irq:
+ pha
+ lda #'i'
+ jsr lcd_send_data
+ pla
+ bit PORTA ; clear interrupt on port A
+ rti
+
+message:
+ .asciiz "6502 "
+
+ .org #$fffa
+ .word nmi
+ .word reset
+ .word irq
diff --git a/roms/lcd_no_ram.asm b/roms/lcd_no_ram.asm
new file mode 100644
index 0000000..7616dcf
--- /dev/null
+++ b/roms/lcd_no_ram.asm
@@ -0,0 +1,132 @@
+PORTB = $6000
+PORTA = $6001
+DDRB = $6002
+DDRA = $6003
+
+E = %10000000
+RW = %01000000
+RS = %00100000
+
+ .org #$f800
+
+reset:
+ lda #%11111111 ; set output on all pins of PORTB
+ sta DDRB
+
+ lda #%11100000 ; set output on LCD control pins of PORTA
+ sta DDRA
+
+ lda #%00111000 ; set 8-bit, 2-line display, 5x8 font
+ sta PORTB
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #E ; clear RS/RW, set E, send instruction
+ sta PORTA
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #%00001110 ; display on, cursor on, no blink
+ sta PORTB
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #E ; clear RS/RW, set E, send instruction
+ sta PORTA
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #%00000001 ; clear display
+ sta PORTB
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #E ; clear RS/RW, set E, send instruction
+ sta PORTA
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #%00000010 ; return home
+ sta PORTB
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #E ; clear RS/RW, set E, send instruction
+ sta PORTA
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #%00000110 ; set entry mode: increment, no shift
+ sta PORTB
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #E ; clear RS/RW, set E, send instruction
+ sta PORTA
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #'6' ; data to send
+ sta PORTB
+
+ lda #RS ; clear RW, E, set RS for data
+ sta PORTA
+
+ lda #( E | RS ) ; clear RW, set E/RS, send data
+ sta PORTA
+
+ lda #RS ; clear RS, E, keep RS
+ sta PORTA
+
+ lda #'5' ; data to send
+ sta PORTB
+
+ lda #RS ; clear RW, E, set RS for data
+ sta PORTA
+
+ lda #( E | RS ) ; clear RW, set E/RS, send data
+ sta PORTA
+
+ lda #RS ; clear RS, E, keep RS
+ sta PORTA
+
+ lda #'0' ; data to send
+ sta PORTB
+
+ lda #RS ; clear RW, E, set RS for data
+ sta PORTA
+
+ lda #( E | RS ) ; clear RW, set E/RS, send data
+ sta PORTA
+
+ lda #RS ; clear RS, E, keep RS
+ sta PORTA
+
+ lda #'2' ; data to send
+ sta PORTB
+
+ lda #RS ; clear RW, E, set RS for data
+ sta PORTA
+
+ lda #( E | RS ) ; clear RW, set E/RS, send data
+ sta PORTA
+
+ lda #RS ; clear RS, E, keep RS
+ sta PORTA
+
+end:
+ jmp end
+
+ .org #$fffc
+ .word reset
+ .word $0000
diff --git a/roms/lcd_with_ram.asm b/roms/lcd_with_ram.asm
new file mode 100644
index 0000000..7340c71
--- /dev/null
+++ b/roms/lcd_with_ram.asm
@@ -0,0 +1,82 @@
+PORTB = $6000
+PORTA = $6001
+DDRB = $6002
+DDRA = $6003
+
+E = %10000000
+RW = %01000000
+RS = %00100000
+
+ .org #$f800
+
+reset:
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ lda #%11111111 ; set output on all pins of PORTB
+ sta DDRB
+
+ lda #%11100000 ; set output on LCD control pins of PORTA
+ sta DDRA
+
+ lda #%00111000 ; set 8-bit, 2-line display, 5x8 font
+ jsr lcd_send_command
+
+ lda #%00001110 ; display on, cursor on, no blink
+ jsr lcd_send_command
+
+ lda #%00000001 ; clear display
+ jsr lcd_send_command
+
+ lda #%00000010 ; return home
+ jsr lcd_send_command
+
+ lda #%00000110 ; set entry mode: increment, no shift
+ jsr lcd_send_command
+
+ lda #'6' ; data to send
+ jsr lcd_send_data
+
+ lda #'5' ; data to send
+ jsr lcd_send_data
+
+ lda #'0' ; data to send
+ jsr lcd_send_data
+
+ lda #'2' ; data to send
+ jsr lcd_send_data
+
+term:
+ jmp term
+
+lcd_send_command:
+ sta PORTB
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #E ; clear RS/RW, set E, send instruction
+ sta PORTA
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ rts
+
+lcd_send_data:
+ sta PORTB ; data to send to port B
+
+ lda #RS ; clear RW, E, set RS for data
+ sta PORTA
+
+ lda #( E | RS ) ; clear RW, set E/RS, send data
+ sta PORTA
+
+ lda #RS ; clear RS, E, keep RS
+ sta PORTA
+
+ rts
+
+ .org #$fffc
+ .word reset
+ .word $0000
diff --git a/roms/lcd_with_ram_busy_check.asm b/roms/lcd_with_ram_busy_check.asm
new file mode 100644
index 0000000..01bd1d1
--- /dev/null
+++ b/roms/lcd_with_ram_busy_check.asm
@@ -0,0 +1,112 @@
+PORTB = $6000
+PORTA = $6001
+DDRB = $6002
+DDRA = $6003
+
+E = %10000000
+RW = %01000000
+RS = %00100000
+
+ .org #$f800
+
+reset:
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ lda #%11111111 ; set output on all pins of PORTB
+ sta DDRB
+
+ lda #%11100000 ; set output on LCD control pins of PORTA
+ sta DDRA
+
+ lda #%00111000 ; set 8-bit, 2-line display, 5x8 font
+ jsr lcd_send_command
+
+ lda #%00001110 ; display on, cursor on, no blink
+ jsr lcd_send_command
+
+ lda #%00000001 ; clear display
+ jsr lcd_send_command
+
+ lda #%00000010 ; return home
+ jsr lcd_send_command
+
+ lda #%00000110 ; set entry mode: increment, no shift
+ jsr lcd_send_command
+
+ lda #'6' ; data to send
+ jsr lcd_send_data
+
+ lda #'5' ; data to send
+ jsr lcd_send_data
+
+ lda #'0' ; data to send
+ jsr lcd_send_data
+
+ lda #'2' ; data to send
+ jsr lcd_send_data
+
+term:
+ jmp term
+
+lcd_wait:
+ pha
+ lda #%00000000 ; port B to all input
+ sta DDRB
+
+lcd_wait_loop:
+ lda #RW
+ sta PORTA
+
+ lda #(RW | E)
+ sta PORTA
+
+ lda PORTB
+ and #%10000000
+ bne lcd_wait_loop
+
+ lda #RW
+ sta PORTA
+ lda #%11111111 ; port B back to output
+ sta DDRB
+
+ pla
+ rts
+
+lcd_send_command:
+
+ jsr lcd_wait
+
+ sta PORTB
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #E ; clear RS/RW, set E, send instruction
+ sta PORTA
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ rts
+
+lcd_send_data:
+
+ jsr lcd_wait
+
+ sta PORTB ; data to send to port B
+
+ lda #RS ; clear RW, E, set RS for data
+ sta PORTA
+
+ lda #( E | RS ) ; clear RW, set E/RS, send data
+ sta PORTA
+
+ lda #RS ; clear RS, E, keep RS
+ sta PORTA
+
+ rts
+
+ .org #$fffc
+ .word reset
+ .word $0000
diff --git a/roms/lcd_with_ram_busy_check_and_string_print.asm b/roms/lcd_with_ram_busy_check_and_string_print.asm
new file mode 100644
index 0000000..34b78b4
--- /dev/null
+++ b/roms/lcd_with_ram_busy_check_and_string_print.asm
@@ -0,0 +1,112 @@
+PORTB = $6000
+PORTA = $6001
+DDRB = $6002
+DDRA = $6003
+
+E = %10000000
+RW = %01000000
+RS = %00100000
+
+ .org #$f800
+
+reset:
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ lda #%11111111 ; set output on all pins of PORTB
+ sta DDRB
+
+ lda #%11100000 ; set output on LCD control pins of PORTA
+ sta DDRA
+
+ lda #%00111000 ; set 8-bit, 2-line display, 5x8 font
+ jsr lcd_send_command
+
+ lda #%00001110 ; display on, cursor on, no blink
+ jsr lcd_send_command
+
+ lda #%00000001 ; clear display
+ jsr lcd_send_command
+
+ lda #%00000010 ; return home
+ jsr lcd_send_command
+
+ lda #%00000110 ; set entry mode: increment, no shift
+ jsr lcd_send_command
+
+ ldx #0
+msg_loop:
+ lda message, x ; string to send
+ beq msg_end
+ jsr lcd_send_data
+ inx
+ jmp msg_loop
+msg_end:
+
+term:
+ jmp term
+
+lcd_wait:
+ pha
+ lda #%00000000 ; port B to all input
+ sta DDRB
+
+lcd_wait_loop:
+ lda #RW
+ sta PORTA
+
+ lda #(RW | E)
+ sta PORTA
+
+ lda PORTB
+ and #%10000000
+ bne lcd_wait_loop
+
+ lda #RW
+ sta PORTA
+ lda #%11111111 ; port B back to output
+ sta DDRB
+
+ pla
+ rts
+
+lcd_send_command:
+
+ jsr lcd_wait
+
+ sta PORTB
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #E ; clear RS/RW, set E, send instruction
+ sta PORTA
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ rts
+
+lcd_send_data:
+
+ jsr lcd_wait
+
+ sta PORTB ; data to send to port B
+
+ lda #RS ; clear RW, E, set RS for data
+ sta PORTA
+
+ lda #( E | RS ) ; clear RW, set E/RS, send data
+ sta PORTA
+
+ lda #RS ; clear RS, E, keep RS
+ sta PORTA
+
+ rts
+
+message:
+ .asciiz "6502"
+
+ .org #$fffc
+ .word reset
+ .word $0000
diff --git a/roms/read_write.hex b/roms/read_write.hex
new file mode 100644
index 0000000..b31b2ac
--- /dev/null
+++ b/roms/read_write.hex
@@ -0,0 +1,128 @@
+00000000: a942 8d00 60cb eaea eaea eaea eaea eaea ................
+00000010: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000020: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000030: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000040: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000050: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000060: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000070: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000080: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000090: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000100: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000110: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000120: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000130: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000140: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000150: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000160: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000170: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000180: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000190: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000200: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000210: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000220: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000230: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000240: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000250: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000260: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000270: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000280: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000290: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000300: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000310: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000320: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000330: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000340: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000350: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000360: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000370: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000380: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000390: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000400: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000410: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000420: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000430: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000440: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000450: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000460: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000470: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000480: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000490: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000500: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000510: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000520: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000530: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000540: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000550: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000560: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000570: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000580: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000590: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000600: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000610: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000620: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000630: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000640: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000650: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000660: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000670: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000680: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000690: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000700: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000710: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000720: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000730: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000740: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000750: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000760: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000770: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000780: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000790: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007f0: eaea eaea eaea eaea eaea eaea 00f8 eaea ................
diff --git a/roms/simple_ram_test.asm b/roms/simple_ram_test.asm
new file mode 100644
index 0000000..4b5e285
--- /dev/null
+++ b/roms/simple_ram_test.asm
@@ -0,0 +1,16 @@
+ .org #$f800
+
+MEM = $ff
+
+reset:
+ ldx #$0
+ stx MEM
+loop:
+ ldx MEM
+ inx
+ stx MEM
+ jmp loop
+
+ .org #$fffc
+ .word reset
+ .word $0000
diff --git a/roms/simple_ram_test2.asm b/roms/simple_ram_test2.asm
new file mode 100644
index 0000000..9803056
--- /dev/null
+++ b/roms/simple_ram_test2.asm
@@ -0,0 +1,162 @@
+PORTB = $6000
+PORTA = $6001
+DDRB = $6002
+DDRA = $6003
+
+E = %10000000
+RW = %01000000
+RS = %00100000
+
+ .org #$f800
+
+reset:
+ ldx #$FF ; initialize call stack to $1FF
+ txs
+
+ lda #%11111111 ; set output on all pins of PORTB
+ sta DDRB
+
+ lda #%11100000 ; set output on LCD control pins of PORTA
+ sta DDRA
+
+ lda #%00111000 ; set 8-bit, 2-line display, 5x8 font
+ jsr lcd_send_command
+
+ lda #%00001110 ; display on, cursor on, no blink
+ jsr lcd_send_command
+
+ lda #%00000001 ; clear display
+ jsr lcd_send_command
+
+ lda #%00000010 ; return home
+ jsr lcd_send_command
+
+ lda #%00000110 ; set entry mode: increment, no shift
+ jsr lcd_send_command
+
+set_memory:
+ ldy #$0
+ ldx #$FF
+set_memory_loop:
+ sty $0, x
+ iny
+ dex
+ bne set_memory_loop
+
+test_memory:
+ ldy #$0
+ ldx #$FF
+test_memory_loop:
+ tya
+ pha
+ lda $0, x
+ cmp $1FF ; stack was empty so Y is now on top of stack
+ bne test_memory_bad
+ pla
+ tay
+ iny
+ dex
+ bne test_memory_loop
+ jmp test_memory_ok
+
+test_memory_bad:
+ ldx #0
+msg_loop_bad:
+ lda message_memory_bad, x
+ beq msg_end_bad
+ jsr lcd_send_data
+ inx
+ jmp msg_loop_bad
+msg_end_bad:
+ jmp finish
+
+test_memory_ok:
+ ldx #0
+msg_loop_ok:
+ lda message_memory_ok, x
+ beq msg_end_ok
+ jsr lcd_send_data
+ inx
+ jmp msg_loop_ok
+msg_end_ok
+
+finish:
+ jmp finish
+
+term:
+ jmp term
+
+lcd_wait:
+ pha
+ lda #%00000000 ; port B to all input
+ sta DDRB
+
+lcd_wait_loop:
+ lda #RW
+ sta PORTA
+
+ lda #(RW | E)
+ sta PORTA
+
+ lda PORTB
+ and #%10000000
+ bne lcd_wait_loop
+
+ lda #RW
+ sta PORTA
+ lda #%11111111 ; port B back to output
+ sta DDRB
+
+ pla
+ rts
+
+lcd_send_command:
+
+ jsr lcd_wait
+
+ sta PORTB
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ lda #E ; clear RS/RW, set E, send instruction
+ sta PORTA
+
+ lda #$0 ; clear RS/RW/E
+ sta PORTA
+
+ rts
+
+lcd_send_data:
+
+ jsr lcd_wait
+
+ sta PORTB ; data to send to port B
+
+ lda #RS ; clear RW, E, set RS for data
+ sta PORTA
+
+ lda #( E | RS ) ; clear RW, set E/RS, send data
+ sta PORTA
+
+ lda #RS ; clear RS, E, keep RS
+ sta PORTA
+
+ rts
+
+nmi:
+ rti
+
+irq:
+ rti
+
+message_memory_bad:
+ .asciiz "mem bad"
+
+message_memory_ok:
+ .asciiz "mem ok"
+
+ .org #$fffa
+ .word nmi
+ .word reset
+ .word irq
diff --git a/roms/wait.hex b/roms/wait.hex
new file mode 100644
index 0000000..c9241fd
--- /dev/null
+++ b/roms/wait.hex
@@ -0,0 +1,128 @@
+00000000: cbea eaea eaea eaea eaea eaea eaea eaea ................
+00000010: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000020: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000030: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000040: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000050: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000060: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000070: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000080: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000090: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000000f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000100: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000110: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000120: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000130: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000140: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000150: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000160: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000170: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000180: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000190: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000001f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000200: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000210: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000220: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000230: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000240: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000250: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000260: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000270: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000280: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000290: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000002f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000300: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000310: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000320: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000330: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000340: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000350: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000360: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000370: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000380: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000390: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000003f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000400: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000410: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000420: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000430: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000440: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000450: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000460: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000470: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000480: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000490: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000004f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000500: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000510: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000520: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000530: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000540: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000550: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000560: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000570: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000580: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000590: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000005f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000600: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000610: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000620: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000630: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000640: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000650: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000660: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000670: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000680: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000690: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000006f0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000700: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000710: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000720: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000730: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000740: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000750: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000760: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000770: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000780: eaea eaea eaea eaea eaea eaea eaea eaea ................
+00000790: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007a0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007b0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007c0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007d0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007e0: eaea eaea eaea eaea eaea eaea eaea eaea ................
+000007f0: eaea eaea eaea eaea eaea eaea 00f8 eaea ................
diff --git a/sketches/6502_addr_read.ino b/sketches/6502_addr_read.ino
new file mode 100644
index 0000000..415c4b7
--- /dev/null
+++ b/sketches/6502_addr_read.ino
@@ -0,0 +1,48 @@
+char addr_pin[16];
+char data_pin[8];
+const int clock_pin = 2;
+const int rw_pin = 3;
+
+void setup( )
+{
+ for( int i = 0; i < 16; i++ ) {
+ addr_pin[i] = 52 - i*2;
+ pinMode( addr_pin[i], INPUT );
+ }
+ for( int i = 0; i < 8; i++ ) {
+ data_pin[i] = 53 - i*2;
+ pinMode( data_pin[i], INPUT );
+ }
+ pinMode( clock_pin, INPUT );
+ pinMode( rw_pin, INPUT );
+ attachInterrupt( digitalPinToInterrupt( clock_pin ), onClk, RISING );
+ Serial.begin( 115200 );
+}
+
+void onClk( )
+{
+ unsigned int addr = 0;
+ for( int i = 0; i < 16; i++ ) {
+ int b = ( digitalRead( addr_pin[i] ) == HIGH ) ? 1 : 0;
+ Serial.print( b );
+ addr = ( addr << 1 ) + b;
+ }
+ Serial.print( " " );
+ unsigned int data = 0;
+ for( int i = 0; i < 8; i++ ) {
+ int b = ( digitalRead( data_pin[i] ) == HIGH ) ? 1 : 0;
+ Serial.print( b );
+ data = ( data << 1 ) + b;
+ }
+ Serial.print( " " );
+
+ char rw = ( digitalRead( rw_pin ) == HIGH ) ? 'r' : 'w';
+
+ char output[32];
+ sprintf( output, "%04x %c %02x", addr, rw, data );
+ Serial.println( output );
+}
+
+void loop( )
+{
+}
diff --git a/vga/README b/vga/README
new file mode 100644
index 0000000..b53a919
--- /dev/null
+++ b/vga/README
@@ -0,0 +1,19 @@
+SVGA Signal 800 x 600 @ 60 Hz timing
+
+40.0 MHz
+
+Visible area 800 20
+Front porch 40 1
+Sync pulse 128 3.2
+Back porch 88 2.2
+Whole line 1056 26.4
+
+
+Visible area 800 200
+Front porch 40 10
+Sync pulse 128 32
+Back porch 88 22
+Whole line 1056 264
+
+Pixel freq. 10 MHz
+