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:
|
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:
|
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);
|
- 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;
|
- 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;
|
- 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;
|
- 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
|
## 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.
|
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.
|
Standard input/output ports are not supported.
|
||||||
|
|
||||||
## Keypad input
|
## 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
|
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 )
|
( 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 )
|
( byte to short )
|
||||||
( x -- 00 x )
|
( x -- 00 x )
|
||||||
@@ -12,36 +12,23 @@
|
|||||||
%RND { .Control/random DEI }
|
%RND { .Control/random DEI }
|
||||||
%STACKTRACE { #ff .Control/random DEO }
|
%STACKTRACE { #ff .Control/random DEO }
|
||||||
%SYS { .Control/syscall DEO }
|
%SYS { .Control/syscall DEO }
|
||||||
%INKEY { .Control/input DEI2 }
|
%INKEY { .Control/io DEI2 }
|
||||||
|
%PXL { .Control/io DEO2 }
|
||||||
%DBG { #20 SYS SYS }
|
%DBG { #20 SYS SYS }
|
||||||
%SND { .Control/sound DEO }
|
%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 )
|
( subtract #20 from the ASCII code and you get the offset from the nanofont label )
|
||||||
%CHAR-TO-NF { #20 SUB ;nanofont ADD }
|
%CHAR-TO-NF { #20 SUB ;nanofont ADD }
|
||||||
|
|
||||||
|0100
|
|0100
|
||||||
#03 #02 #01
|
|
||||||
ROT
|
|
||||||
DBG DBG DBG
|
|
||||||
;on-frame SETSCRVEC
|
;on-frame SETSCRVEC
|
||||||
#30
|
#10 #12
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
@on-frame
|
@on-frame
|
||||||
DUP SND
|
DUP2 INC PXL
|
||||||
INC
|
|
||||||
( #10 #12 PXL )
|
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
|
|
||||||
@putc
|
@putc
|
||||||
|
|
||||||
JMP2r
|
JMP2r
|
||||||
|
|||||||
+18
-1
@@ -39,8 +39,25 @@ function ESOPExtensions() {
|
|||||||
height = 48,
|
height = 48,
|
||||||
vramOffset = vm.videoMemOffset,
|
vramOffset = vm.videoMemOffset,
|
||||||
vramSize = vm.videoMemSize,
|
vramSize = vm.videoMemSize,
|
||||||
ctx = cnv.getContext('2d', {alpha: false})
|
ctx = cnv.getContext('2d', {alpha: false}),
|
||||||
|
xval = null, yval = null
|
||||||
ctx.globalAlpha = 1
|
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
|
//setup screen renderer
|
||||||
function renderScreen() {
|
function renderScreen() {
|
||||||
var vram = vm.getram(vramOffset, vramSize),
|
var vram = vm.getram(vramOffset, vramSize),
|
||||||
|
|||||||
Reference in New Issue
Block a user