summaryrefslogtreecommitdiff
path: root/tests/tst-context.c
diff options
context:
space:
mode:
authorkx <kx@radix-linux.su>2026-10-09 18:00:15 +0300
committerkx <kx@radix-linux.su>2026-10-09 18:00:15 +0300
commit065da3509019b15dd0e678072e6be629e5330bef (patch)
tree69c934c9e786ac048b4fbe8f4c4c5571661521f4 /tests/tst-context.c
parentd130fe27fa753be02ed76fd9b277aa3c3d928eb9 (diff)
downloadlibmcpu-0.4.0.tar.xz
Version 0.4.00.4.0
Diffstat (limited to 'tests/tst-context.c')
-rw-r--r--tests/tst-context.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/tests/tst-context.c b/tests/tst-context.c
new file mode 100644
index 0000000..6384d75
--- /dev/null
+++ b/tests/tst-context.c
@@ -0,0 +1,121 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <libmcpu.h>
+
+
+static int failures = 0;
+
+#define CHECK(cond,msg) \
+ do { \
+ if( !(cond) ) \
+ { \
+ fprintf( stderr, "FAIL: %s\n", (msg) ); \
+ ++failures; \
+ } \
+ } while( 0 )
+
+
+int
+main( void )
+{
+ __mpu_uint32_t psw;
+
+ __cpu_init();
+
+ CHECK( __cpu_pc == 0, "PC after __cpu_init()" );
+ CHECK( __cpu_sp == 0, "SP after __cpu_init()" );
+ CHECK( __cpu_fp == 0, "FP after __cpu_init()" );
+ CHECK( __cpu_get_psw() == 0, "PSW after __cpu_init()" );
+
+ /* Verify access to the complete 512 KiB register file. */
+ __cpu_registers[0] = 0x5a;
+ __cpu_registers[CPU_REGISTERS_MEM_SIZE_IN_UNITS - 1] = 0xa5;
+ CHECK( __cpu_registers[0] == 0x5a, "register file first byte" );
+ CHECK( __cpu_registers[CPU_REGISTERS_MEM_SIZE_IN_UNITS - 1] == 0xa5,
+ "register file last byte" );
+
+ /* Low PSW bits are maintained by LibMPU. */
+ __mpu_stc();
+ __mpu_stz();
+ __mpu_stinx();
+
+ psw = __cpu_get_psw();
+ CHECK( (psw & PSW_CF_MASK) != 0, "PSW reads LibMPU CF" );
+ CHECK( (psw & PSW_ZF_MASK) != 0, "PSW reads LibMPU ZF" );
+ CHECK( (psw & PSW_INXF_MASK) != 0, "PSW reads LibMPU INXF" );
+
+ /* High PSW bits belong to LibCPU. */
+ __cpu_sth();
+ __cpu_stt();
+ __cpu_sti();
+ CHECK( __cpu_stmode( 2 ) == 0, "set CPU MODE" );
+
+ psw = __cpu_get_psw();
+ CHECK( (psw & PSW_HF_MASK) != 0, "PSW HF" );
+ CHECK( (psw & PSW_TF_MASK) != 0, "PSW TF" );
+ CHECK( (psw & PSW_IF_MASK) != 0, "PSW IF" );
+ CHECK( __cpu_gtmode() == 2, "PSW MODE" );
+
+ /* CPU flag operations do not alter the LibMPU half of PSW. */
+ __cpu_clh();
+ __cpu_cmt();
+ __cpu_cmi();
+
+ psw = __cpu_get_psw();
+ CHECK( (psw & PSW_HF_MASK) == 0, "clear HF" );
+ CHECK( (psw & PSW_TF_MASK) == 0, "complement TF" );
+ CHECK( (psw & PSW_IF_MASK) == 0, "complement IF" );
+ CHECK( (psw & PSW_CF_MASK) != 0, "CF preserved by CPU flags" );
+ CHECK( (psw & PSW_ZF_MASK) != 0, "ZF preserved by CPU flags" );
+ CHECK( (psw & PSW_INXF_MASK) != 0, "INXF preserved by CPU flags" );
+
+ /* Store/restore the complete logical PSW. */
+ __cpu_set_psw( PSW_AF_MASK | PSW_OF_MASK | PSW_DOMF_MASK |
+ PSW_HF_MASK | PSW_IF_MASK |
+ ((__mpu_uint32_t)3 << PSW_MODE_SHIFT) );
+
+ psw = __cpu_get_psw();
+ CHECK( psw == (PSW_AF_MASK | PSW_OF_MASK | PSW_DOMF_MASK |
+ PSW_HF_MASK | PSW_IF_MASK |
+ ((__mpu_uint32_t)3 << PSW_MODE_SHIFT)),
+ "complete PSW store/restore" );
+ CHECK( __mpu_gta() == 1, "LibMPU AF after __cpu_set_psw()" );
+ CHECK( __mpu_gto() == 1, "LibMPU OF after __cpu_set_psw()" );
+ CHECK( __mpu_gtdom() == 1, "LibMPU DOMF after __cpu_set_psw()" );
+ CHECK( __mpu_gtc() == 0, "LibMPU CF cleared by __cpu_set_psw()" );
+ CHECK( __cpu_gth() == 1, "LibCPU HF after __cpu_set_psw()" );
+ CHECK( __cpu_gti() == 1, "LibCPU IF after __cpu_set_psw()" );
+ CHECK( __cpu_gtmode() == 3, "LibCPU MODE after __cpu_set_psw()" );
+
+ __cpu_clear_psw();
+ CHECK( __cpu_get_psw() == 0, "clear complete PSW" );
+
+ __cpu_pc = 0x123456789abcdef0ULL;
+ __cpu_sp = 0x0fedcba987654321ULL;
+ __cpu_fp = 0x0123456789abcdefULL;
+ CHECK( __cpu_pc == 0x123456789abcdef0ULL, "PC access" );
+ CHECK( __cpu_sp == 0x0fedcba987654321ULL, "SP access" );
+ CHECK( __cpu_fp == 0x0123456789abcdefULL, "FP access" );
+
+ __cpu_free_context();
+ CHECK( __cpu_pc == 0, "PC after __cpu_free_context()" );
+ CHECK( __cpu_sp == 0, "SP after __cpu_free_context()" );
+ CHECK( __cpu_fp == 0, "FP after __cpu_free_context()" );
+ CHECK( __cpu_get_psw() == 0, "PSW after __cpu_free_context()" );
+
+ if( failures != 0 )
+ {
+ fprintf( stderr, "libcpu context regression: %d failure(s)\n", failures );
+ return( 1 );
+ }
+
+ printf( "libcpu context/PSW regression: PASS\n" );
+ printf( "register file: %u bytes\n", CPU_REGISTERS_MEM_SIZE_IN_UNITS );
+ printf( "PSW: LibMPU bits 0..15, LibCPU bits 16..20\n" );
+
+ return( 0 );
+}