revamped pixel output draft
This commit is contained in:
@@ -35,13 +35,13 @@ Unlike Uxn/Varvara or Uxn/SPARTA, Uxn/ESOP only exposes the control block ports
|
||||
In Uxntal, the ESOP's control block would be described as follows:
|
||||
|
||||
```
|
||||
|00 @Control [ &framevec $2 &input $2 &random $1 &status $1 &sound $1 &syscall $1 ]
|
||||
|00 @Control [ &framevec $2 &io $2 &random $1 &status $1 &sound $1 &syscall $1 ]
|
||||
```
|
||||
|
||||
The fields of the control block are:
|
||||
|
||||
- Frame vector (`00-01`) - the port to set the vector to be run on each frame (60 frames per second);
|
||||
- Input (`02-03`) - the port to read input status bits of every key on the keypad;
|
||||
- Input/output (`02-03`) - the port to read input status bits of every key on the keypad and to output pixels at given coordinates;
|
||||
- Random/debug port (`04`) - the port to trace debug information on output and retrieve a random byte value on input;
|
||||
- Status port (`05`) - the port to get the information on battery and get/set screen brightness level;
|
||||
- Sound port (`06`) - the port to perform mono audio beeper operations;
|
||||
@@ -51,15 +51,17 @@ Implementation note: direct writing to or reading from the control block memory
|
||||
|
||||
## Screen output
|
||||
|
||||
All the 4032 pixels of 84x48 screen are allocated in the 504-byte video memory of ESOP (`#fe00-#fff7`) in the left-to-right, top-to-bottom, high-to-low order. To output a pixel at the given coordinates, the app must calculate the appropriate byte position itself.
|
||||
All the 4032 pixels of 84x48 screen are allocated in the 504-byte video memory of ESOP (`#fe00-#fff7`) in the left-to-right, top-to-bottom, high-to-low order. To output a pixel at the given coordinates using memory manipulation routines, the app must calculate the appropriate byte position itself. This process is made easier by reusing I/O port `02-03` with the `DEO2` instruction where you can directly pass X and Y coordinates of the pixel.
|
||||
|
||||
The actual screen contents get updated 60 times per second according to the video memory. Before this process, the frame vector is run, if set in the corresponding control port (`00-01`). All graphics operations must be performed within this frame vector.
|
||||
|
||||
Due to shared nature of the I/O device port, the handler responsible for pixel output in the ESOP implementaion must preserve the input state between port write calls, i.e. save it before the processing and restore afterwards.
|
||||
|
||||
Standard input/output ports are not supported.
|
||||
|
||||
## Keypad input
|
||||
|
||||
The 16 bits of the input ports (`02` and `03`) have the following mapping:
|
||||
When in input mode, the 16 bits of the input ports (`02` and `03`) have the following mapping:
|
||||
|
||||
Bit|15 |14 |13|12|11|10|9|8|7|6|5|4|3|2|1|0
|
||||
---|---|---|--|--|--|--|-|-|-|-|-|-|-|-|-|-
|
||||
|
||||
+5
-18
@@ -1,6 +1,6 @@
|
||||
( ESOP stdlib )
|
||||
|
||||
|00 @Control [ &framevec $2 &input $2 &random $1 &status $1 &sound $1 &syscall $1 ]
|
||||
|00 @Control [ &framevec $2 &io $2 &random $1 &status $1 &sound $1 &syscall $1 ]
|
||||
|
||||
( byte to short )
|
||||
( x -- 00 x )
|
||||
@@ -12,36 +12,23 @@
|
||||
%RND { .Control/random DEI }
|
||||
%STACKTRACE { #ff .Control/random DEO }
|
||||
%SYS { .Control/syscall DEO }
|
||||
%INKEY { .Control/input DEI2 }
|
||||
%INKEY { .Control/io DEI2 }
|
||||
%PXL { .Control/io DEO2 }
|
||||
%DBG { #20 SYS SYS }
|
||||
%SND { .Control/sound DEO }
|
||||
|
||||
( x y -- ref* )
|
||||
%COORD { BTS ROT BTS SWP2 #0054 MUL2 ADD2 }
|
||||
( x y -- bitshift byteptr* )
|
||||
%PXLOFFSET { COORD DUP2 #03 SFT2 DUP2 #30 SFT2 ROT2 SWP2 SUB2 SWP POP ROT #fe00 ADD2 }
|
||||
|
||||
( x y -- )
|
||||
%PXL { PXLOFFSET DUP2 LDA #01 ROT #40 SFT SFT ORA ROT ROT STA }
|
||||
|
||||
( subtract #20 from the ASCII code and you get the offset from the nanofont label )
|
||||
%CHAR-TO-NF { #20 SUB ;nanofont ADD }
|
||||
|
||||
|0100
|
||||
#03 #02 #01
|
||||
ROT
|
||||
DBG DBG DBG
|
||||
;on-frame SETSCRVEC
|
||||
#30
|
||||
#10 #12
|
||||
BRK
|
||||
|
||||
@on-frame
|
||||
DUP SND
|
||||
INC
|
||||
( #10 #12 PXL )
|
||||
DUP2 INC PXL
|
||||
BRK
|
||||
|
||||
|
||||
@putc
|
||||
|
||||
JMP2r
|
||||
|
||||
+18
-1
@@ -39,8 +39,25 @@ function ESOPExtensions() {
|
||||
height = 48,
|
||||
vramOffset = vm.videoMemOffset,
|
||||
vramSize = vm.videoMemSize,
|
||||
ctx = cnv.getContext('2d', {alpha: false})
|
||||
ctx = cnv.getContext('2d', {alpha: false}),
|
||||
xval = null, yval = null
|
||||
ctx.globalAlpha = 1
|
||||
//setup pixel drawing ports
|
||||
function pixelHook(port, coord, prev) {
|
||||
if(port === 2) xval = coord
|
||||
else if(port === 3) yval = coord
|
||||
if(xval !== null && yval !== null) { //both coordinates set, update the pixel
|
||||
var pxlOffset = yval * width + xval,
|
||||
byteOffset = pxlOffset >>> 3,
|
||||
bitOffset = 7 - pxlOffset + (byteOffset << 3),
|
||||
vramvalue = vm.getram(vramOffset + byteOffset, 1)[0]
|
||||
vm.setram(vramOffset + byteOffset, vramvalue | (1<<bitOffset))
|
||||
xval = yval = null
|
||||
}
|
||||
vm.setdev(port, prev) //preserve the input value
|
||||
}
|
||||
vm.setWriteHook(2, pixelHook) //X
|
||||
vm.setWriteHook(3, pixelHook) //Y
|
||||
//setup screen renderer
|
||||
function renderScreen() {
|
||||
var vram = vm.getram(vramOffset, vramSize),
|
||||
|
||||
Reference in New Issue
Block a user