diff options
| author | kx <kx@radix-linux.su> | 2026-10-09 18:00:15 +0300 |
|---|---|---|
| committer | kx <kx@radix-linux.su> | 2026-10-09 18:00:15 +0300 |
| commit | 065da3509019b15dd0e678072e6be629e5330bef (patch) | |
| tree | 69c934c9e786ac048b4fbe8f4c4c5571661521f4 /tests/tst-context.c | |
| parent | d130fe27fa753be02ed76fd9b277aa3c3d928eb9 (diff) | |
| download | libmcpu-0.4.0.tar.xz | |
Version 0.4.00.4.0
Diffstat (limited to 'tests/tst-context.c')
| -rw-r--r-- | tests/tst-context.c | 121 |
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 ); +} |
