home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
clarion
/
brokcode.zip
/
RE4-1.EXE
/
INTLEM.CLA
< prev
Wrap
Text File
|
1992-01-17
|
24KB
|
502 lines
TITLE( 'Listing One - IntLEM.CLA' )
SUBTITLE( 'HEED WARNING ON FIRST PAGE! Demonstrate INT.BIN LEM' )
INTLEM PROGRAM
!╔══════════════════════════════════════════════════════╗
!║ ║
!║ ║
!║ W A R N I N G ! W A R N I N G ! ║
!║ W A R N I N G ! WARNING! W A R N I N G ! ║
!║ W A R N I N G ! W A R N I N G ! ║
!║ ║
!╟──────────────────────────────────────────────────────╢
!║ ║
!║ The program presented here can easily cause your ║
!║ computer system to crash - or worse. This can ║
!║ happen if you incorrectly specify the calling ║
!║ parameters for any particular interrupt. Play ║
!║ it safe - do not run this program if you feel ║
!║ uncomfortable exploring low-level system calls! ║
!║ By using this program, you acknowledge that you ║
!║ take FULL responsibility for any consequences. ║
!║ ║
!╟──────────────────────────────────────────────────────╢
!║ ║
!║ DO NOT MODIFY THIS SOURCE CODE!!! ║
!║ ║
!║ Unless you are an experienced Clarion developer ║
!║ with knowledge about low-level operations. ║
!║ To do so could cause unexpected and possibly ║
!║ serious results. ║
!║ ║
!╟──────────────────────────────────────────────────────╢
!║ ║
!║ That said - don't be afraid to simply load this ║
!║ program. By itself it won't do anything - until ║
!║ you tell it to call an interrupt via an explicit ║
!║ keyboard command ([^ENTER]). As long as you do ║
!║ not press that key command you can play with the ║
!║ various entry fields on the screen. ║
!║ ║
!║ ║
!╚══════════════════════════════════════════════════════╝
!┌────────────────────────────────────────────────────────────────────┐
!│ │
!│ Program..: IntLEM.CLA │
!│ Module...: Global module. │
!│ Function.: N/A │
!│ Version..: 1.00 │
!│ Date.....: 12/10/91 │
!│ Published: Clarion Tech Journal, Volume x, number x │
!│ Notice...: Copyright (c) 1991, 1992 Ronald J. Eisner. │
!│ : All Rights Reserved │
!│ Author...: Ronald J. Eisner, PC Consulting Services │
!│ : P.O. Box 30137, Columbia, MO 65205-3137 │
!│ : Compuserve I.D. # 74010,3011 │
!│ │
!└────────────────────────────────────────────────────────────────────┘
MAP
PROC( StrZeroPad ) ! StrZeroPad( s4HexString )
FUNC( DecToStrHex ), STRING ! s4SHexStr=DecToStrHex(isDecVal)
FUNC( StrHexToDec ), LONG ! ilRegVal = StrHexToDec( sAX )
INCLUDE( 'INT.CPY' ) ! INT.BIN declaration.
END
eFieldOffset EQUATE( 1 ) !. Used in screen LOOPs.
!***** KEYBOARD EQUATES *****!
Esc_Key EQUATE( 256 )
Up_Key EQUATE( 262 )
Ctrl_Esc EQUATE( 279 )
Ctrl_Enter EQUATE( 280 )
F10_Key EQUATE( 2058 )
!***** LOCAL VARIABLES *****!
GlobalVars GROUP, PRE( Gbl ) ! Global variables:
bbQuit BYTE !. TRUE = Quit program.
ibNdx BYTE !. Loop index.
ibField BYTE !. FIELD().
isFlagMask SHORT !. Mask to set screen flags.
ilRegVal LONG !. Temp home of register value.
gOverReg GROUP, PRE( Ovr ), OVER( Gbl:ilRegVal ) !. Over temp reg value.
gLow GROUP !. Low Short.
ibLowLow BYTE !. Low Byte.
ibLowHigh BYTE !. High Byte.
END !.
gHigh GROUP !. High Short.
ibHighLow BYTE !. Low Byte.
ibHighHigh BYTE !. High Byte.
END !.
END !. gOverReg GROUP.
END !. LocalVars GROUP.
gCPU_Strings GROUP, PRE( SPU ) !. "Screen" display CPU Regs group:
sAX STRING( '0000' ) !.. AX Reg (accumulator)
sBX STRING( '0000' ) !.. BX Register (base)
sCX STRING( '0000' ) !.. CX Register (count)
sDX STRING( '0000' ) !.. DX Register (data)
sSI STRING( '0000' ) !.. SI Reg (source index)
sDI STRING( '0000' ) !.. DI Reg (dest. index)
sDS STRING( '0000' ) !.. DS Reg (data segment)
sES STRING( '0000' ) !.. ES Reg (extra)
sInt STRING( '00' ) !.. Int to call (00h-FFh)
END !. gCPU_Strings
! INT.BIN LEM PARAMETER GROUP:
INCLUDE( 'INT.CLI' )
!╔═════════════════════════════════════════════════════════════════════════════╗
!║ .. = Unused FLAGS: ║
!╟─────────────────────────────────────────────────────────────────────────────╢
!║ ║
!║ F E D C B A 9 8 7 6 5 4 3 2 1 0h ║
!║ .. NF └IOP┘ OF DF IF TF SF ZF .. AF .. PF .. CF ║
!║ ┌─────┴─┐ │ │ │ │ │ │ └ Zero │ │ └─ Carry ║
!║ │Nested │ │ │ │ │ │ └─── Sign │ └─────── Parity ║
!║ │Process│ │ │ │ │ └────── Trap └───────────── Auxilary Carry ║
!║ ├───────┴──┴─┐ │ │ └───────── Int Enable ║
!║ │I/O Prot Lvl│ │ └──────────── Direction ║
!║ ├─────┬──────┤ └─────────────── Overflow ║
!║ │ 286+ Only │ ║
!║ └────────────┘ ║
!╚═════════════════════════════════════════════════════════════════════════════╝
fScreen SCREEN PRE(Scr),HUE(7,0)
ROW(1,1) PAINT(23,28),HUE(7,1)
ROW(1,47) PAINT(23,34),HUE(7,1)
COL(1) STRING('<218,196{26},191,0{18},218,196{32},191>')
ROW(2,1) REPEAT(2),EVERY(2)
STRING('<179,0{26},179,0{18},179,0{32},179>') .
ROW(3,1) STRING('<195,196{26},180,0{18},195,196{32},180>')
ROW(5,1) REPEAT(2),EVERY(16)
STRING('<179,0{26},179,0{18},179,0{32},179>') .
ROW(6,1) STRING('<179,0{26},179,0{18},195,196{32},180>')
ROW(7,1) REPEAT(12)
STRING('<179,0{26},179,0{18},179,0{32},179>') .
ROW(19,1) STRING('<179,0{26},179,0{18},179,0{6},196,194,196>' |
& '<0{23},179>')
ROW(20,1) STRING('<179,0{26},179,0{18},179,0{6},196,217>' |
& '<0{24},179>')
ROW(22,1) STRING('<179,0{26},179,0{18},179,0{32},179>')
ROW(23,1) STRING('<192,196{26},217,0{18},192,196{32},217>')
ROW(1,30) REPEAT(2),EVERY(6);STRING('<196{16}>') .
ROW(6,32) STRING('<24,0,25>'),HUE(10,0)
ROW(2,8) STRING('CPU REGISTERS:'),ENH
COL(31) STRING('Keys to ACCEPT'),HUE(2,0)
COL(53) STRING(' INTERRUPT LEM TESTER '),HUE(14,6)
ROW(3,31) STRING('and SELECT'),HUE(2,0)
ROW(4,31) STRING('fields:'),HUE(2,0)
COL(59) STRING('Processor'),ENH
ROW(5,61) STRING('Flags'),ENH
ROW(6,37) STRING('[ENTER]'),HUE(10,0)
ROW(7,7) STRING('AHAL'),HUE(14,1)
COL(52) STRING('0 Carry {9}.. = Unused')
ROW(8,13) STRING('Accumulator')
COL(32) STRING('Other Keys:'),HUE(2,0)
COL(52) STRING('1 ..')
ROW(9,52) STRING('2 Parity')
ROW(10,7) STRING('BHBL'),HUE(14,1)
COL(31) STRING('[ESC]'),HUE(10,0)
COL(38) STRING('Restore'),HUE(2,0)
COL(52) STRING('3 ..')
ROW(11,13) STRING('Base')
COL(38) STRING('Entry'),HUE(2,0)
COL(52) STRING('4 Auxiliary Carry')
ROW(12,52) STRING('5 ..')
ROW(13,7) STRING('CHCL'),HUE(14,1)
COL(31) STRING('[F10]'),HUE(10,0)
COL(38) STRING('Clear'),HUE(2,0)
COL(52) STRING('6 Zero')
ROW(14,13) STRING('Count')
COL(38) STRING('All'),HUE(2,0)
COL(52) STRING('7 Sign')
ROW(15,38) STRING('Fields'),HUE(2,0)
COL(52) STRING('8 Trap')
ROW(16,7) STRING('DHDL'),HUE(14,1)
COL(52) STRING('9 Interrupt Enable')
ROW(17,13) STRING('Data')
COL(30) STRING('^[ENTER]'),HUE(10,0)
COL(40) STRING('Call'),HUE(2,0)
COL(52) STRING('A Direction')
ROW(18,36) STRING('Selected'),HUE(2,0)
COL(52) STRING('B Overflow')
ROW(19,13) STRING('Source Index')
COL(35) STRING('Interrupt'),HUE(2,0)
COL(52) STRING('C')
COL(58) STRING('I/O Protection Level')
ROW(20,13) STRING('Dest Index')
COL(52) STRING('D')
ROW(21,13) STRING('Data Segment')
COL(30) STRING('^[ESC]'),HUE(10,0)
COL(38) STRING('Exit'),HUE(2,0)
COL(52) STRING('E Nested Process')
ROW(22,13) STRING('Extra Segment')
COL(38) STRING('Program'),HUE(2,0)
COL(52) STRING('F ..')
ROW(24,1) STRING('**'),HUE(30,1)
COL(3) STRING('**'),HUE(16,7)
COL(27) STRING('By Ron Eisner (c) 1991, 1992'),ENH
COL(77) STRING('**'),HUE(25,3)
COL(79) STRING('**'),HUE(28,2)
ROW(25,1) STRING('**'),HUE(26,5)
COL(3) STRING('**'),HUE(27,4)
COL(17) STRING(' Clarion Tech Journal {5}Hand Crafted ' |
& 'Clarion '),HUE(14,6)
COL(77) STRING('**'),ENH,BLK
COL(79) STRING('**'),HUE(20,7)
COL(80) ENTRY,USE(?FirstField)
ROW(5,4) STRING('Interrupt To Call:'),HUE(14,1)
COL(24) ENTRY(@S2),USE(SPU:sInt),HUE(15,0),SEL(0,7),OVR,UPR
ROW(8,4) STRING('AX'),HUE(14,1)
COL(7) ENTRY(@S4),USE(SPU:sAX),HUE(15,0),SEL(0,7),OVR,UPR
ROW(11,4) STRING('BX'),HUE(14,1)
COL(7) ENTRY(@S4),USE(SPU:sBX),HUE(15,0),SEL(0,7),OVR,UPR
ROW(14,4) STRING('CX'),HUE(14,1)
COL(7) ENTRY(@S4),USE(SPU:sCX),HUE(15,0),SEL(0,7),OVR,UPR
ROW(17,4) STRING('DX'),HUE(14,1)
COL(7) ENTRY(@S4),USE(SPU:sDX),HUE(15,0),SEL(0,7),OVR,UPR
ROW(19,4) STRING('SI'),HUE(14,1)
COL(7) ENTRY(@S4),USE(SPU:sSI),HUE(15,0),SEL(0,7),OVR,UPR
ROW(20,4) STRING('DI'),HUE(14,1)
COL(7) ENTRY(@S4),USE(SPU:sDI),HUE(15,0),SEL(0,7),OVR,UPR
ROW(21,4) STRING('DS'),HUE(14,1)
COL(7) ENTRY(@S4),USE(SPU:sDS),HUE(15,0),SEL(0,7),OVR,UPR
ROW(22,4) STRING('ES'),HUE(14,1)
COL(7) ENTRY(@S4),USE(SPU:sES),HUE(15,0),SEL(0,7),OVR,UPR
ROW(25,80) ENTRY,USE(?LastField)
REPEAT(16),INDEX(Gbl:ibNdx)
ssFlagBit ROW(7,50) STRING(1),HUE(14,1)
. .
!***** CODE SECTION ****!
CODE
OPEN( fScreen )
DISPLAY()
DO ClearFlags
Gbl:bbQuit = 0
ALERT( Esc_Key )
ALERT( Up_Key )
ALERT( Ctrl_Enter )
ALERT( Ctrl_Esc )
ALERT( F10_Key )
LOOP
SELECT( ?FirstField )
LOOP
ACCEPT
Gbl:ibField = FIELD()
IF REFER()
UPDATE( ? )
! Pad invalid hex digits with zero ('0'):
DO ZeroPadField
DISPLAY( ? ) !.... Display padded field.
DO ConvertToDec !.... Convert hex string to dec.
END !... IF REFER()
CASE KEYCODE() ! Process hot keys:
OF Ctrl_Esc
Gbl:bbQuit = 1
BREAK
OF Esc_Key
SELECT( ? )
DISPLAY( ? )
OF Up_Key
SELECT( ? - 1 )
IF SELECTED() = ?FirstField
SELECT( ?LastField - 1 )
END !.... IF FIELD() = ?FirstField
OF Ctrl_Enter !... Call Interrupt:
SELECT( ? )
!. Filter out Divide By Zero interrupt
!. (causes system to abort program):
IF CPU:ibInt = 00h
CYCLE
END !.... IF CPU:ibInt = 00h
! CALL INTERRUPT:
Interrupt( gCPU_Regs )
! Update all fields with interrupt return values:
LOOP Gbl:ibField = ?FirstField TO ?LastField
DO ConvertToHex
DO SetCPUFlags
DISPLAY( Gbl:ibField )
END !.... LOOP Gbl:ibNdx = ...
OF F10_Key
SELECT( ?FirstField + 1 )
CLEAR( gCPU_Strings )
LOOP Gbl:ibField = ?FirstField TO ?LastField
DO ZeroPadField
DISPLAY( Gbl:ibField )
END !.... LOOP Gbl:ibNdx = ...
DO ClearFlags !.... Clear screen flags.
CPU:ibInt = 0
CPU:isAX = 0
CPU:isBX = 0
CPU:isCX = 0
CPU:isDX = 0
CPU:isSI = 0
CPU:isDI = 0
CPU:isDS = 0
CPU:isES = 0
CPU:isFlags = 0
END !... CASE KEYCODE()
IF Gbl:ibField = ?LastField
SELECT( ?FirstField + 1 )
END !... IF Gbl:ibField = ?LastField.
END !.. LOOP
IF Gbl:bbQuit THEN BREAK. !.. Quit if TRUE.
END !. LOOP
RETURN
!────────────────────────────────
ClearFlags ROUTINE ! Clear all screen flags:
LOOP Gbl:ibNdx = 1 TO SIZE( Gbl:isFlagMask ) * 8
Scr:ssFlagBit = 0
DISPLAY( Scr:ssFlagBit )
END !. LOOP SIZE(Gbl:isFlagMask)...
!────────────────────────────────
SetCPUFlags ROUTINE ! Set screen display flag bits:
Gbl:isFlagMask = 01b
!. Loop once per bit:
LOOP Gbl:ibNdx = 1 TO SIZE( Gbl:isFlagMask ) * 8
IF BAND( CPU:isFlags, Gbl:isFlagMask )
Scr:ssFlagBit = 1
ELSE
Scr:ssFlagBit = 0
END !.. IF BAND(CPU:isFlags...)
DISPLAY( Scr:ssFlagBit )
!. "Walk" mask to the left to test next bit:
Gbl:isFlagMask = BSHIFT( Gbl:isFlagMask, 1 )
END !. LOOP SIZE(Gbl:isFlagMask)...
!────────────────────────────────
ConvertToHex ROUTINE ! Convert current field to hex:
EXECUTE Gbl:ibField - eFieldOffset !. -1 offset from ?FirstField.
!. SPU:sInt only uses the "xx" characters "--xx----" of the return val:
SPU:sInt = SUB( DecToStrHex( CPU:ibInt ), 3, 2 )
SPU:sAX = DecToStrHex( CPU:isAX )
SPU:sBX = DecToStrHex( CPU:isBX )
SPU:sCX = DecToStrHex( CPU:isCX )
SPU:sDX = DecToStrHex( CPU:isDX )
SPU:sSI = DecToStrHex( CPU:isSI )
SPU:sDI = DecToStrHex( CPU:isDI )
SPU:sDS = DecToStrHex( CPU:isDS )
SPU:sES = DecToStrHex( CPU:isES )
END !. EXECUTE Gbl:ibField
!────────────────────────────────
ConvertToDec ROUTINE ! Convert current field to decimal:
!┌─────────────────────────────────────────┐
!│ Assign low two bytes to CPU register: │
!└─────────────────────────────────────────┘
CASE Gbl:ibField
OF ?SPU:sAX; Gbl:ilRegVal = StrHexToDec( SPU:sAX ); CPU:gAX = Ovr:gLow
OF ?SPU:sBX; Gbl:ilRegVal = StrHexToDec( SPU:sBX ); CPU:gBX = Ovr:gLow
OF ?SPU:sCX; Gbl:ilRegVal = StrHexToDec( SPU:sCX ); CPU:gCX = Ovr:gLow
OF ?SPU:sDX; Gbl:ilRegVal = StrHexToDec( SPU:sDX ); CPU:gDX = Ovr:gLow
OF ?SPU:sSI; Gbl:ilRegVal = StrHexToDec( SPU:sSI ); CPU:gSI = Ovr:gLow
OF ?SPU:sDI; Gbl:ilRegVal = StrHexToDec( SPU:sDI ); CPU:gDI = Ovr:gLow
OF ?SPU:sDS; Gbl:ilRegVal = StrHexToDec( SPU:sDS ); CPU:gDS = Ovr:gLow
OF ?SPU:sES; Gbl:ilRegVal = StrHexToDec( SPU:sES ); CPU:gES = Ovr:gLow
OF ?SPU:sInt; Gbl:ilRegVal = StrHexToDec( SPU:sInt ); CPU:ibInt = Ovr:ibLowLow
END !. CASE Gbl:ibField.
!────────────────────────────────
ZeroPadField ROUTINE ! Zero-pad current field:
EXECUTE Gbl:ibField - eFieldOffset !. -1 offset from ?FirstField.
StrZeroPad( SPU:sInt )
StrZeroPad( SPU:sAX )
StrZeroPad( SPU:sBX )
StrZeroPad( SPU:sCX )
StrZeroPad( SPU:sDX )
StrZeroPad( SPU:sSI )
StrZeroPad( SPU:sDI )
StrZeroPad( SPU:sDS )
StrZeroPad( SPU:sES )
END !. EXECUTE FIELD()
!────────────────────────────────
StrZeroPad PROCEDURE( xsString ) ! Replace invalid chars with '0':
!────────────────────────────────
xsString EXTERNAL
LocalVars GROUP, PRE( Lcl )
ilStrLen LONG !. Length of external string.
ilNdx LONG !. Loop index.
s1Char STRING( 1 ) !. Character being compared.
END
CODE
Lcl:ilStrLen = LEN( xsString )
LOOP Lcl:ilNdx = 1 TO Lcl:ilStrLen
Lcl:s1Char = SUB( xsString, Lcl:ilNdx, 1 )
IF NOT INSTRING( Lcl:s1Char, '0123456789ABCDEF' )
! Replace non-valid characters with zero ('0'):
xsString = SUB( xsString, 1, Lcl:ilNdx - 1 ) |
& '0' |
& SUB( xsString, Lcl:ilNdx + 1, Lcl:ilStrLen )
END !.. IF NOT INSTRING()
END !. LOOP ibNdx = 1 TO ilStrLen
!────────────────────────────────
DecToStrHex FUNCTION( pisDec ) ! Convert decimal to hex "string":
!────────────────────────────────
LocalVars GROUP, PRE( Lcl )
pisDec SHORT !. Short parameter to convert.
!. aibOverDec lays BYTEs over the decimal value:
aibOverDec BYTE, DIM(SIZE( Lcl:pisDec )), OVER( Lcl:pisDec )
ibNdx BYTE !. Loop index.
ibNibble BYTE !. Nibble being converted.
s1Nibble STRING( 1 ) !. Nibble converted to string Hex.
sConverter STRING( '123456789ABCDEF' ) !. Used to convert hex to dec.
s4RetVal STRING( 8 ) !. String Hex return value.
END
CODE
Lcl:s4RetVal = '' !. Clear any stray value.
!. Step through overlaid bytes:
LOOP Lcl:ibNdx = 1 TO MAXIMUM( Lcl:aibOverDec[], 1 )
!. Get low nibble:
Lcl:ibNibble = BAND( Lcl:aibOverDec[ Lcl:ibNdx ], 0Fh )
DO NibToHex !.. Convert to hex.
!. Get high nibble:
Lcl:ibNibble = BAND( Lcl:aibOverDec[ Lcl:ibNdx ], 0F0h )
!. Shift to low nibble for conversion:
Lcl:ibNibble = BSHIFT( Lcl:ibNibble, -4 )
DO NibToHex !.. Convert to hex.
END !. LOOP Lcl:ibNdx = 1 TO MAX...
RETURN( Lcl:s4RetVal )
!────────────────────────────────
NibToHex ROUTINE ! Convert nibble to hex:
Lcl:s1Nibble = SUB( Lcl:sConverter, Lcl:ibNibble, 1 )
!. '0' must be handled as an exception because SUB() will return NULL:
IF Lcl:s1Nibble = ''
Lcl:s1Nibble = '0'
END !. IF Lcl:s1Nibble = ''.
!. Tack nibble onto left side of hex string:
Lcl:s4RetVal = Lcl:s1Nibble & CLIP( Lcl:s4RetVal )
!────────────────────────────────
StrHexToDec FUNCTION( xsHexStr ) ! Convert hex "string" to decimal:
!────────────────────────────────
xsHexStr EXTERNAL !. Converts up to a SHORT.
LocalVars GROUP, PRE( Lcl )
ilRetVal LONG !. Decimal return value.
ibStrLen BYTE !. Length of sHexStr.
ibNdx BYTE !. Loop index.
sConverter STRING( '123456789ABCDEF' ) !. Used to convert hex to dec.
s1Char STRING( 1 ) !. Char to convert.
ibOffset BYTE !. Offset into sConverter.
END
CODE
Lcl:ilRetVal = 0
Lcl:ibStrLen = LEN( xsHexStr )
LOOP Lcl:ibNdx = Lcl:ibStrLen TO 1 BY - 1
!. Get one character to convert:
Lcl:s1Char = SUB( xsHexStr, Lcl:ibNdx, 1 )
!. Get offset into value table:
Lcl:ibOffset = INSTRING( Lcl:s1Char, Lcl:sConverter )
!. Raise character to correct power of 16
!. (Rightmost position is ^0):
ilRetVal += Lcl:ibOffset * 16^( Lcl:ibStrLen - Lcl:ibNdx )
END !. LOOP Lcl:ibNdx=Lcl:ibStrLen...
RETURN( Lcl:ilRetVal )