Skip to content

Commit

Permalink
Merge pull request #849 from leuat/TIM011_library_update
Browse files Browse the repository at this point in the history
Extended libraries, used for TimTris
  • Loading branch information
leuat authored Apr 6, 2024
2 parents a25026a + 135a6d3 commit 1d48fcc
Show file tree
Hide file tree
Showing 2 changed files with 335 additions and 39 deletions.
229 changes: 196 additions & 33 deletions units/TIM/system/file.tru
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ var
dst, ptmp : ^byte;
cpmfPos, cpmfByt, cpmfVal, i,j,k,l: byte;


/**
Class that realizes file access for Z80 CP/M
**/
Handle = class
Mode : byte; // read or write
ReadPos : byte; // current position in buffer, $FF means EOF
FilePos : byte; // current position in buffer, $FF means EOF
Buffer : array[128] of byte; // 128 bytes read from file
FCX : array[37] of byte; // FCX, USER (1) + FCB (36)

Expand All @@ -39,10 +40,10 @@ var
Z80CPM::bdos_hl(Z80CPM::BF_DMA, #this.Buffer);
if Z80CPM::bdos_a(Z80CPM::BF_READSEQ, #this.FCX) <> 0 then begin
this.ReadPos := EOF;
this.FilePos := EOF;
break;
end;
this.ReadPos := 0;
this.FilePos := 0;
ReadChunk_ret := true;
break;
end;
Expand Down Expand Up @@ -78,24 +79,23 @@ var
Z80CPM::bdos_hl(Z80CPM::BF_DMA, #this.Buffer);

if cpmfMode = ModeRead then begin
if Z80CPM::bdos_a(Z80CPM::BF_OPEN, #this.FCX) = 255 then begin
if Z80CPM::bdos_a(Z80CPM::BF_OPEN, #this.FCX) = EOF then begin
break;
end;
// Read first chunk from the file
//Handle::ReadChunk(this);
this.ReadChunk();
end else begin
if Z80CPM::bdos_a(Z80CPM::BF_FIND1ST, #this.FCX) <> 255 then begin
if Z80CPM::bdos_a(Z80CPM::BF_DELETE, #this.FCX) = 255 then begin
if Z80CPM::bdos_a(Z80CPM::BF_FIND1ST, #this.FCX) <> EOF then begin
if Z80CPM::bdos_a(Z80CPM::BF_DELETE, #this.FCX) = EOF then begin
break;
end;
end;

if Z80CPM::bdos_a(Z80CPM::BF_CREATE, #this.FCX) = 255 then begin
if Z80CPM::bdos_a(Z80CPM::BF_CREATE, #this.FCX) = EOF then begin
break;
end;

this.ReadPos := 0; // No data in buffer
this.FilePos := 0; // No data in buffer
end;

// Set file mode
Expand All @@ -107,6 +107,65 @@ var
Handle::Open := Open_ret;
end;

/**
Reads one byte from file's buffer and returns it.<br>
Sets handle's ReadPos to EOF if end of file is encountered.
**/
function ReadByte(): byte;
var
ReadByte_ret: byte;
begin
ReadByte_ret := EOF;
// Read next record if needed
if this.FilePos = 128 then this.ReadChunk();
// Read byte
if this.FilePos <> EOF then begin
ReadByte_ret := this.Buffer[this.FilePos];
this.FilePos += 1;
end;
Handle::ReadByte := ReadByte_ret;
end;

/**
Writes one byte to file's buffer.
**/
function WriteByte(File::cpmfByt: global byte): byte;
var
WriteByte_ret: byte;
begin
WriteByte_ret := EOF;
while (1) offpage do begin
// File opened for writing and without errors?
Z80CPM::PutString("W");
if this.Mode <> ModeWrite then begin
Z80CPM::PutString("1");
break;
end;
// Store character in buffer and increment position
this.Buffer[this.FilePos] := cpmfByt;
this.FilePos += 1;
Z80CPM::PutString("2");
// Write record if needed
if this.FilePos = 128 then begin
Z80CPM::PutString("3");
Z80CPM::bdos_hl(Z80CPM::BF_DMA, #this.Buffer);
//Z80CPM::PutString("4");
if Z80CPM::bdos_a(Z80CPM::BF_WRITESEQ, #this.FCX) = EOF then begin
Z80CPM::PutString("5");
this.FilePos := EOF;
break;
end;
Z80CPM::PutString("6");
this.FilePos := 0;
end;
WriteByte_ret := 0;
break;
end;
Z80CPM::PutString("7");
Handle::WriteByte := WriteByte_ret;
end;
/**
Closes the file
**/
Expand All @@ -116,8 +175,20 @@ var
begin
Close_ret := false;
while (1) do begin
// Writing mode?
if this.Mode = ModeWrite then begin
//Z80CPM::PutString("Close1\n\r");
while this.FilePos <> 0 do begin
this.WriteByte($1A);
if this.FilePos = EOF then ReturnValue(EOF);
end;
end;
//Z80CPM::PutString("Close2\n\r");
Z80CPM::bdos_hl(Z80CPM::BF_DMA, #this.Buffer);
if Z80CPM::bdos_a(Z80CPM::BF_CLOSE, #this.FCX) = 255 then break;
//Z80CPM::PutString("Close3\n\r");
if Z80CPM::bdos_a(Z80CPM::BF_CLOSE, #this.FCX) = EOF then break;
//Z80CPM::PutString("Close4\n\r");
// Success
Close_ret := true;
Expand All @@ -127,25 +198,6 @@ var
Handle::Close := Close_ret;
end;
/**
Reads one byte from file's buffer and returns it.<br>
Sets handle's ReadPos to EOF if end of file is encountered.
**/
function ReadByte(): byte;
var
ReadByte_ret: byte;
begin
ReadByte_ret := EOF;
// Read next record if needed
if this.ReadPos = 128 then this.ReadChunk();
// Read byte
if this.ReadPos <> EOF then begin
ReadByte_ret := this.Buffer[this.ReadPos];
this.ReadPos += 1;
end;
Handle::ReadByte := ReadByte_ret;
end;

/**
Reads a sequence of bytes from file until a defined value (cpmfVal) is encountered.<br>
Provided buffer will include that value and zero byte after it.<br>
Expand All @@ -155,7 +207,7 @@ var
function ReadUntil(File::cpmfBuffer: global pointer, File::cpmfVal: global byte): byte;
begin
cpmfPos := 0;
while this.ReadPos <> EOF do begin
while this.FilePos <> EOF do begin
cpmfByt := Handle::ReadByte(this);
cpmfBuffer[cpmfPos] := cpmfByt;
cpmfPos += 1;
Expand All @@ -173,7 +225,7 @@ var
function ReadBytes(File::cpmfBuffer: global pointer, File::cpmfVal: global byte): byte;
begin
cpmfPos := 0;
while this.ReadPos <> EOF do begin
while this.FilePos <> EOF do begin
cpmfByt := Handle::ReadByte(this);
cpmfBuffer[cpmfPos] := cpmfByt;
cpmfPos += 1;
Expand Down Expand Up @@ -252,22 +304,34 @@ f.LoadCompressedFile(d1.bin",$4000, $7000);
this.ReadAll(File::ptmp);
this.Close();
Compression::Decompress(File::ptmp,File::dst);
end;
end;
end; // end of Handle class
end;
// vars for ShowPic functions
x, y: byte;
tpcName: pointer;
adr, adr1: integer;
fpp3: pointer;
width, height, buffCnt, buffLeft, byteCnt, hCnt: byte;
PicFile : Handle;
const buffCntInit: byte = 64;
/**
Displays a TPC picture on coordinates (x,y) <br>
Coordinates are the same as tile cooridinates [0..127, 0..63].
**/
/*
procedure ShowPic(x, y: byte, tpcName: pointer);
var
adr, adr1: integer;
fpp3: pointer;
width, height, buffCnt, buffLeft, byteCnt, hCnt: byte;
PicFile : Handle;
*/
procedure ShowPic(x, y: global byte, tpcName: global pointer);
begin
if PicFile.Open(tpcName, ModeRead) offpage then begin
Expand Down Expand Up @@ -337,4 +401,103 @@ begin
end;
end;
/**
Prepares picture displaying using incremental display, on coordinates (x,y) <br>
Coordinates are the same as tile cooridinates [0..127, 0..63].
**/
function PreparePic(x, y: global byte, tpcName: global pointer): boolean;
begin
if PicFile.Open(tpcName, ModeRead) offpage then begin
// adr1 := $8000 + (x shl 8) + (y shl 2);
// adr1 := $8000 + x * 256 + y * 4;
asm("
// y*4
ld a,(File_y)
sla a
sla a
ld l,a
// x*256, x just goes into high byte
ld a,(File_x)
ld h, a
// add video address start
ld de,$8000
add hl, de
ld (File_adr1), hl
");
adr := adr1;
width := PicFile.Buffer[0];
height := PicFile.Buffer[1] << 2;
buffCnt := 2; // 2 bytes were used for dimensions
buffLeft := 126; // max 126 bytes are left in the buffer
ReturnValue(true);
end;
ReturnValue(false);
end;
/**
Shows part of prepared TPC image, returns true if there is more to show, otherwise false
**/
function ShowIncrementalPic(): boolean;
begin
while width > 0 offpage do begin
if hCnt = 0 then hCnt := height;
while hCnt > 0 offpage do begin
//byteCnt = (hCnt <= buffLeft) ? hCnt : buffLeft;
if hCnt <= buffLeft then
if hCnt <= buffCntInit then
byteCnt := hCnt
else
byteCnt := buffCntInit
else
if buffLeft <= buffCntInit then
byteCnt := buffLeft
else
byteCnt := buffCntInit;
// write bytes to video memory
fpp3 := #PicFile.Buffer[buffCnt];
asm("
ld bc, (File_adr)
ld hl, (File_fpp3)
ld de, (File_byteCnt)
ld e, d
ld d, 0
_outv2:
ld a, (hl)
out (c), a
inc c
inc hl
dec e
jp nz, _outv2
");
buffCnt += byteCnt;
buffLeft -= byteCnt;
hCnt -= byteCnt;
adr += byteCnt;
if buffLeft = 0 then begin
PicFile.ReadChunk();
buffCnt := 0;
buffLeft := 128;
end;
if hCnt > 0 then ReturnValue(true);
end;
adr1 += $100;
adr := adr1;
width -= 1;
end;
PicFile.Close();
ReturnValue(false);
end;
//procedure ShowPic(x, y: global byte, tpcName: global pointer);
//begin
// if PreparePic(x,y,tpcName) then
// while ShowIncrementalPic() do ;
//end;
end.
Loading

0 comments on commit 1d48fcc

Please sign in to comment.