From 4c167d48f0f972ff9a5f0e10247aab71c50a141b Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 19 Nov 2020 10:59:32 +0100 Subject: added some docu and links --- LINKS | 13 ++ ...rvisord_org_tutorials_register_preservation.txt | 188 +++++++++++++++++++++ roms/README | 3 +- 3 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 doc/www_webmail_supervisord_org_tutorials_register_preservation.txt 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 -- cgit v1.2.3-54-g00ecf