ROM Tool

About

ROM Tool (RT) is a simple BASIC utility to program sideways RAM and EEPROM modules with ROM images.

Written in BBC BASIC 2 for an Acorn BBC Microcomputer Model A/B.

The commented version requires PAGE at &1900 or below. The uncommented version will run with PAGE at &2000 so should work with multiple filesystems loaded (e.g. DFS & MMFS, ADFS etc).

Permission is freely given to copy and modify this source for non-commercial use.

How do I transfer this to my BBC?

SSD Disc Image

Current version RTool v1.02

Download SSD

Disc Contents
RTool

Comments stripped version. OK for PAGE at &2000

BAS2PRG Program BASIC 2 into the EEPROM
V.RT102 Commented version. OK for PAGE at &1900
R.RT102

ROM FS image for *ROM file system

Instructions

Mount disc image then CHAIN"RTOOL" to run. Press ? for command summary/help.

Basic version

RTool requires BASIC version 2 or later. Most machines will already have a BASIC2 ROM fitted.

To find out which BASIC you have press BREAK then type REPORT at the prompt. It will display "(C)1981 Acorn" for BASIC1 or "(C)1982 Acorn" for BASIC2.

BASIC2 is a useful upgrade. You can program BASIC2 into the EEPROM with CHAIN"BAS2PRG" on the tools disk. Follow the on screen instructions. When BASIC2 is programmed you should turn off the machine and remove your original BASIC1 ROM. BASIC2 will run from the EEPROM module.

Most users will want BASIC to be the highest priority ROM so it starts when the machine is turned on. To do this load BASIC2 into the highest bank number of your EEPROM and insert the EEPROM module in the right most ROM socket of the BBC Micro.

Automate RTool

RTool is a BASIC program which means you can automate it with !BOOT or *EXEC.

For example on a floppy disc (or solid state disc image).

*OPT4,3
*BUILD !BOOT
CHAIN"RTOOL"
L:0.R.RT102
P4
Q
<ESCAPE>

On SHIFT+BREAK (or *EXEC !BOOT) this !BOOT file would run RTool, load ROM image R.RT101 from drive 0, program it to slot/bank 4 and quit.

Source

REM BooBip.com
REM BASIC sideways EEPROM/RAM utility
REM (C)2017-2018 Chris Morley
MODE7
HIMEM=&3C00
*FX15,1
ON ERROR GOTO 260
roms%=&80
PROCassemble

P."BooBip.com"'"BASIC sideways EEPROM/RAM utility"'"Version 1.02"
P.FNromlist

REPEAT
P."? ";:REPEAT:K%=INKEY(100):UNTIL K%<>-1
F$="unrecognised":A$=""
RESTORE
REPEAT:READ key$,func$,arg$,help$:IF key$=CHR$(K%) THEN F$=func$:A$=arg$
UNTIL key$=""
P.CHR$(K%);" ";
IF A$<>"" THEN INPUT ""A$:A%=VAL(A$)
P.EVAL("FN"+F$)
UNTIL FALSE

REM Error reporter
REPORT:P.
GOTO 140

DATA "I","romlist","","List ROMs"
DATA "*","oscli","<cmd>","Issue user OS Command"
DATA ".","cat","","Catalogue filesystem (*.)"
DATA "D","drive","<drive>","Change drive"
DATA "L","load","<afsp>","Load ROM image from file"
DATA "S","save","<afsp>","Save ROM image to file"
DATA "R","read","<bank>","Read ROM image"
DATA "P","program","<bank>","Program ROM image"
DATA "V","verify","<bank>","Verify ROM image"
DATA "E","erase","<bank>","Erase complete 64kB EEPROM"
DATA "K","lock","<bank>","Lock (write protect) SRAM"
DATA "U","unlock","<bank>","Unlock (write enable) SRAM"
DATA "Q","quit","","Quit"
DATA "B","reset","","Reboot computer"
DATA "?","help","","Display this help"
DATA "","","",""

DEF FNunrecognised="Unrecognised command. ? for help"

DEF FNquit
*FX200,2
CALL !&FFFC
=0

DEF FNreset
*KEY10OLD|MRUN|M
CALL !&FFFC
=0

DEF FNoscli
OSCLI(A$)
=""

DEF FNcat
*CAT
=""

DEF FNdrive
OSCLI("DRIVE "+A$)
=""

DEF FNload
R$="LOAD "+A$+" "+STR$~(HIMEM)
OSCLI(R$)
=R$

