Extended vector entry points table; Extended vector handler - 167 bytes (1%)
§1. Extended Vector Entry Points.
See NAUG Section 17.4.3 - Extended Vectors, Page 312 There is a mechanism by which Paged ROMs can intercept the standard vectors at $0200 upwards, instead getting them to point to a specific address *in a specified ROM*. To intercept vector N: - Disable interrupts during this change over - Get memory base address (call it V) using OSBYTE 168 (V is address '.extendedVectorSpace' in this particular version of the ROM) - Store desired ROM address for routine at the two byte starting at V+3*N - Store desired ROM number in the following byte - Make a copy of the original contents of the vector at $0200+2*N if needed - Store the address '$FF00+3*N' in OS vector at '$0200+2*N'
.extendedVectorTable = $ff00 JSR .extendedVectorEntryPoint E_USERV JSR .extendedVectorEntryPoint E_BRKV JSR .extendedVectorEntryPoint E_IRQ1V JSR .extendedVectorEntryPoint E_IRQ2V JSR .extendedVectorEntryPoint E_CLIV JSR .extendedVectorEntryPoint E_BYTEV JSR .extendedVectorEntryPoint E_WORDV JSR .extendedVectorEntryPoint E_WRCHV JSR .extendedVectorEntryPoint E_RDCHV JSR .extendedVectorEntryPoint E_FILEV JSR .extendedVectorEntryPoint E_ARGSV JSR .extendedVectorEntryPoint E_BGETV JSR .extendedVectorEntryPoint E_BPUTV JSR .extendedVectorEntryPoint E_GBPBV JSR .extendedVectorEntryPoint E_FINDV JSR .extendedVectorEntryPoint E_FSCV JSR .extendedVectorEntryPoint E_EVENTV JSR .extendedVectorEntryPoint E_UPTV JSR .extendedVectorEntryPoint E_NETV JSR .extendedVectorEntryPoint E_VDUV JSR .extendedVectorEntryPoint E_KEYV JSR .extendedVectorEntryPoint E_INSV JSR .extendedVectorEntryPoint E_REMV JSR .extendedVectorEntryPoint E_CNPV JSR .extendedVectorEntryPoint E_IND1V JSR .extendedVectorEntryPoint E_IND2V JSR .extendedVectorEntryPoint E_IND3V
.extendedVectorEntryPoint = $ff51 PHA save A on stack - make space for currently selected ROM (address '$109,X' in code below) PHA save A on stack - make space for return address low (address '$108,X' in code below) PHA save A on stack - make space for return address high (address '$107,X' in code below) PHA save A on stack - make space for ROM address low (address '$106,X' in code below) PHA save A on stack - make space for ROM address high (address '$105,X' in code below) PHP } PHA } TXA } save Flags,A,X,Y to the stack PHA } TYA } PHA } TSX get stack pointer into X LDA #>(.returnFromROM-1) } STA .stackPage + 8,X } LDA #<(.returnFromROM-1) } store return address in the stack } (the .returnFromROM routine below) STA .stackPage + 7,X } LDY .stackPage + 10,X Y=3*N+2 (low byte of caller address) LDA .extendedVectorSpace-2,Y get low byte of action address STA .stackPage + 5,X store it on stack LDA .extendedVectorSpace-1,Y get high byte of action address STA .stackPage + 6,X store it on stack LDA .currentlySelectedROM get the current ROM number STA .stackPage + 9,X store it on stack LDA .extendedVectorSpace,Y get new ROM number STA .currentlySelectedROM store RAM copy of current ROM STA .romSelectRegister switch the ROM into the memory map PLA } TAY } PLA } Restore Y,X,A from stack TAX } PLA } RTI the RTI instruction restores the flags, and jumps to the (ROM) address we've put on the stack. i.e. this jumps to the ROM routine. When that returns, the address on the stack jumps us to the routine below.
Return from ROM Once the ROM routine from above is finished, the return address takes us here, which restores the registers and returns to the proper calling routine.
.returnFromROM = $ff89 PHP } PHA } TXA } save Flags,A,X to the stack PHA } TSX LDA .stackPage + 2,X } STA .stackPage + 5,X } LDA .stackPage + 3,X } store real return address onto } stack (ready for RTS) STA .stackPage + 6,X } PLA } TAX } recall X PLA recall A - lose these 2 bytes. They are the address of this routine. PLA recall A - lose these 2 bytes. They are the address of this routine. PLA get back A (original ROM number) STA .currentlySelectedROM store it as RAM copy of current ROM number STA .romSelectRegister switch the ROM into the memory map PLA get back A PLP get back flags .return = $ffa6 RTS return (pulls real return address from stack)