"Ignoring" an active 6502 second processor?

Discuss all aspects of programming here. From 8-bit through to modern architectures.
SteveF
Posts: 439
Joined: Fri Aug 28, 2015 8:34 pm

"Ignoring" an active 6502 second processor?

Postby SteveF » Fri Jan 13, 2017 11:30 pm

I have two versions of the PLASMA VM (http://www.stardot.org.uk/forums/viewto ... 55&t=12306) - one is called 'PLASMA' and the other is 'PLAS128'. Both take over from the current language - they freely use zero page workspace from &00-&8F and the memory at &400-&800.

PLASMA is not very interesting for the purposes of this post; it has load/exec addresses with the high order bits clear, so it loads and runs on a 6502 second processor if one is active, and it uses the relevant OS calls to read OSHWM/HIMEM and everything's just peachy.

PLAS128 is a BAS128-ish version which bank switches sideways RAM to use it for storing the user's program. This is not something I think can reasonably be made second processor compatible. I seem to have two options here:
  1. Set the high order bits of the load/exec addresses to 0, so it loads into the second processor if one is active. The first thing it does is check to see if that's the case, and exits with an error saying it's not second processor compatible.
  2. Set the high order bits of the load/exec addresses to &FFFF, so it loads and runs in the host even if a second processor is active. It will then proceed to trample all over &00-&8F, &400-&800 and all memory between OSHWM and HIMEM in the host. Pragmatically, this does mostly seem to work - I experience some weird failures, but I haven't made the necessary adjustments to all parts of my code as this was just a quick experiment.
My gut feeling is that the second option is just begging for subtle bugs to occur and I should go for the first. But the second option has a superficial veneer of user-friendliness about it, since it "just works".

Are these both viable options or not? And is there a third option I've overlooked?

User avatar
jgharston
Posts: 2764
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield

Re: "Ignoring" an active 6502 second processor?

Postby jgharston » Sat Jan 14, 2017 2:11 am

If your code needs to run in the I/O processor then you specify in the load/exec addresses that it needs to run in the I/O processor. You don't specify that it needs to run in the language processor and then complain if it finds itself in the language processor.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

User avatar
BigEd
Posts: 1499
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: "Ignoring" an active 6502 second processor?

Postby BigEd » Sat Jan 14, 2017 8:33 am

Sounds like option 2 is supposed to work. And it should also work if there happens to be, say, a Z80 or x86 copro in place.

(Is there an official way for 6502 code to refuse to be loaded and run on a non-6502 copro?? I know that ROM code has a machine type byte, which means PLASMA-in-ROM would be able to do this, but what about an application on disk? What about Z80 code launched when there is no Z80? My best guess would be that it's down to the user to know what they've got and what they are doing. Perhaps the universal answer would have to be a stub loader for the 6502 which runs in the host and then somehow has a look around to see which version of the application to run, and where.)

User avatar
jgharston
Posts: 2764
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield

Re: "Ignoring" an active 6502 second processor?

Postby jgharston » Sat Jan 14, 2017 12:32 pm

BigEd wrote:Sounds like option 2 is supposed to work. And it should also work if there happens to be, say, a Z80 or x86 copro in place.

It can't refuse to be loaded, how do you stop *LOAD from operating?
However, code can refuse to be executed. You start it with a standard code header.

The shortest possible code header is the following 12 bytes:

Code: Select all

  .load
  JMP start            :\ Entry point
  EQUB 0:EQUB 0:EQUB 0 :\ No service entry
  EQUB codetype        :\ CPU type
  EQUB 8               :\ Offset to copyright string
  EQUB 0:EQUS "(C)"    :\ Copyright string
  .start
The codetype is &40+cpu code, eg &42=65x2, &43=6809, &47=PDP11, &48=Z80, &49=32000, etc.

A full code header is:

Code: Select all

  .load
  JMP start              :\ Entry point
  EQUB 0:EQUB 0:EQUB 0   :\ No service entry
  EQUB codetype          :\ CPU type
  EQUB copy-load         :\ Offset to copyright string
  EQUB &00               :\ Binary version number
  EQUS "Title"           :\ Title string
  EQUB &00
  EQUS "0.00 (01 Jan 1990)"      :\ Version string
  .copy
  EQUB 0:EQUS "(C)J.G.Harston"   :\ Copyright string
  EQUB 0
  EQUD load
  .start
The codetype is &60+cpu code, eg &62=65x2, &63=6809, &67=PDP11, &68=Z80, etc.

If run on a CPU other than the one specified in the code header you get an error such as 'This is not 6502 code'.

See also this article on writing machine code utilities that interact with BASIC, and the Tube Client documents at here, here, here, etc.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

SteveF
Posts: 439
Joined: Fri Aug 28, 2015 8:34 pm

Re: "Ignoring" an active 6502 second processor?

Postby SteveF » Sat Jan 14, 2017 2:27 pm

Thanks guys. I'm afraid I'm running into a problem...

As I say, my application wants to use all the language workspace between &400-&800. This means that - to give the example I've run into at the moment - when it tries to acknowledge an Escape condition by calling OSBYTE &7E, the tube host code in page &4 is executed and the system crashes, because it's been overwritten. I've created a test program which shows this in a simplified form:
Screenshot from 2017-01-14 14-23-09.png

When OSBYTE &7E is executed, the tube host code ends up executing the JMP at &403 and (because this test program carefully chooses to use &404 and &405 in a particular way) the code at 'boom' is executed and it displays a '+'. The real application would have some arbitrary data at &404 and &405.

It would seem the obvious solution to this is for my code to disable the second processor as soon as it starts - is that right? Presumably by doing the same as *TUBEOFF here: http://mdfs.net/Software/Tube/BBC/TubeSwitch

ETA: I note that Acorn don't appear to have taken this route for BAS128. Still, it would be nice to do better than them if I can. :-)
Screenshot from 2017-01-14 12-29-54.png


Code: Select all

DIM code% 256
oswrch=&FFEE
osrdch=&FFE0
osbyte=&FFF4
FOR opt%=4 TO 7 STEP 3
O%=code%:P%=&2000
[OPT opt%
.start
LDA #boom MOD 256:STA &404
LDA #boom DIV 256:STA &405
LDA #ASC("?"):JSR oswrch
.loop
JSR osrdch
BCS escape
JSR oswrch
JMP loop
.escape
LDA #&7E:JSR osbyte
LDA #ASC("!"):JSR oswrch
JMP loop
.boom
LDA #ASC("+"):JSR oswrch
.spin
JMP spin
]
NEXT
save$="SAVE TEST "+STR$~code%+" "+STR$~O%+" FFFF"+STR$~start+" FFFF"+STR$~start
PRINT save$
OSCLI save$
Attachments
test.zip
(584 Bytes) Downloaded 12 times

User avatar
BigEd
Posts: 1499
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: "Ignoring" an active 6502 second processor?

Postby BigEd » Sat Jan 14, 2017 5:35 pm

jgharston wrote:See also this article on writing machine code utilities that interact with BASIC, and the Tube Client documents at here, here, here, etc.

Great pointers - thanks JGH. (Now that I'm able to run so many copros, I need some hints as to how to use them.)

User avatar
jgharston
Posts: 2764
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield

Re: "Ignoring" an active 6502 second processor?

Postby jgharston » Sun Jan 15, 2017 6:52 pm

Yes, if you want to run in the I/O processor, and take over the I/O processor's language workspace, you have to kick out the current language - which, if a Tube is active is the Tube host code. You do that by clearing the Tube flag at &27A/OSBYTE &EA (to stop the MOS and filing systems calling the Tube host code) and claiming BRKV and EVENTV (which have been claimed by the Tube host code). You're then left with the puzzle of how to return from your code. The simplest solution is to not return, but require that the user presses Break.

It is contradictory to be attempting to run a language/application in the I/O processor, you normally run I/O code in the I/O processor and so use the memory that I/O code is allowed to use in the I/O processor - which is not language/application memory. So, yes, when trying to lever an application into running in the I/O processor you have to jump through hoops to get the system to swallow it without barfing.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

SteveF
Posts: 439
Joined: Fri Aug 28, 2015 8:34 pm

Re: "Ignoring" an active 6502 second processor?

Postby SteveF » Sun Jan 15, 2017 8:50 pm

Thanks Jonathan, I'll give that a try and see if I can make it work.

User avatar
jgharston
Posts: 2764
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield

Re: "Ignoring" an active 6502 second processor?

Postby jgharston » Mon Jan 16, 2017 10:52 pm

Update:
Code header: Wiki article on writing code with a header indicating what CPU it is intended to run on.

I've been wrangling the mess of ARM headers, and decided to get what I've written so far uploaded rather than try and get it perfect straight away.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

User avatar
BigEd
Posts: 1499
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: "Ignoring" an active 6502 second processor?

Postby BigEd » Tue Jan 17, 2017 10:21 am

Thanks JGH. That's an interesting capability and is new to me. (I knew about ROMs but didn't know the same story can optionally be applied to executables.)


Return to “programming”

Who is online

Users browsing this forum: No registered users and 1 guest