PTSL

From Esolang
Jump to navigation Jump to search

PTSL or Portable Terse Stack Language is a language designed by User:Moon for use in a simulated universe/tabletop game/community written world. It is intended as a mechanism for storing programs on cartridges designed to run on multiple systems. Due to its nature as a terse language, it's also rather esoteric, hence it being documented on this wiki.

Execution enviornment

PTSL executes in a flat memory space of up to 224 bytes (16MiB), divided in 8KB pages. Any memory beyond this space is treated as Memory Mapped IO space, for direct access to system devices when the program supports it. There can be up to 254 MMIO devices mapped, with MMIO device 0 being RAM and MMIO device 1 being the first 64KB of cartridge.

0 RAM
1 CART[0]
2 MMIO[0]
3-254 MMIO[1-253]
255 MMIO[254]

Program execution can begin in either RAM (Bank 0) or CART[0] (Bank 1), MMIO devices are not executable unless they are mapped as a storage device, like extra RAM or extra cartridge space.

Not all of RAM is immediately accessable, and has to be requested in 64KB pages by the program before use.

The stack is located in the first page of RAM, with values on the stack being exactly 32 bits.

Instructions

Each opcode is 8 bits long, with up to 32 bits of data associated with it.

PTSL instruction table
ID Opcode Definition
00 DROP SP--
01 DUP [SP++] = [SP]
02 SWAP swap [SP-1] [SP]
03 PUSHI32 data [SP++] = [DATA:32]
04 PUSHI24 data [SP++] = [DATA:24]
05 PUSHI16 data [SP++] = [DATA:16]
06 PUSHI8 data [SP++] = [DATA:8]
07 LOADI32 [SP] = MEM[[SP]:32]
08 LOADI24 [SP] = MEM[[SP]:24]
09 LOADI16 [SP] = MEM[[SP]:16]
0A LOADI8 [SP] = MEM[[SP]:8]
0B JUMP PC = [SP--]
0C JPIF IF [SP--] { PC = [SP--] }
0D ADDI8 [SP] = [SP] + [DATA:8]
0E ADD [SP--] = [SP-1] + [SP-2]
0F ADC
10 SUBVI8 [SP--] = [SP-1] - [DATA:8]
11 SUBI8V [SP--] = [DATA:8] - [SP-1]
12 SUB [SP--] = [SP-1] - [SP-2]
13 SBB
14 8BCRRY
15 16BCRRY
16 32BCRRY
17 CALLI32 [RSP++] = PC; PC = [DATA:I32]
18 CALL [RSP++] = PC; PC = [SP--]
19 PUSHRS [RSP++] = [SP--]
1A PEEKRS [SP++] = [RSP]
1B POPRS [SP++] = [RSP--]
1C PUSHRSP [SP++] = RSP
1D POPRSP RSP = [SP--]
1E ALLOCP Request memory page from OS
1F MAPDEV Map device [SP-1] to page [SP-2].
20 COPY Fast copy, provided by OS. [SP-1] = Length, [SP-2] = Source, [SP-3] = Dest
21 JPRELI8 PC = PC + [SDATA:8]
22 JPRELI16 PC = PC + [SDATA:16]
23 JPREL PC = PC + [SP--]
24 RET PC = [RSP--]
25 GREQ [SP--] = [SP-1] >= [SP-2] (Signed)
26 LEEQ [SP--] = [SP-1] <= [SP-2] (Signed)
27 GRTR [SP--] = [SP-1] > [SP-2] (Signed)
28 LESS [SP--] = [SP-1] < [SP-2] (Signed)
29 ABEQ [SP--] = [SP-1] >= [SP-2] (Unsigned)
2A BLEQ [SP--] = [SP-1] <= [SP-2] (Unsigned)
2B ABOV [SP--] = [SP-1] > [SP-2] (Unsigned)
2C BELO [SP--] = [SP-1] < [SP-2] (Unsigned)
2D STORI32 MEM[[SP]:32] = [SP--]
2E STORI24 MEM[[SP]:24] = [SP--]
2F STORI16 MEM[[SP]:16] = [SP--]
30 STORI8 MEM[[SP]:8] = [SP--]
31 NOT [SP] = ![SP]
32 AND [SP--] = [SP-1] & [SP-2]
33 OR [SP-2]
34 XOR [SP--] = [SP-1] ^ [SP-2]
35 MUL [SP--] = [SP-1] * [SP-2]
36 DIVMOD A = [SP-1] / [SP-2]; [SP-1] = [SP-1] % [SP-2]; [SP] = A
37 SHL [SP--] = [SP-1] << [SP-2]
38 SHR [SP--] = [SP-1] >> [SP-2]
39 SHRA [SP--] = [SP-1] >>> [SP-2]
3A SHL8 [SP] = [SP] << 8
3B SHL16 [SP] = [SP] << 16
3C SHL24 [SP] = [SP] << 24
3D PUSH1 [SP++] = 1
3E SETQC [QUICKCONST] = [DATA:32]
3F GETQC32 [SP++] = [QUICKCONST:32]
40 GETQC16 [SP++] = [QUICKCONST:16]
41 GETQC8 [SP++] = [QUICKCONST:8]
42 MXCHG swap [SP-1] MEM[[SP--]:32]
43 SETSP SP = [SP]
44 SYSINF Writes system info to address pointed to by [SP--]. Must be a 256 byte space.
45 PUSH0 [SP++] = 0
46 BITSET
47 BITGET
48 BITFLIP
49 JMPTOASM Execute system specific assembly code at location pointed to by [SP--]
4A CALLASM Same as JMPTOASM, but provides a return value in a system dependent register.
4B MSET32 Set the region specified by [SP-1] of length [SP-2] to [SP-3:32]. Undefined behavior if region length is not multiple of 4
4C MSET16 Set the region specified by [SP-1] of length [SP-2] to [SP-3:16]. Undefined behavior if region length is not multiple of 2
4D MSET8 Set the region specified by [SP-1] of length [SP-2] to [SP-3:8].
4E SHL1 [SP] = [SP] << 1
4F SHR1 [SP] = [SP] >> 1
50 SHLI8 [SP] = [SP] << [DATA:8]
51 SHRI8 [SP] = [SP] >> [DATA:8]
52 OVER [SP++] = [SP-1]
53 ROT rotate [SP], [SP-1], [SP-2]
FF EXPLD System prints "BANG!" to display, halts. May also play noise from system speaker if one is present.

Example code

The following is written in the human readable PTSLASM format, instead of PTSL directly.

Hello, World!

 ; Assumes that it is running on a MX08-A. Not a good example of portable code :)
 %DEF TERMINAL_DEVICE_ID 0xFF000001 ; MX08-A terminal
 %DEF MMIO0 0x02000000
 %DEF STR_HELLO_WORLD_LEN 13
 [ORG 0x000000]
 _START:
   PUSHI24 0x001000
   PUSHRSP ; Set up return stack. Not used in this demo, but worth setting up.
   PUSHI8 2
   PUSHI32 TERMINAL_DEVICE_ID
   MAPDEV
   PUSHI8 STR_HELLO_WORLD_LEN
   PUSHI24 STR_HELLO_WORLD
   PUSHI32 MMIO0
   COPY
 .HANG: JUMPRELI8 0x00
 
 STR_HELLO_WORLD: DB "Hello, World!"