--this module provides compatability between Altos and D Machines
--by implementing Long BITBLTs for Altos
DIRECTORY
LongDefs: FROM "LongDefs",
BcplOps: FROM "BcplOps",
BitBltDefs: FROM "BitBltDefs",
InlineDefs: FROM "InlineDefs",
SegmentDefs: FROM "SegmentDefs",
SystemDefs: FROM "SystemDefs";

Long: PROGRAM IMPORTS BcplOps, InlineDefs, LongDefs, SegmentDefs, SystemDefs
EXPORTS LongDefs =
BEGIN

NovaBBArgBlock: TYPE = MACHINE DEPENDENT RECORD
[
bank: CARDINAL,
bbt: POINTER TO BitBltDefs.BBTable
];

NovaCode: ARRAY [0..16) OF CARDINAL ←
[
54415B,-- STA3 saveret
115000B,-- MOV0 3AC3: @arg
22415B,-- LDA0 @bankno
40413B,-- STA0 savebanksavebank ← EmulatorBankRegister
21400B,-- LDA0 0,3
42412B,-- STA0 @banknoEmulatorBankRegister ← arg.bank
31401B,-- LDA2 1,3AC2: arg.bbt
126400B,-- SUB1 1AC1: 0
61024B,-- BITBLT
20405B,-- LDA0 savebank
42405B,-- STA0 @banknoEmulatorBankRegister ← savebank
34402B,-- LDA3 saveret
1400B,-- JMP0 3
0B,-- saveret: 0
0B,-- savebank: 0
177740B-- bankno: 177740
];

Machine: SegmentDefs.MachineType = SegmentDefs.GetMemoryConfig[].AltoType;
DMachine: PUBLIC BOOLEAN ← (Machine = D0) OR (Machine = Dorado);

SoftBITBLT: PUBLIC PROCEDURE [ptr: POINTER TO BitBltDefs.BBTable] =
BEGIN
srcBank: CARDINAL ← InlineDefs.HighHalf[ptr.slbca];
destBank: CARDINAL ← InlineDefs.HighHalf[ptr.dlbca];
randomPointer: POINTER;
arg: NovaBBArgBlock;
x: ARRAY [0..SIZE[BitBltDefs.BBTable]] OF UNSPECIFIED;
bbt: POINTER TO BitBltDefs.BBTable ← @x[LOOPHOLE[@x,CARDINAL] MOD 2];
bbt↑ ← ptr↑;

--make sure DMachine variable was initialized
IF DMachine THEN BEGIN LongDefs.HardBITBLT[ptr];RETURN;END;

bbt.ptrs ← short;
IF bbt.sourcetype = gray THEN srcBank ← 0;
IF (srcBank = 0) OR (srcBank = destBank) OR (destBank = 0) THEN --easy
BEGIN
bbt.sourcealt ← srcBank#0;
bbt.sbca ← InlineDefs.LowHalf[bbt.slbca];
bbt.destalt ← destBank#0;
bbt.dbca ← InlineDefs.LowHalf[bbt.dlbca];
arg ← [bank: InlineDefs.BITOR[srcBank,destBank], bbt: bbt];
[] ← BcplOps.BcplJSR[code: JSR, address: @NovaCode, arg: @arg];
RETURN;
END;
--nope, hard case; allocate bank 0 block of appropriate size
bbt.dlx ← 0;
bbt.dty ← 0;
bbt.dbmr ← (bbt.dw+15)/16;
randomPointer ← SystemDefs.AllocateSegment[bbt.dbmr*bbt.dh];
bbt.sourcealt ← TRUE;
bbt.sbca ← InlineDefs.LowHalf[bbt.slbca];
bbt.destalt ← FALSE;
bbt.dbca ← randomPointer;
bbt.function ← replace;
bbt.sourcetype ← block;
arg ← [bank: srcBank, bbt: bbt];
[] ← BcplOps.BcplJSR[code: JSR, address: @NovaCode, arg: @arg];

bbt.slx ← 0;
bbt.sty ← 0;
bbt.dlx ← ptr.dlx;
bbt.dty ← ptr.dty;
bbt.sbmr ← bbt.dbmr;
bbt.dbmr ← ptr.dbmr;
bbt.sourcealt ← FALSE;
bbt.sbca ← randomPointer;
bbt.destalt ← TRUE;
bbt.dbca ← InlineDefs.LowHalf[bbt.dlbca];
bbt.function ← ptr.function;
bbt.sourcetype ← ptr.sourcetype;
arg ← [bank: destBank, bbt: bbt];
[] ← BcplOps.BcplJSR[code: JSR, address: @NovaCode, arg: @arg];
SystemDefs.FreeSegment[randomPointer];
END;

InitMachineType: PUBLIC PROCEDURE = BEGIN END; --to initialize DMachine

END.