summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-11-19 10:59:32 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2020-11-19 10:59:32 +0100
commit4c167d48f0f972ff9a5f0e10247aab71c50a141b (patch)
tree2956f0f591bf79c6cb265c1e828a702ffb46b018
parent055ca03ed8ebadaafea285bf79f7e85529663bab (diff)
download6502-4c167d48f0f972ff9a5f0e10247aab71c50a141b.tar.gz
6502-4c167d48f0f972ff9a5f0e10247aab71c50a141b.tar.bz2
added some docu and links
-rw-r--r--LINKS13
-rw-r--r--doc/www_webmail_supervisord_org_tutorials_register_preservation.txt188
-rw-r--r--roms/README3
3 files changed, 203 insertions, 1 deletions
diff --git a/LINKS b/LINKS
index fefd03f..9addc00 100644
--- a/LINKS
+++ b/LINKS
@@ -2,6 +2,8 @@ GeckOS, Unix on 6502:
http://www.6502.org/users/andre/osa/index.html
eater.net: 6502 kit
+
+arduino monitor:
https://github.com/dpm-343/6502-monitor/blob/master/6502-monitor.ino
other 6052:
@@ -79,6 +81,7 @@ 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)
+https://hgj.hu/live-migrating-a-virtual-machine-with-libvirt-without-a-shared-storage/
delay/timers:
https://gist.github.com/superjamie/fd80fabadf39199c97de400213f614e9
@@ -95,3 +98,13 @@ 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
+
+6502 emulators:
+https://github.com/gianlucag/mos6502.git
+
+other emulators:
+https://github.com/pdewacht/oberon-risc-emu (RISC-5 Wirth Emulator, as inspiration)
+
+video:
+https://youtu.be/0QleiL-WdyM
+https://en.wikipedia.org/wiki/Texas_Instruments_TMS9918
diff --git a/doc/www_webmail_supervisord_org_tutorials_register_preservation.txt b/doc/www_webmail_supervisord_org_tutorials_register_preservation.txt
new file mode 100644
index 0000000..b8833ff
--- /dev/null
+++ b/doc/www_webmail_supervisord_org_tutorials_register_preservation.txt
@@ -0,0 +1,188 @@
+ Register Preservation Using The Stack (and a BRK handler)
+
+ by Bruce Clark, 7 Jun 2004
+ __________________________________________________________________
+
+ On the 65C02, a subroutine can save the A, X, and Y registers without
+ altering them by using:
+PHA
+PHX
+PHY
+
+ The subroutine then restores A, X, and Y by exiting with:
+PLY
+PLX
+PLA
+RTS
+
+ The PHX/PLX and PHY/PLY instructions are not available on the 6502. On
+ the 6502, A, X, and Y are often saved using:
+PHA
+TXA
+PHA
+TYA
+PHA
+
+ which preserves X and Y, but overwrites A. The subroutine then restores
+ A, X, and Y by exiting with:
+PLA
+TAY
+PLA
+TAX
+PLA
+RTS
+
+ One way to preserve A (to allow it to be passed as a parameter to the
+ subroutine) -- as well as X and Y -- is to use:
+STA TEMP
+PHA
+TXA
+PHA
+TYA
+PHA
+LDA TEMP
+
+ which takes 4 additional bytes and 6 additional cycles if TEMP is a
+ zero page location, and 6 additional bytes and 8 additional cycles if
+ TEMP is an absolute memory location.
+
+ This is usually sufficient, but if, for example, the subroutine is used
+ by the main program and by an interrupt routine, interrupts must be
+ disabled so that TEMP will not be in use when the interrupt occurs.
+
+ An alternative is to use:
+PHA
+TXA
+TSX
+PHA
+TYA
+PHA
+INX
+LDA $100,X ; get A from the stack
+
+ which takes 5 additional bytes and 8 additional cycles (as compared to
+ the the first 6502 example, not the previous example) but interrupts
+ need not be disabled since it gets A from the stack rather than
+ requiring a special memory location. This could be used in a subroutine
+ called by an NMI (since an NMI can't be disabled). Remember, NMIs are
+ dangerous, and should be used with extreme caution if at all.
+
+ Notice that the idea is to get the stack pointer into X as soon as
+ possible so that the number INX instructions needed can be minimized.
+
+ The code above works correctly regardless of the value of the stack
+ pointer. As long as the stack pointer is not $FF, the last two
+ instructions could be replaced with a LDA $101,X instruction, which
+ would save 1 byte and two cycles. Ordinarily, this is not a problem
+ since the stack pointer is usually initialized to $FF (and will
+ therefore be less than $FF after the PHA). It goes without saying that
+ the software should be fully debugged before even considering the LDA
+ $101,X change.
+
+ The code above preserves A, but overwrites X. To preserve A, X, and Y,
+ use:
+PHA
+TXA
+TSX
+PHA
+TYA
+PHA
+INX
+LDA $100,X ; get A from the stack
+PHA
+DEX
+LDA $100,X ; get X from the stack
+TAX
+PLA
+
+ which is 7 bytes and 15 cycles longer than the previous example. This
+ may be more trouble than it is worth, but it could come in handy for
+ subroutines that are used for debugging (where the idea is to be as
+ independent as possible and to stay as far out of the way of the main
+ program as possible).
+
+ The preceding techniques can also be applied to the BRK/IRQ interrupt
+ handler. For example, on the 6502,
+PHA
+TXA
+TSX
+PHA
+INX
+INX
+LDA $100,X ; get the status register from the stack
+AND #$10 ; mask B flag
+BNE BREAK
+BEQ IRQ
+
+ can be used to determine whether the interrupt was caused by a BRK
+ instruction or an IRQ. Ordinarily, of course, the code would simply
+ fall through to the IRQ handler, eliminating the BEQ instruction. The
+ BRK and IRQ handlers would then exit with:
+PLA
+TAX
+PLA
+RTI
+
+ Alternatively, A and X could be restored immediately after branching
+ (or falling through) to the BRK or IRQ interrupt handler.
+
+ On the 65C02, with PHX and PLX available,
+PHX
+TSX
+PHA
+INX
+INX
+LDA $100,X ; get the status register from the stack
+AND #$10 ; mask B flag
+BNE BREAK
+BEQ IRQ
+
+ can be used, which takes 1 fewer byte and 2 fewer cycles than the 6502
+ example. The BRK and IRQ handlers would then exit with:
+PLA
+PLX
+RTI
+
+ which also takes 1 fewer byte and 2 fewer cycles than the 6502 example.
+
+ Note that A and X are saved in the opposite order that they were in the
+ 6502 example!
+
+ The B (Break) flag, bit 4 of the P (Processor status) register, is a
+ frequent source of confusion on the 6502. The sole purpose of this flag
+ is to distinguish a BRK from a IRQ. However, the behavior of BRK and
+ IRQ (and how to distinguish between the two) can be described without
+ even mentioning the B flag.
+
+ After the return address has been pushed onto the stack, a BRK
+ instruction pushes the value of the P register ORed with $10, then
+ transfers control to the BRK/IRQ interrupt handler.
+
+ After the return address has been pushed onto the stack, an IRQ
+ interrupt pushes the value of the P register ANDed with $EF, then
+ transfers control to the BRK/IRQ interrupt handler.
+
+ This means that the value of the P register that was pushed onto the
+ stack must be used to distinguish a BRK from a IRQ, not the value of
+ the P register upon entry to the BRK/IRQ interrupt handler.
+ Specifically,
+PHA
+PHP
+PLA
+AND #$10 ; mask B flag
+BNE BREAK
+BEQ IRQ
+
+ does NOT properly distinguish a BRK from an IRQ!
+
+ Chelly adds: At the end proper checking of the B flag is discussed. My
+ feedback is that it would be simpler to explain that there is no B flag
+ in the processor status register; that bit is simply unused. When
+ pushing the status register on the stack, that bit is set to a fixed
+ value based on the instruction/event (set for PHP and BRK, clear for
+ NMI). This is much simpler to explain and leads to no incorrect
+ assumption that there is a B flag in the status register that can be
+ checked.
+ __________________________________________________________________
+
+ Last page update: November 11, 2006.
diff --git a/roms/README b/roms/README
index 9ba01d1..d19afae 100644
--- a/roms/README
+++ b/roms/README
@@ -21,4 +21,5 @@ wait.hex - test 65C02 WAI special opcode
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)
+7seg_counter_reset_on_irq_delay.asm - counter, reset on IRQ (usable at 1 MHz)
+7seg_counter_irq_timer_smart_update.asm - counter, working version, update when needed, proper interrupt handling