DEF FNsave
R$="SAVE "+A$+" "+STR$~(HIMEM)+"+4000"
OSCLI(R$)
=R$

DEF FNread
CALL copy_down
=""

DEF FNprogram
IF roms%?A% AND 1 THEN R$="EEPROM":CALL ee_write
IF (roms%?A% AND &20) THEN R$="SRAM":CALL sr_unlock:CALL copy_up:CALL sr_lock
="Program "+R$+" bank "+STR$(A%)

DEF FNverify
S%=USR(verify) AND 255
IF S%=FALSE THEN R$=CHR$(129)+"fail" ELSE R$=" OK"
="Verify "+R$

DEF FNerase
CALL ee_erase
=""

DEF FNlock
CALL sr_lock
=""

DEF FNunlock
CALL sr_unlock
=""

DEF FNhelp
RESTORE
REPEAT:READ key$,func$,arg$,help$:IF help$<>"" THEN P.'" ";key$;" ";arg$;TAB(10);CHR$(134);help$;
UNTIL key$=""
=""

DEF PROCscan
REM Blank check
FOR A%=0TO15:S%=USR(ee_blankcheck) AND &FF
IF S%=&FF THEN roms%?A%=2 ELSE roms%?A%=0
N.

REM Find EEPROM
FOR A%=0TO3:S%=USR(ee_readid) AND &FFFF
FOR J%=A%TO15STEP4:IF S%=&5DBF THEN roms%?J%=roms%?J% OR 1
N.:N.

REM Writeable check
FOR A%=0TO15
S%=USR(sr_testw) AND &FF:IF S%=0 THEN roms%?A%=roms%?A% OR &10
CALL sr_unlock
S%=USR(sr_testw) AND &FF:IF S%=0 THEN roms%?A%=roms%?A% OR &20
IF roms%?A%=&20 THEN CALL sr_lock
N.
ENDPROC

DEF FNromlist
PROCscan
P.'"ROM#";TAB(5);"Type";TAB(12);"Title";
FOR A%=0TO15
P.';A%;CHR$(134);TAB(5);FNtype(A%);CHR$(131);TAB(12);
IF roms%?A% AND 2 THEN P."(blank)"; ELSE CALL print_rom_title
N.
P.
=""

DEF FNtype(R%)
A$="ROM"
IF roms%?A% AND 1 THEN A$="EEPROM"
IF (roms%?A% AND &30)=&30 THEN A$="SRAM U"
IF (roms%?A% AND &30)=&20 THEN A$="SRAM L"
=A$

REM EEPROM detect, program & erase subroutines
DEF PROCassemble
REM DIM mc% 384
mc%=&B40
bufpage%=HIMEM DIV 256
FOR pass%=0TO2STEP2
P%=&70
[opt pass%
.src
EQUW 0
.dst
EQUW 0
.rom
EQUB 0
]
P%=mc%
[opt pass%
.copyright
EQUB 0
EQUS "(C)"

\*******************
\ JEDEC magic sequence
\ params; ROM# in rom, command in X
\ returns; (nothing)
.magic
LDA rom
AND #3
ORA #&44:STA &FE30:LDY #&AA:STY &9555 \EEPROM write &5555=&AA
AND #&43:STA &FE30:LDY #&55:STY &AAAA \EEPROM write &2AAA=&55
ORA #&44:STA &FE30:STX &9555 \EEPROM write &5555=cmd
LDA rom:ORA #&40:STA &FE30 \ select correct ROM
RTS

\*******************
\ EEPROM read chip ID
\ params; ROM# in A
\ returns; Mfg ID in X Chip ID in A
.ee_readid
STA rom:PHP:SEI \store flags & disable interrupts
LDX #&90:JSR magic \ EEPROM enter ID mode
LDA &8000:PHA:LDA &8001:PHA \ read mfg & id
LDX #&F0:JSR magic \ EEPROM leave ID mode
PLA:TAX:PLA
JMP cleanexit

\*******************
\ EEPROM erase chip
\ params; ROM# in A
\ returns; (nothing)
.ee_erase
STA rom:PHP:SEI \store flags & disable interrupts
LDX #&80:JSR magic:LDX #&10:JSR magic \ EEPROM erase sequence
jsr ee_wait
JMP cleanexit

\*******************
\ EEPROM write
\ params; ROM# in A
\ returns; (nothing)
.ee_write
STA rom:PHP:SEI \store flags & disable interrupts
LDX #&BF:STX dst+1:LDX #bufpage%+&3F:STX src+1
.ee_pagewrite
LDX #&A0:JSR magic \ EEPROM enter page program mode
LDY#0
.ee_pagewrite1:LDA (src),Y:STA (dst),Y:INY:BPL ee_pagewrite1 \copy 128 bytes data
jsr ee_wait
LDX #&A0:JSR magic \ EEPROM enter page program mode
LDY#&80
.ee_pagewrite2:LDA (src),Y:STA (dst),Y:INY:BMI ee_pagewrite2 \copy 128 bytes data
jsr ee_wait
DEC src+1:DEC dst+1:BMI ee_pagewrite
JMP cleanexit

.ee_wait
LDA src+1
.ee_waitloop2:LDX &8000:CPX &8000:bne ee_waitloop2 \ wait for write to complete
RTS

\*******************
\ EEPROM blank check
\ params; ROM# in A
\ returns; A=&FF if blank
.ee_blankcheck
PHP:SEI \store flags & disable interrupts
STA &FE30 \ select ROM
LDA #&FF:LDX #&BF:STX bc_tploop+2:LDX #0 \initialise loop
.bc_tploop:AND &8000,X:INX:BNE bc_tploop
CMP #&FF:BNE cleanexit
DEC bc_tploop+2
BMI bc_tploop
.cleanexit
LDY &F4:STY &FE30  \ restore OS selected ROM
PLP \restore interrupt flag
RTS

\*******************
\ Print ROM title
\ params; ROM# in A
\ returns; (nothing)
.print_rom_title
PHP:SEI \store flags & disable interrupts
STA &FE30 \ select ROM
LDA &8007 \ get copyright offset
ADC #3:TAX:LDY #3
.copyrightloop
LDA copyright,Y
BEQ copyrightok
CMP &8000,X \ check ROM (C) string
BNE cleanexit
DEX:DEY:BNE copyrightloop
.copyrightok
LDX #9
.printloop
LDA &8000,X:BNE prtout:LDA #32:.prtout:JSR &FFEE \load and print character
INX:CPX &8007:BNE printloop
JMP cleanexit

\*******************
\ Copy ROM to low memory
\ params; ROM# in A
\ returns; (nothing)
.copy_down
PHP:SEI \store flags & disable interrupts
STA &FE30 \ select ROM
LDX #&80:STX src+1:LDX #bufpage%:STX dst+1:LDY #0:LDX #&40 \ setup source and destination
.copy_loop:LDA (src),Y:STA (dst),Y:INY:BNE copy_loop \ copy a 256 byte page
INC src+1:INC dst+1:DEX:BNE copy_loop
JMP cleanexit

\*******************
\ Copy low memory to sideways RAM
\ params; ROM# in A
\ returns; (nothing)
.copy_up
PHP:SEI \store flags & disable interrupts
STA &FE30 \ select ROM
LDX #bufpage%:STX src+1:LDX #&80:STX dst+1:LDY #0:LDX #&40 \ setup source and destination
JMP copy_loop

\*******************
\ Verify ROM
\ params; ROM# in A
\ returns; ??
.verify
PHP:SEI \store flags & disable interrupts
STA &FE30 \ select ROM
LDX #&80:STX src+1:LDX #bufpage%:STX dst+1:LDY #0:LDX #&40 \ setup source and destination
.verify_loop:LDA (src),Y:CMP (dst),Y:BNE verify_bad:INY:BNE verify_loop \ verify a 256 byte page
INC src+1:INC dst+1:DEX:BNE verify_loop \ advance to next page
LDA #&FF
JMP cleanexit
.verify_bad
LDA #0:JMP cleanexit

\*******************
\ Set write protect sideways RAM
\ params; ROM# in A
\ returns; (nothing)
.sr_lock
PHP:SEI \store flags & disable interrupts
ORA #&20:STA &FE30 \ set wp
JMP cleanexit

\*******************
\ Clear write protect sideways RAM
\ params; ROM# in A
\ returns; (nothing)
.sr_unlock
PHP:SEI \store flags & disable interrupts
ORA #&30:STA &FE30 \ clear wp
JMP cleanexit

\*******************
\ Test writeable sideways RAM
\ params; ROM# in A
\ returns; A=0 if writeable
.sr_testw
PHP:SEI \store flags & disable interrupts
STA &FE30 \ select ROM/RAM
LDX &8008:TXA \ save SWRAM value in Y
EOR #&FF:STA &8008:EOR &8008 \ test if writeable
STX &8008 \ restore SWRAM value
JMP cleanexit

]
NEXT
REM P."MC size=";(P%-mc%)
ENDPROC