Yeah a couple of the things I'd love to add to the BBC BASIC are PEEK and POKE I'll try your suggestion out. Ta.sweh wrote: ↑Mon Feb 12, 2024 9:10 pm FWIW, from inside the emulator you can verify the contents with something likeCode: Select all
>PRINT ~!&FFF4 AND &FFFFFF 020A6C >
Porting BASIC2 to a homebrew system
Re: Building BASIC4 source
Re: Building BASIC4 source
"?" is peek and poke all in one; ?&70=123 is the same as POKE &70,123; PRINT ?&70 is the same as PRINT PEEK &70. The "!" operator is similar but operates on 4 bytes rather than one. Remember the Beeb is low-byte first so if you do !&70=&12345678 then ?&70==&78, ?&71==&56, ?&72=34, ?&73=&12
Rgds
Stephen
Stephen
Re: Building BASIC4 source
I would tell you what I see in the bs emulator but I can't get the ~ key to work I've tried changing keyboard layouts too. Help Tom!sweh wrote: ↑Mon Feb 12, 2024 9:29 pm "?" is peek and poke all in one; ?&70=123 is the same as POKE &70,123; PRINT ?&70 is the same as PRINT PEEK &70. The "!" operator is similar but operates on 4 bytes rather than one. Remember the Beeb is low-byte first so if you do !&70=&12345678 then ?&70==&78, ?&71==&56, ?&72=34, ?&73=&12
Shift and ` just print a divide symbol - not a forward slash but a horizontal line with the dot above and below. Kinda like this:
Code: Select all
.
---
.
I can see 20A6C.. which must be 02 0A 6C.. a bit different from what's in the mem dump that I got. I should probably try again in case I'm using a different ROM/hardware config now.
Re: Building BASIC4 source
Yeah, that's how it looks in MODE 7; the teletext character set is slightly different to the other modes. You can see how it looks, e.g. in MODE 6.
Rgds
Stephen
Stephen
Re: Building BASIC4 source
Aha! We have the correct contents:
Like you say, BBC converted the 3 bytes into reverse order - I was expecting 6C 0A 02 for JMP ($020A) which I can see in the image above.
Looking in the debug memory window:
This also matches what we have above.
Going back to my hex dump:
Code: Select all
000fff0 6c02 020c 0a6c 6c02 0208 0d00 d9cd dc1c
..
0000fff0 6c 02 02 0c
0000fff4 0a 6c 6c 02
0000fff6 02 08 0d 00
This time round I used "Start" and "Size" when saving the memory instead of "Start" and "End".
I got my much needed memory dump.. and learnt more on the journey Thanks. But yes.. I like b2
Re: Building BASIC4 source
The debugger in b-em does not have commands to load and save memory from the BBC micro to host files. It could be added, of course.
There is another way in that b-em has VDFS, which enables accessing a subset of the host's filing system as a normal BBC micro filing system so if you were to enable it, and set a sensible root directory, i.e. somewhere on your PC, you could then use *SAVE and *SRSAVE as needed to save memory straight to files on the PC.
-
- Posts: 899
- Joined: Tue Aug 30, 2005 12:42 am
- Contact:
Re: Building BASIC4 source
The BBC B+Acorn DFS is suitable; the BBC B and B+ configs all come with BASIC 2, as was pretty much standard in the 1980s. (I probably need to update the docs to be a little more explicit about what the default configs actually contain. The docs are long overdue an overhaul anyway.)SparkyNZ wrote: ↑Mon Feb 12, 2024 8:35 pm I've managed to save 64k of memory to file.. but I'm not seeing 6C 02 0A at FFF4 as I expected. (or 6C 0A 02 if I have the bytes the wrong way around).
Do I need a different Hardware config from the default ones provided in b2? I was expecting to see a Model B Basic 2 32k system somewhere.. Maybe that's why things are different?Code: Select all
000ffe0 106c c902 d00d a907 200a ffee 0da9 0e6c 000fff0 6c02 020c 0a6c 6c02 0208 0d00 d9cd dc1c
Regarding the output from the save file, I think this will be the dump tool treating the values as little-endian 16-bit words. So the sequence of bytes is as follows: (split up a bit, hopefully for clarity)
Code: Select all
fff0 02 - end of oswrch entry point
fff1 6c 0c 02 - osword entry point
fff4 6c 0a 02 - osbyte entry point
fff7 6c 08 02 - oscli entry point
fffa 00 0d - NMI vector
fffc cd d9 - reset vector
fffe 1c dc - IRQ vector
b2 BBC B/B+/Master emulator: https://github.com/tom-seddon/b2; BeebLink filing system: https://github.com/tom-seddon/beeblink; more BBC Micro stuff: https://github.com/tom-seddon?tab=repos ... :bbc-micro
Re: Building BASIC4 source
I didn't even think about the hexdump itself Yeah I just used 'hexdump' on my Linux box rather than using my usual tried and tested Windows tools. That makes sense.tom_seddon wrote: ↑Wed Feb 14, 2024 5:15 pm Regarding the output from the save file, I think this will be the dump tool treating the values as little-endian 16-bit words. So the sequence of bytes is as follows: (split up a bit, hopefully for clarity)
I've just popped RTS instructions at FFF4 etc for now - that way I can snoop on the PC address in my emulator, do something in Windows and then return to wherever the OSBYTE/OSBlah call was made from. I'll obviously have to write some 6502 code eventually but my plan is just to implement a BBC BASIC "black box" for now. Finding the time at the moment is the biggest challenge.
Re: Building BASIC4 source
I have a wrapper for hexdump that makes it produce output in a format reminiscent of *DUMP
Output would look something like
Code: Select all
#!/bin/sh
if [ -t ]
then
cols=$(tput cols)
fi
cols=${cols:-80}
if [ $cols -ge 80 ]
then
x=16
a=8
else
x=8
a=4
fi
case $1 in
-16) x=16 ; a=8 ; shift ;;
-8) x=8 ; shift ;;
esac
exec hexdump -v -e '"%0'$a'_ax "' -e $x'/1 "%02X "" "" "' -e $x'/1 "%_p""\n"' "$@"
Code: Select all
00000000 23 21 2F 62 69 6E 2F 73 68 0A 0A 69 66 20 5B 20 #!/bin/sh..if [
00000010 2D 74 20 5D 0A 74 68 65 6E 0A 20 20 63 6F 6C 73 -t ].then. cols
00000020 3D 24 28 74 70 75 74 20 63 6F 6C 73 29 0A 66 69 =$(tput cols).fi
00000030 0A 63 6F 6C 73 3D 24 7B 63 6F 6C 73 3A 2D 38 30 .cols=${cols:-80
00000040 7D 0A 0A 69 66 20 5B 20 24 63 6F 6C 73 20 2D 67 }..if [ $cols -g
00000050 65 20 38 30 20 5D 0A 74 68 65 6E 0A 20 20 78 3D e 80 ].then. x=
00000060 31 36 0A 20 20 61 3D 38 0A 65 6C 73 65 0A 20 20 16. a=8.else.
00000070 78 3D 38 0A 20 20 61 3D 34 0A 66 69 0A 0A 63 61 x=8. a=4.fi..ca
00000080 73 65 20 24 31 20 69 6E 0A 20 20 2D 31 36 29 20 se $1 in. -16)
00000090 78 3D 31 36 20 3B 20 61 3D 38 20 3B 20 73 68 69 x=16 ; a=8 ; shi
000000a0 66 74 20 3B 3B 0A 20 20 20 2D 38 29 20 78 3D 38 ft ;;. -8) x=8
000000b0 20 3B 20 73 68 69 66 74 20 3B 3B 0A 65 73 61 63 ; shift ;;.esac
000000c0 0A 0A 65 78 65 63 20 68 65 78 64 75 6D 70 20 2D ..exec hexdump -
000000d0 76 20 2D 65 20 27 22 25 30 27 24 61 27 5F 61 78 v -e '"%0'$a'_ax
000000e0 20 20 22 27 20 2D 65 20 24 78 27 2F 31 20 22 25 "' -e $x'/1 "%
000000f0 30 32 58 20 22 22 20 20 22 22 20 22 27 20 2D 65 02X "" "" "' -e
00000100 20 24 78 27 2F 31 20 22 25 5F 70 22 22 5C 6E 22 $x'/1 "%_p""\n"
00000110 27 20 22 24 40 22 0A ' "$@".
Rgds
Stephen
Stephen
Re: Building BASIC4 source
What's the easiest way to execute an OSBYTE call and see register A, X and Y contents afterwards?
I was thinking a little BBC BASIC + ASM program would do the trick.. but I wouldn't know where to start
I was thinking a little BBC BASIC + ASM program would do the trick.. but I wouldn't know where to start
Re: Building BASIC4 source
From BASIC? Use, USR
The Welcome Guide says "On return from the machine code section, an integer number is generated from the four registers P, Y, X, A (most significant byte to least significant byte)."A%=&80:PRINT ~USR(&FFF4)
B1040080
So, in the above example, P=&B1, Y=4, X=0, A=&80
EDIT: But I suspect wiser heads than mine would tell you to look at what the documentation tells you each call should return / preserve / trample on
BBC Micro User Guide https://www.stardot.org.uk/forums/viewtopic.php?t=14024
Master Reference Manuals https://www.stardot.org.uk/forums/viewtopic.php?t=20466
Advanced User Guide https://www.stardot.org.uk/forums/viewtopic.php?t=17243
Beeb Wiki https://beebwiki.mdfs.net/OSBYTE which has a nice summary of what usually happens to A, X and Y.
EDIT2: Now with missing "~" added (thanks for the tipoff)
Re: Building BASIC4 source
Thanks for this - I read in one of the manuals that I could call an OSBYTE routine but there was no means of getting the returned values. I thought I'd have to write some assembler code to print out the register values - so this is super helpful.
Yeah, this is where I read that I would not be able to get the returned register values.. unless I misinterpreted what it meant:
http://www.sprow.co.uk/bbc/reference.htm
Re: Building BASIC4 source
If you *FX or use BASIC’s CALL, you won’t get the AXY values back.
Sprow’s document talks about OSWORD (rather than OSBYTE) and the Tube: Note that the Tube protocol for OSWord does not permit passing back the A, X, Y, or Status registers
Edit: struck out some nonsense.
Sprow’s document talks about OSWORD (rather than OSBYTE) and the Tube: Note that the Tube protocol for OSWord does not permit passing back the A, X, Y, or Status registers
Edit: struck out some nonsense.
Last edited by james on Fri Feb 16, 2024 2:19 pm, edited 1 time in total.
Re: Building BASIC4 source
*FX is an OS wrapper that parses the arguments into A/X/Y and calls OSBYTE; no return values are available.
CALL is a BASIC command that sets A/X/Y from A%/X%/Y% and calls the routine at the specified address; no return values. (There is a more advanced use of CALL which can set up variable parameter blocks, but that's out of scope here).
USR is a BASIC function that sets A/X/Y and calls the specified address and returns an INT containing A/X/Y/P values as the 4 bytes making up the INT (on the 6502, anyway; other architectures eg Z80 will return different values).
So to get the return value from an OSBYTE call you would use USR in the way James described.
CALL is a BASIC command that sets A/X/Y from A%/X%/Y% and calls the routine at the specified address; no return values. (There is a more advanced use of CALL which can set up variable parameter blocks, but that's out of scope here).
USR is a BASIC function that sets A/X/Y and calls the specified address and returns an INT containing A/X/Y/P values as the 4 bytes making up the INT (on the 6502, anyway; other architectures eg Z80 will return different values).
So to get the return value from an OSBYTE call you would use USR in the way James described.
Rgds
Stephen
Stephen
Re: Building BASIC4 source
USR() looks like what I want to use the most while I'm experimenting with OSBYTE calls.
Just trying this bit of BASIC out, I'm getting a "No such variable" error at line 30.
What I wanted to do was just convert the B1300084 I'm getting into a string so I can chop it up with MID$() etc.
Thanks to page 324 of the User Guide, I just realised that "PRINT ~" is actually a PRINT statement variant and that it's not the ~ operator that does the hex conversion.
What's the most convenient way to convert R into a string? If I "PRINT R" by itself, it seems to return a floating point number.
UPDATE: Now why is it that I discover the answer as soon as I ask? I see STR$~() will do the job.
Just trying this bit of BASIC out, I'm getting a "No such variable" error at line 30.
Code: Select all
10 A%=&84
20 R=USR(&FFF4)
30 R$=STR$(~R)
Thanks to page 324 of the User Guide, I just realised that "PRINT ~" is actually a PRINT statement variant and that it's not the ~ operator that does the hex conversion.
What's the most convenient way to convert R into a string? If I "PRINT R" by itself, it seems to return a floating point number.
UPDATE: Now why is it that I discover the answer as soon as I ask? I see STR$~() will do the job.
Re: Building BASIC4 source
Next question.. how does HIMEM work?
I've been playing around with OSBYTE &84 and I've noticed I'm getting different values returned depending upon what screen MODE I'm using.
On page 500 of the User Guide I see that HIMEM relates to where the BASIC stack ends and where the Hi-res Graphics RAM starts? So is the actual screen display using the memory which starts at HIMEM? For example, if I am in MODE 1 and I get back $3000 from OSYBYTE &74 (X:$00, Y:$30), does that mean that the screen pixel RAM starts at $3000?
Likewise, if I switch to MODE 3, I get back $4000 - so does that mean that the system uses 4K less for the screen memory than it does in MODE 1?
But... how come I get back $7C00 for the initial bootup mode? MODE 7?
Feel free to throw manual names and page numbers at me - I have the 3 main manuals here as well as the compendium. I don't seem very good at finding info using the Index
I see this puts ASCII 'A' at the top left of the screen for MODE 7.. so I guess the BBC is similar to the Vic20/C64 for screen character RAM. I'm still confused as to why the screen addresses/HIMEM values vary so much - $3000, $4000, $7c00 etc
Next I'll be wanting to know how the character colours work and how bitmap graphics work - from a memory perspective. I see writing 255 into $4000 for MODE 3 prints a flat line - so maybe MODE 7 is character based and MODE 3 is bitmap based? (excuse my choice of terminology )
I've been playing around with OSBYTE &84 and I've noticed I'm getting different values returned depending upon what screen MODE I'm using.
On page 500 of the User Guide I see that HIMEM relates to where the BASIC stack ends and where the Hi-res Graphics RAM starts? So is the actual screen display using the memory which starts at HIMEM? For example, if I am in MODE 1 and I get back $3000 from OSYBYTE &74 (X:$00, Y:$30), does that mean that the screen pixel RAM starts at $3000?
Likewise, if I switch to MODE 3, I get back $4000 - so does that mean that the system uses 4K less for the screen memory than it does in MODE 1?
But... how come I get back $7C00 for the initial bootup mode? MODE 7?
Feel free to throw manual names and page numbers at me - I have the 3 main manuals here as well as the compendium. I don't seem very good at finding info using the Index
Code: Select all
M=&7C00
?M=65
Next I'll be wanting to know how the character colours work and how bitmap graphics work - from a memory perspective. I see writing 255 into $4000 for MODE 3 prints a flat line - so maybe MODE 7 is character based and MODE 3 is bitmap based? (excuse my choice of terminology )
Re: Building BASIC4 source
You could also keep the numbers as numbers, eg take inspiration from https://www.beebwiki.mdfs.net/OSBYTE_%26A1
Code: Select all
A%=&80:R%=USR(&FFF4)
A%=R% AND &FF
X%=(R%AND&FF00)DIV256
Y%=(R%AND&FF0000)DIV65536
Re: Building BASIC4 source
By default, yes. This can be kludged but, in essence, if you change MODE then HIMEM is set to the location where screen memory starts, and the stack grows down from there.
Yes; MODE 7 uses 1K of memory. Sure, 40*25 is only 1000 so there's an extra 24 bytes to account for, but this is, in some ways, a weird mode. I works differently to every other mode (character mapped rather than pixel mapped) and hardware scrolling changes the start address and it wraps around, so all 1024 bytes do get used.But... how come I get back $7C00 for the initial bootup mode? MODE 7?
Only in MODE 7, and only if the screen hasn't scrolled.I see this puts ASCII 'A' at the top left of the screen for MODE 7.. so I guess the BBC is similar to the Vic20/C64 for screen character RAM.Code: Select all
M=&7C00 ?M=65
MODE 0,1,2 take 20K so HIMEM is set to &3000; MODE 3 is 16K, so &4000; MODE 4, 5 take 10K, so &5800. MODE 6 takes 8K, so &6000 and MODE 7 takes 1K, so &7C00.I'm still confused as to why the screen addresses/HIMEM values vary so much - $3000, $4000, $7c00 etc
Screen memory always ends at &7FFF ('cos &8000 is the beginning of ROM) so you count backwards from there.
https://www.stairwaytohell.com/articles ... fig3-L.jpg isn't a bad picture.
All modes are pixel based, except mode 7 (which is teletext character based) but the pixel mapping changes depending on the mode. In MODE 2, for example, 'cos it's 16 colours, each byte only covers 2 pixels. But 2 colour modes (eg 0, 3, 6) each byte covers 8 pixels.Next I'll be wanting to know how the character colours work and how bitmap graphics work - from a memory perspective. I see writing 255 into $4000 for MODE 3 prints a flat line - so maybe MODE 7 is character based and MODE 3 is bitmap based? (excuse my choice of terminology )
Rgds
Stephen
Stephen
Re: Building BASIC4 source
And if you're not in a shadow mode, or running on a second/co-processor ...sweh wrote: ↑Sat Feb 17, 2024 11:16 amOnly in MODE 7, and only if the screen hasn't scrolled.SparkyNZ wrote: ↑Sat Feb 17, 2024 5:23 amI see this puts ASCII 'A' at the top left of the screen for MODE 7.. so I guess the BBC is similar to the Vic20/C64 for screen character RAM.Code: Select all
M=&7C00 ?M=65
Re: Building BASIC4 source
And not a model A, etc. There's a lot of caveats; I was just talking about the "normal" case
Rgds
Stephen
Stephen
Re: Building BASIC4 source
And why Acorn emphasized using official OS entry points and APIs (e.g. in BASIC use PLOT, GCOL, COLOUR etc etc) rather than poking directly at the memory; lots of flexibility and things can change from one machine to the next; even with model Bs, PAGE can change depending on ROMs installed, let alone worrying about expansion cards, co-pros, and other models
Rgds
Stephen
Stephen
Re: Building BASIC4 source
I had started to write the long reply you've more elegantly answered upthread. My reply was littered with "don't poke the screen" and "use the official MOS calls" and the such. With warnings about Tubes, shadow RAM, and even BAS128 - which is going to give you, I suspect, a very peculiar view of the host machine.
Prescient! It has puzzled the OP over here https://www.stardot.org.uk/forums/viewtopic.php?t=28572even with model Bs, PAGE can change depending on ROMs installed, let alone worrying about expansion cards, co-pros, and other models
I suspect if the OP wants BASIC running on non-Acorn hardware "I do have a WD65C02 on my homebrew machine that I'd intended to port BBC BASIC over too", it really only needs to provide the MOS API's that BASIC uses. How the Acorn MOS or homebrew handle the screen data doesn't really matter beyond emulating MODE, resolution and colour-depth. Being able to poke the screen or other hardware directly shouldn't really be part of the process - unless you're writing an emulator!
Porting BASIC2 to a homebrew system
Yeah I totally understand why the whole poking is a no-no and the abstraction. I guess I'm just interested to know what lies beneath -its more curiosity and I don't have any intention of adding additional CPUs or the original OS etc.james wrote: ↑Sat Feb 17, 2024 12:10 pm I had started to write the long reply you've more elegantly answered upthread. My reply was littered with "don't poke the screen" and "use the official MOS calls" and the such. With warnings about Tubes, shadow RAM, and even BAS128 - which is going to give you, I suspect, a very peculiar view of the host machine.
On my journey of doing this BASIC port, I'm seeing the emulator making OSBYTE calls .. so I'm just wanting to know what to return for now.. just to keep the BASIC code happy. I figured the best thing to do is mimic a typical machine - that's why I've been peeking memory locations with the default system that b2 runs.
I'm sure there will be further OSBYTE calls and the likes when it comes to the BASIC commands such as MOVE and DRAW. For things like that I'd like to understand the original machine a bit better. I never did get to play around with a BBCs gfx when I was a kid.
I could keep all of questions in this thread since I am hacking with a homebrew system - I was just starting to think my questions have diverged quite a bit from how to build the BASIC4 source. Subject should really be "Porting BASIC2 to a homebrew system" now I guess. I'm not sure if changing the subject above will change the subject of the entire thread or start a new thread.
Re: Porting BASIC2 to a homebrew system
They are done with VDU sequences (OSWRCH). See chapters 8, 29 and 34 of the user guide. Also the explanations of DRAW PLOT etc in ch 33. viewtopic.php?t=14024
Rgds
Stephen
Stephen
Re: Porting BASIC2 to a homebrew system
Weird: there was a post here and upon replying to it, I got a message saying that the post had been deleted, then the thread as well!
Anyway, I think a reasonable online summary of the OS routine entry points can be found on BeebWiki's API page. I'm sure the Advanced User Guide (for both Beeb and Electron) provides this information in tabular form as well as with each routine's coverage.
Anyway, I think a reasonable online summary of the OS routine entry points can be found on BeebWiki's API page. I'm sure the Advanced User Guide (for both Beeb and Electron) provides this information in tabular form as well as with each routine's coverage.
Re: Porting BASIC2 to a homebrew system
Sorry about that. I was looking for $fff1 and then I realised it was probably OSWORD and sure enough I found it in the Advanced User Guide.paulb wrote: ↑Sat Feb 17, 2024 9:47 pm Weird: there was a post here and upon replying to it, I got a message saying that the post had been deleted, then the thread as well!
Anyway, I think a reasonable online summary of the OS routine entry points can be found on BeebWiki's API page. I'm sure the Advanced User Guide (for both Beeb and Electron) provides this information in tabular form as well as with each routine's coverage.
It would be good to have a definitive list if all important addresses somewhere.. but I may not need that in the end. I'll check that link you sent. Sorry about the post deletion. I was trying not to waste anybody's time and I did just that.
Re: Porting BASIC2 to a homebrew system
The User guide that came with the Beeb (I linked to it earlier) lists all the official endpoints. See page number 452 (chapter 43).
Rgds
Stephen
Stephen
Re: Porting BASIC2 to a homebrew system
No worries! I should have posted the link, anyway.
I spent a bit of time about a year or so ago writing a service ROM and looking things up in various places. The BeebWiki site was useful for gauging the semantics of various calls, especially since the exercise involved a kind of fusion of MOS and Unix semantics, but I did use the original paper version of the Acorn Electron AUG extensively. It was just a shame that the EAUG was perhaps not very well edited, with much of the original prose copy-pasted from the Beeb AUG (as I later found out) and not improved in any way, and there were some amusing slip-ups in the text, too.
Re: Porting BASIC2 to a homebrew system
Hmm.. struggling a bit with OSWORD=&00 - probably because I've never used the BRK instruction before.
If Escape is pressed, there's a JMP $9838
9838 just seems to contain a single BRK instruction.. so wouldn't that cause the execution to occur from the vector at FFFE?
Looking at FFFE, we have address DC1C.
So it must branch into $DC27 below, right?
So ultimately, using vector $0202, control is handed back to $b402, correct? I'm hoping I can just skip the entire code from MOS and continue execution at $b402.
If Escape is pressed, there's a JMP $9838
9838 just seems to contain a single BRK instruction.. so wouldn't that cause the execution to occur from the vector at FFFE?
Looking at FFFE, we have address DC1C.
Code: Select all
This page ([url]https://mdfs.net/Docs/Comp/BBC/OS1-20/DC1C[/url]) tells me it calls this code:
DC1C STA &FC ;save A
DC1E PLA ;get back status (flags)
DC1F PHA ;and save again
DC20 AND #&10 ;check if BRK flag set
DC22 BNE &DC27 ;if so goto DC27
DC24 JMP (&0204) ;else JMP (IRQ1V)
Code: Select all
*************************************************************************
* *
* BRK handling routine *
* *
*************************************************************************
DC27 TXA ;save X on stack
DC28 PHA ;
DC29 TSX ;get status pointer
DC2A LDA &0103,X ;get Program Counter lo
DC2D CLD ;
DC2E SEC ;set carry
DC2F SBC #&01 ;subtract 2 (1+carry)
DC31 STA &FD ;and store it in &FD
DC33 LDA &0104,X ;get hi byte
DC36 SBC #&00 ;subtract 1 if necessary
DC38 STA &FE ;and store in &FE
DC3A LDA &F4 ;get currently active ROM
DC3C STA &024A ;and store it in &24A
DC3F STX &F0 ;store stack pointer in &F0
DC41 LDX #&06 ;and issue ROM service call 6
DC43 JSR &F168 ;(User BRK) to ROMs
;at this point &FD/E point to byte after BRK
;ROMS may use BRK for their own purposes
DC46 LDX &028C ;get current language
DC49 JSR &DC16 ;select ROM
DC4C PLA ;get back original value of X
DC4D TAX ;
DC4E LDA &FC ;get back original value of A
DC50 CLI ;allow interrupts
DC51 JMP (&0202) ;and JUMP via BRKV (normally into current language)