mirror of
https://github.com/wfjm/w11.git
synced 2026-03-09 04:30:39 +00:00
tools/tests: add stktst program [skip ci]
This commit is contained in:
@@ -3,3 +3,4 @@ This directory tree contains **test programs** and is organized in
|
||||
| Directory | Content |
|
||||
| --------- | ------- |
|
||||
| [divtst](divtst) | `divtst` program: test DIV instruction response |
|
||||
| [stktst](stktst) | `stktst` program: test 2.11BSD stack extension |
|
||||
|
||||
12
tools/tests/stktst/Makefile
Normal file
12
tools/tests/stktst/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
# $Id: $
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
# Copyright 2022- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
#
|
||||
stktst : stktst.o dotst.o
|
||||
cc -o stktst stktst.o dotst.o
|
||||
|
||||
stktst.o : stktst.c
|
||||
cc -O -c stktst.c
|
||||
|
||||
clean :
|
||||
rm -f *.o stktst
|
||||
165
tools/tests/stktst/dotst.s
Normal file
165
tools/tests/stktst/dotst.s
Normal file
@@ -0,0 +1,165 @@
|
||||
/ $Id: $
|
||||
/ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
/ Copyright 2022- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
/
|
||||
/ called from C as
|
||||
/ irc = dotst(idat, odat)
|
||||
/ with
|
||||
/ idat[0] command ('I','i','l','f','d','r','w', or 'h')
|
||||
/ idat[1] command repeat count
|
||||
/ idat[2] -c repeat count
|
||||
/ idat[3] -s repeat count
|
||||
/ idat[4] -o byte offset
|
||||
/ and returns in odat
|
||||
/ odat[0] sp before align and offset
|
||||
/ odat[1] sp after align and offset
|
||||
/ odat[2] sp final
|
||||
/
|
||||
/ Revision History:
|
||||
/ Date Rev Version Comment
|
||||
/ 2022-08-01 1267 1.0 Initial version
|
||||
/
|
||||
|
||||
.globl _dotst
|
||||
.text
|
||||
|
||||
_dotst: mov r2,-(sp) / save r2 (r0,r1 are volatile)
|
||||
mov r3,-(sp) / save r3
|
||||
mov r4,-(sp) / save r4
|
||||
mov r5,-(sp) / save r5
|
||||
/ now (sp) -> saved r5
|
||||
/ 2(sp) -> saved r4
|
||||
/ 4(sp) -> saved r3
|
||||
/ 6(sp) -> saved r2
|
||||
/ 10(sp) -> return address
|
||||
/ 12(sp) -> 1st arg: idat
|
||||
/ 14(sp) -> 2nd arg: odat
|
||||
|
||||
mov 12(sp), r2 / r2 = idat
|
||||
mov 14(sp), r3 / r3 = odat
|
||||
|
||||
mov sp,r5 / save sp
|
||||
mov sp,(r3) / store original sp in odat[0]
|
||||
mov sp,2(r3) / store original sp in odat[1]
|
||||
mov sp,4(r3) / store original sp in odat[2]
|
||||
|
||||
/ handle r,w,h commands first
|
||||
clr r0 / set exit code
|
||||
movb (r2),r1 / command code
|
||||
mov 2(r2),r4 / repeat count used as address
|
||||
|
||||
/ handle 'r': probe read
|
||||
cmpb $'r,r1
|
||||
bne testw
|
||||
mov (r4),r1 / probe read
|
||||
br done
|
||||
|
||||
/ handle 'w': probe read/write
|
||||
testw: cmpb $'w,r1
|
||||
bne testh
|
||||
mov (r4),r1 / probe read
|
||||
mov r1,(r4) / probe re-write
|
||||
br done
|
||||
|
||||
/ handle 'h': probe halt
|
||||
testh: cmpb $'h,r1
|
||||
bne testx
|
||||
halt / success is crash here :)
|
||||
testx:
|
||||
|
||||
/ apply sp aligns and offset. In python pseudo code do
|
||||
/ # segmemt align
|
||||
/ if idat[3] > 0:
|
||||
/ sp &= 017777
|
||||
/ sp -= 8192 * (idat[3]-1)
|
||||
/ # click align
|
||||
/ if idat[2] > 0:
|
||||
/ sp &= 077
|
||||
/ sp -= 64 * (idat[2]-1)
|
||||
/ # byte offset
|
||||
/ sp += idat[4]
|
||||
/
|
||||
mov sp,r4
|
||||
/ handle -s
|
||||
tst 6(r2) / idat[3] -s count > 0 ?
|
||||
beq optc
|
||||
bic $017777,r4 / sp &= 017777
|
||||
mov 6(r2),r1
|
||||
dec r1 / idat[3]-1
|
||||
mul $020000,r1
|
||||
sub r1,r4 / sp -= 8192 * (idat[3]-1)
|
||||
/ handle -c
|
||||
optc: tst 4(r2) / idat[2] -c count > 0 ?
|
||||
beq opto
|
||||
bic $000077,r4 / sp &= 077
|
||||
mov 4(r2),r1
|
||||
dec r1 / idat[2]-1
|
||||
mul $000100,r1
|
||||
sub r1,r4 / sp -= 64 * (idat[2]-1)
|
||||
/ handle -o
|
||||
opto: add 10(r2),r4
|
||||
mov r4,sp
|
||||
mov sp,2(r3) / store aligned+offset sp in odat[1]
|
||||
|
||||
/ prepare command handling
|
||||
clr r0 / set exit code
|
||||
mov (r2),r1 / command code
|
||||
mov 2(r2),r4 / command repeat count
|
||||
beq done / if zero quit
|
||||
|
||||
/ handle 'I': clr -(sp)
|
||||
cmpb $'I,r1
|
||||
bne testi
|
||||
1: clr -(sp)
|
||||
sob r4,1b
|
||||
br done
|
||||
|
||||
/ handle 'i': stcfi f0,-(sp); movfi fr0,-(sp) in BSD
|
||||
testi: cmpb $'i,r1
|
||||
bne testl
|
||||
seti
|
||||
setf
|
||||
clrf fr0
|
||||
1: movfi fr0,-(sp)
|
||||
sob r4,1b
|
||||
br done
|
||||
|
||||
/ handle 'l': stcfl f0,-(sp); movfi fr0,-(sp) in BSD
|
||||
testl: cmpb $'l,r1
|
||||
bne testf
|
||||
setl
|
||||
setf
|
||||
clrf fr0
|
||||
1: movfi fr0,-(sp)
|
||||
sob r4,1b
|
||||
br done
|
||||
|
||||
/ handle 'f': stf f0,-(sp); movf fr0,-(sp) in BSD
|
||||
testf: cmpb $'f,r1
|
||||
bne testd
|
||||
setf
|
||||
clrf fr0
|
||||
1: movf fr0,-(sp)
|
||||
sob r4,1b
|
||||
br done
|
||||
|
||||
/ handle 'd': std f0,-(sp); movf fr0,-(sp) in BSD
|
||||
testd: cmpb $'d,r1
|
||||
bne quit
|
||||
setd
|
||||
clrf fr0
|
||||
1: movf fr0,-(sp)
|
||||
sob r4,1b
|
||||
br done
|
||||
|
||||
/ quit with bad command
|
||||
quit: inc r0
|
||||
|
||||
/ final cleanup
|
||||
done: mov sp,4(r3) / sp after tests
|
||||
mov r5,sp / restore sp
|
||||
mov (sp)+,r5 / restore r5
|
||||
mov (sp)+,r4 / restore r4
|
||||
mov (sp)+,r3 / restore r3
|
||||
mov (sp)+,r2 / restore r2
|
||||
rts pc
|
||||
116
tools/tests/stktst/stktst.c
Normal file
116
tools/tests/stktst/stktst.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/* $Id: $ */
|
||||
/* SPDX-License-Identifier: GPL-3.0-or-later */
|
||||
/* Copyright 2022- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de> */
|
||||
|
||||
/* Revision History: */
|
||||
/* Date Rev Version Comment */
|
||||
/* 2022-08-01 1267 1.0 Initial version */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
int doconv(arg)
|
||||
char *arg;
|
||||
{
|
||||
char *eptr = NULL;
|
||||
long res = 0;
|
||||
int ires = 0;
|
||||
if (arg[0] == 0) {
|
||||
fprintf(stderr, "stktst-E: empty string instead of a number\n");
|
||||
exit(1);
|
||||
}
|
||||
res = strtol(arg, &eptr, 0);
|
||||
if (eptr[0] != 0) {
|
||||
fprintf(stderr, "stktst-E: number '%s' invalid after '%s' \n", arg, eptr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (errno == ERANGE || res > 0xFFFFL || res < -0x8000L) {
|
||||
fprintf(stderr, "stktst-E: number '%s' out of range\n", arg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ires = res;
|
||||
return ires;
|
||||
}
|
||||
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int argi = 0;
|
||||
char cmd = 0;
|
||||
int rcnt = 0;
|
||||
int cnt = 0;
|
||||
int idat[5];
|
||||
int odat[3];
|
||||
int optrwh = 0;
|
||||
int dotst();
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "stktst-E: at least two arguments required\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cmd = argv[1][0]; /* get command */
|
||||
rcnt = doconv(argv[2]);
|
||||
idat[0] = cmd; /* command code */
|
||||
idat[1] = 0; /* command repeat */
|
||||
idat[2] = 0; /* -c repeat */
|
||||
idat[3] = 0; /* -s repeat */
|
||||
idat[4] = 0; /* -o offset */
|
||||
|
||||
/* check that command is valid */
|
||||
switch (cmd) {
|
||||
case 'r':
|
||||
case 'w':
|
||||
case 'h':
|
||||
optrwh = 1;
|
||||
break;
|
||||
case 'I':
|
||||
case 'i':
|
||||
case 'l':
|
||||
case 'f':
|
||||
case 'd':
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "stktst-E: invalid command %c\n", cmd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* process options */
|
||||
for (argi=3; argi<argc; argi+=2) {
|
||||
if (argi+1 >= argc) {
|
||||
fprintf(stderr, "stktst-E: no value after %s \n", argv[argi]);
|
||||
exit(1);
|
||||
}
|
||||
cnt = doconv(argv[argi+1]);
|
||||
if (strcmp(argv[argi], "-c") == 0) {
|
||||
idat[2] = cnt;
|
||||
} else if (strcmp(argv[argi], "-s") == 0) {
|
||||
idat[3] = cnt;
|
||||
} else if (strcmp(argv[argi], "-o") == 0) {
|
||||
idat[4] = cnt;
|
||||
} else {
|
||||
fprintf(stderr, "stktst-E: bad option %s \n", argv[argi]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (optrwh) idat[1] = rcnt;
|
||||
/* call test: 1st round */
|
||||
dotst(idat, odat);
|
||||
if (optrwh) exit(0);
|
||||
fprintf(stdout, "stktst-I: before sp %06o %06o\n", odat[0], odat[1]);
|
||||
|
||||
/* call test: 2nd round */
|
||||
idat[1] = rcnt;
|
||||
dotst(idat, odat);
|
||||
fprintf(stdout, "stktst-I: after sp %06o %06o %6o\n",
|
||||
odat[0], odat[1], odat[2]);
|
||||
exit(0);
|
||||
}
|
||||
Reference in New Issue
Block a user