I've been playing around and I think I've managed to persuade the OS character output routines to work in mode 7 with the screen RAM at &3C00, so I should be able to have &4000-&C000 (32K) of contiguous free RAM. Here's the code I've come up with (attached as a zipped .ssd too):
Code: Select all
MODE 7 HIMEM=&3C00 IF INKEY-256<>-1 THEN PRINT "Sorry, BBC B only!":END vdu_status=&D0 wrchv=&20E keyv=&228 rts_opcode=&60 crtc_screen_start_high=12 crtc_cursor_start_high=14 crtc_register=&FE00 crtc_data=&FE01 FOR opt%=0 TO 2 STEP 2 P%=&900 [OPT opt% .start .nop_to_patch nop LDA #rts_opcode:STA nop_to_patch \ We install a wrapper around OSWRCH which adjusts the CRTC cursor position \ after every character output, otherwise the cursor is invisible. LDA wrchv:STA call_old_wrchv+1 LDA wrchv+1:STA call_old_wrchv+2 LDA #our_oswrch MOD 256:STA wrchv LDA #our_oswrch DIV 256:STA wrchv+1 \ In order to make cursor editing work, we need to adjust the CRTC cursor \ position during that too. Hooking the keyboard timer interrupt is the best \ way I've thought of to get a chance to do this. LDA keyv:STA call_old_keyv+1 LDA keyv+1:STA call_old_keyv+2 LDA #our_keyv MOD 256:STA keyv LDA #our_keyv DIV 256:STA keyv+1 RTS \ .our_oswrch .call_old_wrchv JSR &FFFF \ patched PHA OPT FNadjust_cursor(opt%) PLA RTS \ .our_keyv BCC call_old_keyv BVC call_old_keyv \ keyboard timer interrupt entry JSR call_old_keyv PHP PHA BIT vdu_status BVC not_cursor_editing OPT FNadjust_cursor(opt%) .not_cursor_editing PLA PLP RTS .call_old_keyv JMP &FFFF \ patched ] NEXT CALL &900 : VDU 28,0,24,39,0 PROCcrtc(crtc_screen_start_high, &20) ?&34E=&3C:REM high byte of bottom of screen memory ?&351=&3C:REM high byte display start address for 6845 PRINT CHR$(12);:REM force OS to pick up new settings $&7C00="Hello, world!":REM note this doesn't appear on screen PRINT "We're now in mode 7 with the screen RAM"'"at &3C00. The OS is happy, as long as wedon't do VDU 26. Cursor editing works"'"too." END : DEF PROCcrtc(R%,V%) VDU 23,0,R%,V%,0,0,0,0,0,0 ENDPROC : DEF FNadjust_cursor(opt%) [OPT opt% LDA #crtc_cursor_start_high:STA crtc_register LDA &34B:SEC:SBC #&1C:STA crtc_data ] =opt%
So I have a few questions:
- Have I missed something which would let me get the OS to position the cursor correctly without needing to hook those vectors?
- Is there a better alternative to the keyboard timer event to make cursor editing work?
- I've only been able to test this on jsbeeb. Is it likely to work on real hardware? Obviously it will only work on a model B, but that's fine, because on anything else I'll just use a shadow mode instead.
- Are there any other flaws in this plan which I've overlooked?