diff --git a/doc/pascalprogramming.md b/doc/pascalprogramming.md index 0d5e4cd..454b46b 100644 --- a/doc/pascalprogramming.md +++ b/doc/pascalprogramming.md @@ -111,7 +111,7 @@ If heap allocation fails, *new* does not return and instead causes a runtime err variable to *niL* if heap allocation fails. The function *MemAvail* returns the number of free bytes on the heap. It does not guarantee that this amount of memory can be allocated with *new*, because heap space can be fragmented. -The function *MaxAvail* returns the size of the largest contiguous block of available heap memory in bytes. +The function *MaxAvail*, which exists in some versions of Turbo Pascal and returns the size of the largest contiguous block of available heap memory, is not (yet) implemented. ## I/O I/O handling in Tridora Pascal is mostly compatible with other Pascal dialects when reading/writing simple variables from/to the console. There are big differences when opening/reading/writing files explicitly. @@ -236,7 +236,7 @@ In Wirth Pascal, labels must be numbers. Other Pascal dialects also allow normal Tridora-Pascal only allows identifiers as labels. ## Units -Units are the method to create libraries in Tridora-Pascal, that is, code modules that can +Units are the method to create libraries in Tridora-Pascal, that is, codes module that can be reused in other programs. Tridora-Pascal follows the unit syntax that has been established in UCSD-Pascal and is also @@ -275,7 +275,7 @@ in the *SYSTEM* volume. A unit implementation file should start with a *UNIT* statement instead of a *PROGRAM* statement. -It should only be compiled, not assembled. +It should be compiled, not assembled. When building a program that uses units, the assembler will include an assembly language file for each unit. diff --git a/doc/vga.md b/doc/vga.md index 3ef8f8d..76520f2 100644 --- a/doc/vga.md +++ b/doc/vga.md @@ -9,11 +9,11 @@ Registers | _FB_PS_ | $90C | Palette Select | | _FB_PD_ | $910 | Palette Data | | _FB_CTL_ | $914 | Control Register | -| _FB_SHIFTER_ | $918 | Shift Assist Register | -| _FB_SHIFTCOUNT_ | $91C | Shift Count Register | -| _FB_SHIFTERM_ | $920 | Shifted Mask Register | -| _FB_SHIFTERSP_ | $924 | Shifter Spill Register | -| _FB_MASKGEN_ | $928 | Mask Generator Register | +| _FB_SHIFTER | $918 | Shift Assist Register | +| _FB_SHIFTCOUNT | $91C | Shift Count Register | +| _FB_SHIFTERM | $920 | Shifted Mask Register | +| _FB_SHIFTERSP | $924 | Shifter Spill Register | +| _FB_MASKGEN | $928 | Mask Generator Register | ## Pixel Data Pixel data is organized in 32-bit-words. With four bits per pixel, one word @@ -121,12 +121,12 @@ For each four bits of a pixel, the corresponding four mask bits are all set to one if the pixel value is not zero. This can be used to combine foreground and background pixel data -where a pixel value of zero is used to indicate a transparent foreground pixel. +with a pixel value of zero for a transparent background color. -Usually, the mask will be inverted with a *NOT* instruction. -The result can then be used to clear all pixels in the background -that are set in the foreground, using an *AND* instruction. -As the last step, foreground and masked background data can be combined with an *OR* instruction. +Usually, the mask will be inverted with a *NOT* instruction +to clear all pixels in the background that are set in the foreground +with an *AND* instruction +before *ORing* foreground and background together. Example in hexadecimal, each digit is a pixel: | Pixel Data | Mask | diff --git a/examples/animate.pas b/examples/animate.pas index 79cfc82..0e4bb73 100644 --- a/examples/animate.pas +++ b/examples/animate.pas @@ -1,55 +1,34 @@ program animate; -uses sprites,pcmaudio; +uses sprites; type PictData = record magic,mode:integer; palette: array [0..15] of integer; pixeldata: array [0..31999] of integer; - end; + end; Sprite = record x,y:integer; + oldX,oldY:integer; xdelta,ydelta:integer; curFrame:integer; frameCount:integer; frameTime:integer; frameLeft:integer; - moveTime:integer; - moveLeft:integer; changed:boolean; frame:array [0..3] of SpritePixels; end; var pic:PictData; + filename:string; infile:file; ch:char; stickMan:Sprite; rocket:Sprite; - rocket2:Sprite; - rocket3:Sprite; - - buf:SndBufPtr; - procedure WaitVSync; external; -function readAudioFile(fname:string):SndBufPtr; -var size:integer; - buf:SndBufPtr; - f:file; -begin - open(f, fname, ModeReadOnly); - size := FileSize(f); - new(buf, size); - - ReadSample(f, buf); - - writeln; - close(f); - readAudioFile := buf; -end; - -procedure changePalette(var pic:PictData); +procedure loadPalette(var pic:PictData); var i:integer; begin for i := 0 to 15 do @@ -61,16 +40,6 @@ begin PutScreen(pic.pixeldata); end; -procedure loadPic(filename:string;var pic:PictData); -var infile:file; -begin - open(infile, filename, ModeReadonly); - read(infile, pic); - close(infile); - - writeln('magic: ', pic.magic, ' mode:', pic.mode); -end; - procedure loadSpriteFrame(var aSprite:Sprite;spriteIndex:integer; var sheetFile:file;sheetIndex:integer); begin @@ -86,132 +55,94 @@ end; procedure animateSprite(var aSprite:Sprite); var frameIndex:integer; frameTime,frameLeft:integer; - moveTime,moveLeft:integer; ydelta:integer; + oldX,oldY:integer; begin ydelta := aSprite.ydelta; frameIndex := aSprite.curFrame; frameTime := aSprite.frameTime; frameLeft := aSprite.frameLeft; - moveTime := aSprite.moveTime; - moveLeft := aSprite.moveLeft; + oldX := aSprite.x; oldY := aSprite.y; + aSprite.oldX := oldX; aSprite.oldY := oldY; frameLeft := frameLeft - 1; if frameLeft <= 0 then begin frameIndex := frameIndex + 1; - frameLeft := frameTime; + frameLeft := aSPrite.frameTime; + aSprite.frameLeft := frameLeft; aSprite.curFrame := frameIndex; if frameIndex >= aSprite.frameCount then aSprite.curFrame := 0; - end; - moveLeft := moveLeft - 1; - if moveLeft <= 0 then - begin + aSprite.frameLeft := frameLeft; + aSprite.x := aSprite.x + aSprite.xdelta; aSprite.y := aSprite.y + aSprite.ydelta; - moveLeft := moveTime; if aSprite.x > 608 then aSprite.x := 0; - if aSprite.ydelta <> 0 then + if aSprite.y < 0 then begin - if aSprite.y < 3 then - aSprite.ydelta := -aSprite.ydelta - else - if aSprite.y > 130 then - aSprite.ydelta := -aSprite.yDelta; + aSprite.y := 200; + aSprite.x := 0; end; end; - aSprite.frameLeft := frameLeft; - aSprite.moveLeft := moveLeft; end; procedure animLoop; var i:integer; - lastX,lastY:integer; - rlastX,rlastY:integer; - r2lastX,r2lastY:integer; - r3lastX,r3lastY:integer; + oldX,oldY:integer; + roldX,roldY:integer; begin stickMan.x := 0; - stickMan.y := 205; + stickMan.y := 310; stickMan.frameTime := 6; stickMan.frameLeft := stickMan.frameTime; stickMan.curFrame := 0; stickMan.xdelta := 2; stickMan.ydelta := 0; - stickMan.moveTime := 2; - stickman.moveLeft := stickMan.moveTime; + rocket.x := 0; - rocket.y := 50; - rocket.frameTime := 5; + rocket.y := 200; + rocket.frameTime := 1; rocket.frameLeft := rocket.frameTime; rocket.curFrame := 0; - rocket.xdelta := 3; - rocket.ydelta := 1; - rocket.moveTime := 1; - rocket.moveLeft := rocket.moveTime; - - rocket2.x := 50; - rocket2.y := 190; - rocket2.frameTime := 5; - rocket2.frameLeft := rocket2.frameTime; - rocket2.curFrame := 1; - rocket2.xdelta := 3; - rocket2.ydelta := 0; - rocket2.moveTime := 1; - rocket2.moveLeft := rocket2.moveTime; - - rocket3.x :=100; - rocket3.y := 90; - rocket3.frameTime := 5; - rocket3.frameLeft := rocket3.frameTime; - rocket3.curFrame := 2; - rocket3.xdelta := 3; - rocket3.ydelta := -1; - rocket3.moveTime := 1; - rocket3.moveLeft := rocket3.moveTime; + rocket.xdelta := 2; + rocket.ydelta := -1; while not ConAvail do begin - lastX := stickMan.x; - lastY := stickMan.y; + oldX := stickMan.x; + oldY := stickMan.y; - rlastX := rocket.x; - rlastY := rocket.y; + roldX := rocket.x; + roldY := rocket.y; - r2lastX := rocket2.x; - r2lastY := rocket2.y; - - r3lastX := rocket3.x; - r3lastY := rocket3.y; - - PutSprite(rlastX, rlastY, rocket.frame[rocket.curFrame]); - PutSprite(r2lastX, r2lastY, rocket2.frame[rocket2.curFrame]); - PutSprite(r3lastX, r3lastY, rocket3.frame[rocket3.curFrame]); - PutSprite(lastX, lastY, stickMan.frame[stickMan.curFrame]); + PutSprite(roldX, roldY, rocket.frame[rocket.curFrame]); + PutSprite(oldX, oldY, stickMan.frame[stickMan.curFrame]); animateSprite(rocket); - animateSprite(rocket2); - animateSprite(rocket3); animateSprite(stickMan); - Delay(10); + {Delay(1);} WaitVSync; - UndrawSprite(lastX, lastY, pic.pixeldata); - UndrawSprite(rlastX, rlastY, pic.pixeldata); - UndrawSprite(r2lastX, r2lastY, pic.pixeldata); - UndrawSprite(r3lastX, r3lastY, pic.pixeldata); + UndrawSprite(oldX, oldY, pic.pixeldata); + UndrawSprite(roldX, roldY, pic.pixeldata); end; end; begin - loadPic('background.pict', pic); + filename := 'background.pict'; + open(infile, filename, ModeReadonly); + read(infile, pic); + close(infile); + + writeln('magic: ', pic.magic, ' mode:', pic.mode); + loadPalette(pic); showPic(pic); @@ -229,14 +160,5 @@ begin loadSpriteFrame(rocket, 3, infile, 3); close(infile); - rocket2 := rocket; - rocket3 := rocket; - - buf := readAudioFile('footsteps.tdrau'); - SampleQStart(buf, true, 16000); - animLoop; - - SampleQStop; - dispose(buf); end. diff --git a/examples/background.pict b/examples/background.pict index b945347..55e7a2c 100644 Binary files a/examples/background.pict and b/examples/background.pict differ diff --git a/examples/default-palette.pal b/examples/default-palette.pal deleted file mode 100644 index d41cbbe..0000000 --- a/examples/default-palette.pal +++ /dev/null @@ -1,19 +0,0 @@ -JASC-PAL -0100 -16 -0 0 0 -255 255 255 -255 0 0 -0 255 0 -0 0 255 -0 255 255 -255 0 255 -255 255 0 -127 127 127 -160 160 160 -127 0 0 -0 127 0 -0 0 127 -0 127 127 -127 0 127 -127 127 0 diff --git a/examples/graphbench.pas b/examples/graphbench.pas index 32f4627..9abbfba 100644 --- a/examples/graphbench.pas +++ b/examples/graphbench.pas @@ -106,7 +106,7 @@ begin end; begin - readSpriteData('sprite-testcard.sprt'); + readSpriteData('rocket.sprt'); InitGraphics; startBench('points 200K'); diff --git a/examples/rocket.sprt b/examples/rocket.sprt index 6ebbdfc..3108b4a 100644 Binary files a/examples/rocket.sprt and b/examples/rocket.sprt differ diff --git a/examples/sprite-testcard.sprt b/examples/sprite-testcard.sprt deleted file mode 100644 index e31fc9e..0000000 Binary files a/examples/sprite-testcard.sprt and /dev/null differ diff --git a/examples/sprites.s b/examples/sprites.s index 01e2616..5f50081 100644 --- a/examples/sprites.s +++ b/examples/sprites.s @@ -53,9 +53,9 @@ CALC_VMEM_ADDR: .EQU PS_SPILL 24 .EQU PS_STRIPE_C 28 .EQU PS_BPSAVE 32 - .EQU PS_FS_ 36 + .EQU PS_FS 36 PUTSPRITE: - FPADJ -PS_FS_ + FPADJ -PS_FS STORE PS_SPRITE_DATA STORE PS_Y STORE PS_X @@ -175,7 +175,7 @@ PS_L_XT: LOAD PS_BPSAVE STOREREG BP - FPADJ PS_FS_ + FPADJ PS_FS RET ; undraw a sprite, i.e. draw background data diff --git a/examples/walking.sprt b/examples/walking.sprt index a4411d4..2cdd0ce 100644 Binary files a/examples/walking.sprt and b/examples/walking.sprt differ diff --git a/lib/corelib.s b/lib/corelib.s index 998cc8c..1ac12e9 100644 --- a/lib/corelib.s +++ b/lib/corelib.s @@ -977,7 +977,7 @@ SETPALETTE: DEFAULT_PALETTE: .WORD 0, $FFF, $F00, $0F0, $00F, $0FF, $F0F, $FF0 - .WORD $777, $AAA, $700, $070, $007, $077, $707, $770 + .WORD $777, $777, $700, $070, $007, $077, $707, $770 ; set whole video memory to zero CLEARGRAPHICS: diff --git a/lib/pcmaudio.inc b/lib/pcmaudio.inc index bda29a9..dc1dbba 100644 --- a/lib/pcmaudio.inc +++ b/lib/pcmaudio.inc @@ -1,7 +1,6 @@ type SndBuf = string[32768]; type SndBufPtr = ^SndBuf; -procedure ReadSample(aFile:file;buf:SndBufPtr); external; procedure PlaySample(buf:SndBufPtr;sampleRate:integer); external; procedure SampleQStart(buf:SndBufPtr;loop:boolean;sampleRate:integer); external; procedure SampleQStop; external; diff --git a/lib/pcmaudio.s b/lib/pcmaudio.s index 1c3fecf..ebe812a 100644 --- a/lib/pcmaudio.s +++ b/lib/pcmaudio.s @@ -302,22 +302,3 @@ SMPLQ_I_XT2: DROP LOADREG IR ; jump via interrupt return register JUMP - -; args: file ptr, ptr to SndBuf (i.e. a String) -READSAMPLE: - ; buf ptr + 0: addr of cur size header field - ; buf ptr + 4: addr of max size header field - ; buf ptr + 8: start of raw data - - ; copy max size to current size header field of SndBuf - INC.S1.X2Y 4 ; [ file ptr, buf ptr, buf ptr+4 ] - LOADI ; [ file ptr, buf ptr, max size ] - STOREI 8 ; [ file ptr, buf ptr+8 ] - ; put max size back on ToS - DUP ; [ file ptr, buf ptr+8, buf ptr+8] - DEC 4 ; [ file ptr, buf ptr+8, buf ptr+4] - LOADI ; [ file ptr, buf ptr+8, max size ] - - LOADCP READFS - CALL - RET diff --git a/lib/runtime.s b/lib/runtime.s index c90854d..9eb35d7 100644 --- a/lib/runtime.s +++ b/lib/runtime.s @@ -1792,38 +1792,6 @@ MAX_XT: FPADJ 4 RET -; find largest free chunk on heap -; args: none -; returns: size of largest free chunk in bytes -MAXAVAIL: - FPADJ -4 - LOADC 0 - STORE 0 ; start with zero as result - - LOADCP _HEAP_ANCHOR -MXAV_L: - DUP ; dup chunk ptr for later - INC 4 ; move to size field - LOADI ; load chunk size - LOAD 0 ; compare with current result value - CMPU.S0 LE ; compare with keeping first arg on stack - CBRANCH MXAV_NEXT ; if smaller or equal, no change - STORE 0 ; else store as new value - BRANCH MXAV_NEXT2 -MXAV_NEXT: - DROP -MXAV_NEXT2: - LOADI ; load next ptr - DUP - LOADCP _HEAP_ANCHOR ; compare with anchor - CMPU NE - CBRANCH MXAV_L ; if not equal, loop -MXAV_XT: - DROP ; drop chunk ptr - LOAD 0 ; put result value on stack - FPADJ 4 - RET - ; check if a pointer is part of the free list ; args: pointer returned by MEM_ALLOC ; throws runtime error if the pointer is found diff --git a/lib/stdlib.inc b/lib/stdlib.inc index d6531a9..5304403 100644 --- a/lib/stdlib.inc +++ b/lib/stdlib.inc @@ -150,7 +150,6 @@ procedure strmoveup(var s:string;index,length,delta:integer); external; procedure strmovedown(var s:string;index,length,delta:integer); external; procedure RuntimeError(var s:string); external; function MemAvail:integer; external; -function MaxAvail:integer; external; (* from stdlib *) function copy(s:string[256];index,count:integer):string[256]; external; diff --git a/tests/testmem.pas b/tests/testmem.pas deleted file mode 100644 index d449161..0000000 --- a/tests/testmem.pas +++ /dev/null @@ -1,18 +0,0 @@ -program testmem; -var s1:^string[2048]; - s2:^string[2048]; -begin - writeln(MemAvail); - writeln(MaxAvail); - - writeln('new s1 and s2'); - new(s1); - new(s2); - writeln(MemAvail); - writeln(MaxAvail); - - writeln('dispose s1'); - dispose(s1); - writeln(MemAvail); - writeln(MaxAvail); -end. diff --git a/tridoraemu/cpu.go b/tridoraemu/cpu.go index f1ae4de..9d6b08d 100644 --- a/tridoraemu/cpu.go +++ b/tridoraemu/cpu.go @@ -249,7 +249,6 @@ func (c *CPU) step() error { var name string if (insWord & 1) == 1 { name = "STORE.B" - operand &= ^1 ea = c.BP + word(operand) } else { name = "STORE" diff --git a/tridoraemu/framebuffer.go b/tridoraemu/framebuffer.go index 71776ca..189100a 100644 --- a/tridoraemu/framebuffer.go +++ b/tridoraemu/framebuffer.go @@ -10,16 +10,11 @@ import ( const VmemWords = 32768 const PaletteSlots = 16 const FB_RA = 0 -const FB_WA = 4 -const FB_IO = 8 -const FB_PS = 12 -const FB_PD = 16 -const FB_CTL= 20 -const FB_SHIFTER = 24 -const FB_SHIFTCOUNT = 28 -const FB_SHIFTERM = 32 -const FB_SHIFTERSP = 36 -const FB_MASKGEN = 40 +const FB_WA = 1 +const FB_IO = 2 +const FB_PS = 3 +const FB_PD = 4 +const FB_CTL= 5 const PixelMask = 0b11110000000000000000000000000000 const PixelPerWord = 8 @@ -38,9 +33,6 @@ type Framebuffer struct { vmem [VmemWords]word readCount int paletteChanged bool - shiftAssistData word - shiftAssistCount int - maskGenData word } func (f *Framebuffer) initialize() { @@ -61,11 +53,6 @@ func (f *Framebuffer) read(byteaddr word) (word, error) { case FB_PS: result = f.paletteSlot case FB_PD: result = f.readPalette() case FB_CTL: result = f.readCtl() - case FB_SHIFTER: result = f.readShiftAssist() - case FB_SHIFTCOUNT: result = 0xFFFFFFF - case FB_SHIFTERM: result = f.readShifterM() - case FB_SHIFTERSP: result = f.readShifterSp() - case FB_MASKGEN: result = f.readMaskGen() default: } return result, nil @@ -80,11 +67,6 @@ func (f *Framebuffer) write(value word, byteaddr word) (error) { case FB_PS: f.paletteSlot = value case FB_PD: f.writePalette(value) case FB_CTL: f.writeCtl(value) - case FB_SHIFTER: f.writeShiftAssist(value) - case FB_SHIFTCOUNT: f.writeShiftCount(value) - case FB_SHIFTERM: - case FB_SHIFTERSP: - case FB_MASKGEN: f.writeMaskGen(value) default: } @@ -170,47 +152,3 @@ func (f *Framebuffer) readCtl() word { func (f *Framebuffer) writeCtl(value word) { } - -func (f *Framebuffer) writeShiftAssist(value word) { - f.shiftAssistData = value - f.shiftAssistCount = 0 -} - -func (f *Framebuffer) readShiftAssist() word { - return f.shiftAssistData >> (f.shiftAssistCount * 4) -} - -func (f *Framebuffer) writeShiftCount(value word) { - f.shiftAssistCount = int(value & 0x7) -} - -func (f *Framebuffer) readShifterM() word { - return convertToMask(f.readShiftAssist()) -} - -func pixelToMask(pixels word, mask word) word { - if (pixels & mask) != 0 { return mask } else { return 0 } -} - -func convertToMask(pixels word) word { - return pixelToMask(pixels, 0xF0000000) | - pixelToMask(pixels, 0x0F000000) | - pixelToMask(pixels, 0x00F00000) | - pixelToMask(pixels, 0x000F0000) | - pixelToMask(pixels, 0x0000F000) | - pixelToMask(pixels, 0x00000F00) | - pixelToMask(pixels, 0x000000F0) | - pixelToMask(pixels, 0x0000000F) -} - -func (f *Framebuffer) readShifterSp() word { - return word(f.shiftAssistData << ((8-f.shiftAssistCount)*4)) -} - -func (f *Framebuffer) writeMaskGen(value word) { - f.maskGenData = value -} - -func (f *Framebuffer) readMaskGen() word { - return convertToMask(f.maskGenData) -} diff --git a/utils/tdrimg.py b/utils/tdrimg.py index c03e59b..4eeaead 100644 --- a/utils/tdrimg.py +++ b/utils/tdrimg.py @@ -620,9 +620,6 @@ def create_image_with_stuff(imgfile): slotnr = putfile("../examples/background.pict", None , f, part, partstart, slotnr) slotnr = putfile("../examples/walking.sprt", None , f, part, partstart, slotnr) slotnr = putfile("../examples/rocket.sprt", None , f, part, partstart, slotnr) - slotnr = putfile("../examples/sprite-testcard.sprt", None , f, part, partstart, slotnr) - slotnr = putfile("../examples/tiles.inc", None , f, part, partstart, slotnr) - slotnr = putfile("../examples/tiles.s", None , f, part, partstart, slotnr) listdir(f, part)