It is currently Mon Oct 20, 2014 5:49 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 19 posts ] 
Author Message
 Post subject: Coping with Ctrl+Break
PostPosted: Sun Mar 07, 2010 5:28 pm 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
Hi,

Obvious question #1314:

I'm aware Break can't be disabled (ignoring the screw on the Master 128) but that it can be used fairly trivially to call a command after it's pressed using *KEY10.

Back in the early 90s though, I'm pretty sure I had some code which also had some effect over Ctrl+Break - specifically, the program I have in mind allowed you to add your own custom message under the BBC Computer text line which stayed there even when Ctrl+Break was used. No idea where that routine is now, tho.

Anyway - getting to the question, is there a way I can override Ctrl+Break to get it to respect something like:

Code:
*KEY10PAGE=&1900|MCHAIN"EXAMPLE"|M

?

Cheers,

Sam.


Top
 
PostPosted: Sun Mar 07, 2010 8:22 pm 
Offline
User avatar
 Profile

Joined: Sun Jun 28, 2009 11:37 pm
Posts: 55
Ctrl-Break can be intercepted by putting a JMP to the code you want to run at address &287 (or use OSBYTE &F7-&F9 to do it the OS legal way).

I've knocked together a quick demonstration that uses OSCLI to re-make the key 10 assignment (which would have been cleared by the Ctrl-Break), then the standard break handler will do the rest:

Code:
10 P%=&2000:[
20 BCS P%+3:RTS
30 LDX #&00:LDY #&21:JMP &FFF7
40 ]
50 $&2100="KEY10REPORT|M"
60 P%=&287:[JMP &2000:]

Once this program has been run, pressing Break or Ctrl-Break will run the key 10 definition.

Are you sure you want to do this though? It can be annoying when programs hijack the machine like this, forcing a power cycle when you're done with them.

Cheers,
Paul.


Top
 
PostPosted: Sun Mar 07, 2010 11:04 pm 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
PaulDv wrote:
Once this program has been run, pressing Break or Ctrl-Break will run the key 10 definition.

That's the sort of thing I was looking for, thanks.

PaulDv wrote:
Are you sure you want to do this though? It can be annoying when programs hijack the machine like this, forcing a power cycle when you're done with them.

Not entirely sure, no - I'm just experimenting atm but I don't think it's as bad as you're imagining. I don't intend to reload the same program, so two Ctrl+Breaks would return you to the usual reset state (as the second program wouldn't take over the Break key).

Sam.


Top
 
PostPosted: Mon Mar 08, 2010 10:27 am 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
I posted a similar routine here, which makes Break / Ctrl-Break just generate an error, which can then be trapped by BASIC's ON ERROR command. It's a slightly 'cleaner' way of trapping it which doesn't result in the *KEY definition from being seen as it's entered into the keyboard buffer.


Top
 
PostPosted: Mon Mar 08, 2010 11:19 am 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
Hmm ... Paul's routine seems to do what I want - but I'd like a way of stopping it after one Break or Ctrl+Break. I can set ?&287 to 0 in the Break key definition to stop the Ctrl+Break action working, but how can I disable the Break key, preferably without adding a new KEY10 definition to the program I want to be loaded on Break? Presumably I can poke somewhere to clear the KEY10 definition? Doing a *KEY10 within the first KEY10 definition is a no-no, because it results in a "Key in use" error message.

Also, Paul, you mentioned OSBYTE &F7-&F9 but then didn't appear to use that is there an OS-legal version of your patch?

Rich, I tried your patch on STH but couldn't get it to do anything - tried on two emulators. I'm not sure it does what I want, tho, from your description - I don't want to stop anyone from using Break (as Paul says, that would be annoying), I want to to catch the event once only and send them back to a menu.

Sam.


Top
 
PostPosted: Mon Mar 08, 2010 11:57 am 
Offline
User avatar
 Profile

Joined: Mon Jan 07, 2008 6:46 pm
Posts: 380
Location: Málaga, Spain
Just tried the following in BeebEm, based on the other code I posted - seems to work ok.

Code:
  10 REM Assemble BREAK intercept code
  20 P%=&900
  30 [OPT2:LDA&70:STA&202:LDA&71:STA&203:BRK:EQUB100:EQUS"Break":BRK:]
  40 !&70=!&202
  50 :
  60 REM Set BREAK intercept
  70 ?&287=&4C:?&288=0:?&289=9
  80 :
  90 REM Intercept errors and get them
 100 REM to return execution to here
 110 REM and reset BREAK intercept
 120 ON ERROR IF ERR=100:?&287=0
 130 :
 140 REM Some code here
 150 REM BREAK key will return here
 160 REM once only.
 170 REPEAT
 180 PRINT "Hello world"
 190 UNTIL FALSE


Attachments:
File comment: BREAK key intercept demo
break.zip [501 Bytes]
Downloaded 6 times
Top
 
PostPosted: Mon Mar 08, 2010 1:18 pm 
Offline
User avatar
 Profile

Joined: Sun Jun 28, 2009 11:37 pm
Posts: 55
Samwise wrote:
how can I disable the Break key, preferably without adding a new KEY10 definition to the program I want to be loaded on Break? Also, Paul, you mentioned OSBYTE &F7-&F9 but then didn't appear to use that is there an OS-legal version of your patch?

The easiest way I can think of is to use a different key definition then run it manually with the equivalent of *FX 138 in the break routine. That way, it can be disabled with a simple *FX 247,0

Code:
10 DEFFNLO(N)=N AND &FF
20 DEFFNHI(N)=N DIV &100
30 P%=&2000:[
40 .KEYDEF EQUS "KEY9REPORT|M":EQUB 13
50 .PATCH BCS P%+3:RTS
60 LDX #FNLO(KEYDEF):LDY #FNHI(KEYDEF):JSR &FFF7
70 LDA #138:LDX #0:LDY #137:JMP &FFF4
80 ]
90 P%=&287:[JMP PATCH:]

Most folks just seem to poke the code directly into &287, but if you want to use the OSBYTEs, replace line 90 with this:

Code:
90 *FX247,76
100 OSCLI"FX248,"+STR$FNLO(PATCH)
110 OSCLI"FX249,"+STR$FNHI(PATCH)


Top
 
PostPosted: Mon Mar 08, 2010 9:27 pm 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
OK, I've got both your examples working in test form ...

However, in practice, I'm trying to have it work behind the CH_EGG binary and it just hangs ...

I assumed it was to do with where the code is assembled so I've tried setting P% to &880 which I thought was safe in both examples, but that hasn't helped.

Possible, or am I in way over my head?

Sam.

P.S. Disc image attached with example code in SAMPDV2 and SAMRCH2, respectively.


Attachments:
File comment: break.ssd
break.zip [7.6 KiB]
Downloaded 7 times
Top
 
PostPosted: Mon Mar 08, 2010 11:22 pm 
Offline
User avatar
 Profile

Joined: Sun Jun 28, 2009 11:37 pm
Posts: 55
Looking at it briefly, putting the code at &880 should have been okay. However, Chuckie Egg sets the flag at &258 which clears the memory on break so it was wiping out the patch.

On the model B, moving the patch to &140 protects it from the memory clear and that seems to work. The Master is more problematic. It looks like it clears out the break vector too meaning the patch never gets called.

Anyone know of a way around this? If the built-in memory clear can't be used, the break patch would have to undo the damage Chuckie Egg does to pages &B and &D.


Top
 
PostPosted: Mon Mar 08, 2010 11:54 pm 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
Yep, compiling to &140 works with your patch on a basic Model B, though not with Rich's - I assume that's the fault of the &258 flag again.

Would be nice if I could find a way to make this work on a B+ and Master, though.

Sam.


Top
 
PostPosted: Tue Mar 09, 2010 2:22 pm 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
Just to add, I tested and it works on the Electron as well - so it's just the B+ and Master.

I had a look through my Master reference manuals but couldn't find anywhere talking about the memory clear - though I may just not be looking in the right place.

Any suggestions, Rich?

Sam.


Top
 
PostPosted: Sun Mar 14, 2010 7:39 pm 
Offline
User avatar
 Profile

