Skip to content

Faster But Flakier – Punching Through Hercules

August 31, 2018

I hacked the SVC processing code of the Hercules Emulator to let me get at the hardware of the Raspberry Pi. I’m using the WiringPi library so it’s not super fast but with minimal processing on the 370 side I can flip the GPIO in around 1.4 uS which is probably fine. Some function of Hercules is generating an interrupt every 10mS which takes control for 300 uS or so. You wouldn’t want to be driving a servo or reading an ultrasonic sensor but it should be fine for general use. I assume I can use native Pi or WiringPi functions in those cases.
The images blow show the interruption every 10mS and the fine-grained square wave in between.

I’m pretty sure that the interruption is in hercules code rather than linux because it always happens right after a 370 branch instruction is processed.

My 370 test code is very hard core – just a dozen instructions banged into low memory. I’m doing this because it’s kind of fun and also because the version of hercules that i’ve modified doesn’t run MVS TK4- properly yet. Once I get that figured out i’ll develop some C wrappers for the SVC calls.
18-08-19 dwon
I have to say i’m a bit amazed that i can program 370 machine language 40 years after my stint as a system programmer. Not just to remember that the opcode for LOAD Address is 41 but that 41 10 0002 would load a 2 into register 1 or that an unconditional branch is 47F0xxxx.

The code below is my first crack at letting a 370 program access the underlying Raspberry Pi. This is inserted in module general2.c around line 1300 where the Supervisor Call is emulated. Normally an SVC would cause the emulated CPU to pick up the address of some 370 code from fixed 370 memory locations and branch to that code but with this mod the emulator directly performs some function based on the 370 register contents and returns to the emulated program. It’s nasty but it gets the job done. As long i don’t expect my modfied hercules to work anywhere other than on the Pi it should be fine.

int wiringMVS(int function, int parameter){//implements wiringPi functions for MVS
	static int wiringPiIsSetup=0;
	static FILE* wiringMVSLog;
	int result=0;
	if (!wiringPiIsSetup){
 		printf("Setup() sez %d\n",wiringPiSetup ());
		wiringPiIsSetup=1;
	}
	switch (function){
		case 0:	//pinmode INPUT
			pinMode(parameter,INPUT);
			break;
		case 1: //pinmode output
			pinMode(parameter,OUTPUT);
			break;
		case 2: //digitalWrite(LOW)
			digitalWrite(parameter,LOW);
			break;
		case 3: //digitalWrite(HIGH)
			digitalWrite(parameter,HIGH);
			break;
		case 4: //digitalRead
			result=digitalRead(parameter);
		case 5: //
			delay(parameter);
			break;
		case 6: //
			if (wiringPiIsSetup!=1){
 				printf("Setup() sez %d\n",wiringPiIsSetup,wiringPiSetup ());
				wiringPiIsSetup=1;
			}
break;
	}
	return result;
}

 

---Near the top of the file
#include
#if !defined(_GENERAL2_C_)
#define _GENERAL2_C_
#include "wiringMVS.c" //WJR
#endif
---Near line 1335
/*-------------------------------------------------------------------*/
/* 0A   SVC   - Supervisor Call                                 [RR] */
/*-------------------------------------------------------------------*/
DEF_INST(supervisor_call)
{
BYTE    i;                              /* Instruction byte 1        */
PSA    *psa;                            /* -> prefixed storage area  */
RADR    px;                             /* prefix                    */
int     rc;                             /* Return code               */

    RR_SVC(inst, regs, i);
//following 12 lines per wjr 18-07-28
#if 1
//printf("bingo! i=%x, regs->GR_L(0)=%x\n",i,regs->GR_L(0));
/* if we have an SVC 255 and R0 is set to a magic number, then
we invoke the wiringpi code for MVS */
if ((i == 255) && (regs->GR_L(0) == 0x00000042))
	{
	regs->GR_L(15)=wiringMVS(regs->GR_L(1),regs->GR_L(2));
    	PERFORM_SERIALIZATION (regs);
    	PERFORM_CHKPT_SYNC (regs);
    	RETURN_INTCHECK(regs);
	}
#endif

In addition to those source code changes I had to install wiringPi itself from http://wiringpi.com/download-and-install/ and change the LIBS line in the makefile (around line 823) to
LIBS = -lrt -lz -lresolv -lnsl -lm -ldl -pthread -lwiringPi
Obviously I’d rather no diddle the generated makefile but I’m not clear how to pass that from the command line.

Advertisements

From → Olduino/370

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: