Our first version of a nucleus will not do much – but it will do something! It will set a value in the Interval Timer. The CPU will subtract from this value several times every second. When the value goes to zero an External Interrupt will be generated. This will cause the CPU to save the current PSW into the External Old PSW area in low core and load a new PSW from the External New PSW location. In our interrupt routine we will reset the Interval Timer and load a PSW with the wait bit set – but enabled for interrupts.
TXXNUC CSECT , DC X'00',X'00',AL2(0),AL4(DISPINIT) INITIAL PSW DC D'0' RST NEW PSW * DC A(CVT) COMM VECT TABLE DC A(MVT) MOD VECT TABLE * DC D'0' EXT OLD PSW DC D'0' SVC OLD PSW DC D'0' PGM OLD PSW DC D'0' MCK OLD PSW DC D'0' I/O OLD PSW * DC D'0' CHANNEL STATUS WORD DC F'0' CHANNEL ADDRESS WORD DC F'0' DC F'0' INTERVAL TIMER DC F'0' * DC X'00',X'00',AL2(0),AL4(EXTHNDLR) EXT NEW PSW DC X'00',X'00',AL2(0),AL4(SVCHNDLR) SVC NEW PSW DC X'00',X'00',AL2(0),AL4(PGMHNDLR) PGM NEW PSW DC X'00',X'00',AL2(0),AL4(@E@MCK) MCK NEW PSW DC X'00',X'00',AL2(0),AL4(IOHNDLR) I/O NEW PSW * * LOWCLEN EQU *-TXXNUC LOWCFILL EQU 1024-LOWCLEN DC (LOWCFILL)X'00'
We begin by filling in some low core values needed by the CPU. We specify the PSW’s to be loaded when the corresponding interrupt occurs. Finally we pad low core up to 1k (1024) with binary zeros.
EXTREGS DC 16F'0' EXT INTERRUPT REG SAVE IOREGS DC 16F'0' I/O INTERRUPT REG SAVE SVCREGS DC 16F'0' SVC INTERRUPT REG SAVE PGMREGS DC 16F'0' PGM INTERRUPT REG SAVE * * CVT DC A(0) +++ PLACE HOLDER +++ MVT DC A(0) +++ PLACE HOLDER +++
Next we go ahead and define some data areas. These will not be used right now but they will be needed in later versions of our nucleus code.
USING TXXNUC,0 * SVCHNDLR DS 0H PGMHNDLR DS 0H IOHNDLR DS 0H LPSW WAITPSW * DS 0D WAITPSW DC X'00',X'02',AL2(0),A(X'EE9999')
If an SVC, Program, or I/O interrupt occurs we load a disabled wait PSW.
EXTHNDLR DS 0H L R1,=A(X'80') INTERVAL TIMER VALUE ST R1,ITIMER-@LOWCORE SAVE INTO TIMER * LPSW IWAIT LOAD WAIT PSW * DS 0D IWAIT DC AL1(255,2,0,0),AL4(X'FEAD') * * DISPINIT DS 0H B EXTHNDLR
When an External interrupt occurs we store a new value into the interval timer and then load an Enabled Wait PSW. The PSW must be enabled for External interrupts so our interrupt routine will be invoked when the timer expires.
@LOWCORE , * @REGS , @@ERR , END ,
Finally we include our macros for mapping low core and registers. I have also created a new macro called @@ERR to contain wait state codes.
Once the nucleus is assembled and link edited as TXXNUC we can fire up Hercules and IPL from our DASD volume. We should see our enabled wait PSW with the code ‘FEAD’ and we should observe the CPU waking up and performing a few instructions before going back into the wait state.
[Next – Dispatcher]