Joined: Sun Jun 28, 2009 11:37 pm
Posts: 55
It doesn't look like it's possible to stop the break vector from being cleared on the master. The nearest thing to a solution I could think of was taking advantage of the fact that sideways ROMs are notified of a break. It might be possible to write a small service ROM (loaded into one of the master's SRAM banks) that catches the event and either makes the key definiton or re-sets the break vector. This does seem to be getting overly complicated though and, because of the requirement for an SRAM bank, still wouldn't work on a 64K B+.

Approaching it from the other angle, that is stopping Chuckie Egg from clearing the memory on reset, presents its own problem. The memory at &d00 is left full of junk which affects the way sideways ROMs are handled on break (Ctrl-Break works fine because that will reset the ROM table). I tried a few different ideas including trying to force Ctrl-Break behaviour on a normal break. This kind of worked, but on the master it always cleared out the break vector again.

So the question is, can the master be reset in such a way as to re-load the CMOS settings, re-build the ROM table in &d00 but not clear the vectors. And can it be done in a way that's compatible with all the other beeb models? I'm guessing not, but there's no harm in asking.

To be honest, Sam I think it would be better to just use the break key definition for the editor and leave the game as it is. That way, pressing Break simply quits out of the game, or pressing Shift-Break re-loads the menu, and it works on all machines. The simplest solution is often the best ;)


Top
 
PostPosted: Sun Mar 14, 2010 10:24 pm 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
Thanks, Paul.

I asked the question on the BBC Micro Mailing List here.

Looks like you're right - there isn't any simple way to achieve this on a beeb (though there was some mention of the sideways RAM not being cleared, so there might be a possibility of hiding something there. Though that might only work on MOS 3.2 anyway).

Unless anyone else comes up with a bright idea, I think I'll make it a BBC B/Electron only feature. Master / B+ owners can re-load the menu themselves (though it does require them to go through the main menu to get to the sub-menu in question).

Thanks for the effort you've put in investigating though, Paul. Really appreciate it!

Sam.


Top
 
PostPosted: Sun Mar 14, 2010 10:29 pm 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
Oh, and of course, Rich as well!!!

Sam.


Top
 
PostPosted: Thu Mar 18, 2010 5:32 pm 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
Hopefully one last, quick question. Paul, is it possible to modify your patch so it only works with Break (with the memory clear bit set- otherwise I'd use *KEY10!), but not Ctrl+Break?

Sam.


Top
 
PostPosted: Thu Mar 18, 2010 8:21 pm 
Offline
User avatar
 Profile

Joined: Sun Jun 28, 2009 11:37 pm
Posts: 55
Sure, just replace the old line 50:

Code:
50 .PATCH BCS P%+3:RTS

with this:

Code:
50 .PATCH BCS P%+3:.DONE RTS:LDA &028D:BNE DONE


Top
 
PostPosted: Sun Mar 21, 2010 3:27 pm 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
Paul,

Just tried your code amendment in two emulators, but it doesn't appear to change the behaviour i.e. both BREAK and CTRL+BREAK still call the key function. Here's what I'm running:

Code:
 10DEFFNLO(N)=N AND &FF
 20DEFFNHI(N)=N DIV &100
 25KEY$="KEY9*FX247,0|MCHAIN"+CHR$(34)+"MENU"+CHR$(34)+"|M"
 30P%=&140:[
 40.KEYDEF EQUS KEY$:EQUB 13
 50.PATCH BCS P%+3:.DONE RTS:LDA &02BD:BNE DONE
 60LDX #FNLO(KEYDEF):LDY #FNHI(KEYDEF):JSR &FFF7
 70LDA #138:LDX #0:LDY #137:JMP &FFF4
 80]
 90*FX247,76
100OSCLI"FX248,"+STR$FNLO(PATCH)
110OSCLI"FX249,"+STR$FNHI(PATCH)
120*RUN CH_EGG

Am I doing it wrong?

Sam.


Top
 
PostPosted: Sun Mar 21, 2010 4:04 pm 
Offline
User avatar
 Profile

Joined: Sun Jun 28, 2009 11:37 pm
Posts: 55
The instruction at line 50 should be LDA &028D (number 8, not letter B) ;)


Top
 
PostPosted: Sun Mar 21, 2010 4:08 pm 
Offline
Site Admin
User avatar
 Profile

Joined: Wed Dec 19, 2007 10:46 pm
Posts: 779
D'oh. :oops:

Yeah, that works great. Schoolboy error.

Thanks, Paul. Much appreciated!

Sam.


Top
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 19 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron