// RSilBanks.bcpl
get "AltoDefs.d"
get "Sil.defs"
external // incoming procedures
[
// OS
BitBlt
]
external // incoming statics
[
// OS
AltoVersion
lvSwatContextProc
]
external // outgoing
[
nBanks
]
static // statics defined here
[
nBanks = 0
]
manifest
[
BankRegs=#177740
emulator=0
dwt=#11
lnrasterwidth=9
rasterwidth=1 lshift lnrasterwidth
]
structure BANK [ blank bit 12; norm bit 2; alt bit 2 ]
let SetXM(bank) = valof
[
// default is quit if this is a non-XM Alto
// if upper memory has not already been initialized, then try to do so
if nBanks eq 0 then InitBanks()
if nBanks ls bank then
[ CallSwat("This is not an XM Alto.","Type any char to exit."); finish ]
resultis true
]
and InitBanks()=valof
[
// Returns zero if this is a non-XM Alto, or 1 through 4 depending on the
// number of (contiguous) memory banks present. As a side-effect, corrects
// parity in all banks (>0) that are present.
if AltoVersion<<VERS.eng ne 3 resultis 1 // An XM Alto is an "Alto 3"
nBanks=4
@activeInterrupts=@activeInterrupts & #177776 // Disable parity interrupt
let XM = @BankRegs
if XM ne #177761 then @BankRegs = #177761 // CallSwat("XM Init Problem")
let save=BankRegs!emulator
for bank=1 to 3 do
[
BankRegs!emulator=bank
xmstore(0, #125252); let r1=xmload(0)
xmstore(0, #52525); let r2=xmload(0)
if r1 ne #125252 % r2 ne #52525 then
[ nBanks=bank; break ]
xmzero(0,#177000,bank) // DoubleBlt(0, 0, #177000, bank lshift 2)
]
BankRegs!emulator=save
@wakeupsWaiting=@wakeupsWaiting & #177776 // Flush pending parity interrupt
@activeInterrupts=@activeInterrupts % 1 // Reenable parity interrupt
resultis nBanks
]
and xmzero(addr,count,bank) be
[
// zero count words starting at addr
let save=BankRegs!emulator
bank=bank<<BANK.alt
let function=#14 // replace with gray block
function<<BBT.dBank=bank ne 0
BankRegs!emulator=bank
// define width and height of blocks
let height=count rshift lnrasterwidth
let remainder=count & (rasterwidth-1)
// set up bitblt table
let BBTable=vec lBBT
BBTable=(BBTable+1)&(-2)
Zero(BBTable,lBBT)
BBTable>>BBT.function=function
BBTable>>BBT.dbca=addr
BBTable>>BBT.dbmr=rasterwidth
BBTable>>BBT.gray↑0=0
BBTable>>BBT.gray↑1=0
BBTable>>BBT.gray↑2=0
BBTable>>BBT.gray↑3=0
// if more than rasterwidth words then do a block
if height then
[
BBTable>>BBT.dw=rasterwidth*16
BBTable>>BBT.dh=height
BitBlt(BBTable)
]
// if any left over then do one line
if remainder then
[
BBTable>>BBT.dty=height
BBTable>>BBT.dw=remainder*16
BBTable>>BBT.dh=1
BitBlt(BBTable)
]
// restore the bank registers
BankRegs!emulator=save
]
and xmload(addr) be
[
xmload=table
[
#105000 // mov 0 1
#61025 // #61025 ; xmlda -- ac0 ← @ac1
#1401 // jmp 1 3
]
xmload(addr)
]
and xmstore(addr,value) be
[
xmstore=table
[
#41002 // sta 0 2 2
#121000 // mov 1 0
#25002 // lda 1 2 2
#61026 // #61026 ; xmsta -- @ac1 ← ac0
#1401 // jmp 1 3
]
xmstore(addr,value)
]