From 63d0944063b6f240fe0c68ef9b61d4dd906d9fc1 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Tue, 17 Nov 2020 19:12:00 +0100 Subject: initial checkin --- .gitignore | 5 + FINDINGS | 11 + LINKS | 97 +++++ README | 100 ++++++ TODOS | 3 + doc/6502_org_source_general_clockfreq.txt | 201 +++++++++++ doc/www.ganssle.com_articles_anmi.txt | 409 ++++++++++++++++++++++ roms/7seg_counter_irq_timer.asm | 112 ++++++ roms/7seg_counter_reset_on_irq.asm | 89 +++++ roms/7seg_counter_reset_on_irq_delay.asm | 106 ++++++ roms/7seg_print_one.asm | 62 ++++ roms/7seg_print_one_subroutine.asm | 66 ++++ roms/7segment_rom.hex | 128 +++++++ roms/README | 24 ++ roms/blinken_lights.asm | 14 + roms/blinken_lights.hex | 128 +++++++ roms/clear_zero_page.asm | 132 +++++++ roms/counting_lights.asm | 13 + roms/entry.hex | 128 +++++++ roms/irqs_with_lcd1.asm | 132 +++++++ roms/irqs_with_via.asm | 137 ++++++++ roms/lcd_no_ram.asm | 132 +++++++ roms/lcd_with_ram.asm | 82 +++++ roms/lcd_with_ram_busy_check.asm | 112 ++++++ roms/lcd_with_ram_busy_check_and_string_print.asm | 112 ++++++ roms/read_write.hex | 128 +++++++ roms/simple_ram_test.asm | 16 + roms/simple_ram_test2.asm | 162 +++++++++ roms/wait.hex | 128 +++++++ sketches/6502_addr_read.ino | 48 +++ vga/README | 19 + 31 files changed, 3036 insertions(+) create mode 100644 .gitignore create mode 100644 FINDINGS create mode 100644 LINKS create mode 100644 README create mode 100644 TODOS create mode 100644 doc/6502_org_source_general_clockfreq.txt create mode 100644 doc/www.ganssle.com_articles_anmi.txt create mode 100644 roms/7seg_counter_irq_timer.asm create mode 100644 roms/7seg_counter_reset_on_irq.asm create mode 100644 roms/7seg_counter_reset_on_irq_delay.asm create mode 100644 roms/7seg_print_one.asm create mode 100644 roms/7seg_print_one_subroutine.asm create mode 100644 roms/7segment_rom.hex create mode 100644 roms/README create mode 100644 roms/blinken_lights.asm create mode 100644 roms/blinken_lights.hex create mode 100644 roms/clear_zero_page.asm create mode 100644 roms/counting_lights.asm create mode 100644 roms/entry.hex create mode 100644 roms/irqs_with_lcd1.asm create mode 100644 roms/irqs_with_via.asm create mode 100644 roms/lcd_no_ram.asm create mode 100644 roms/lcd_with_ram.asm create mode 100644 roms/lcd_with_ram_busy_check.asm create mode 100644 roms/lcd_with_ram_busy_check_and_string_print.asm create mode 100644 roms/read_write.hex create mode 100644 roms/simple_ram_test.asm create mode 100644 roms/simple_ram_test2.asm create mode 100644 roms/wait.hex create mode 100644 sketches/6502_addr_read.ino create mode 100644 vga/README 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 + 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 + 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 + -- cgit v1.2.3-54-g00ecf