85 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|  *  Sources of the "ARRAY" group instructions
 | |
|  */
 | |
| 
 | |
| /* $Id$ */
 | |
| 
 | |
| #include	"em_abs.h"
 | |
| #include	"global.h"
 | |
| #include	"log.h"
 | |
| #include	"trap.h"
 | |
| #include	"mem.h"
 | |
| #include	"text.h"
 | |
| #include	"fra.h"
 | |
| 
 | |
| #define	LAR		1
 | |
| #define	SAR		2
 | |
| #define	AAR		3
 | |
| 
 | |
| PRIVATE void arr(int, size);
 | |
| 
 | |
| 
 | |
| void DoLAR(size arg)
 | |
| {
 | |
| 	/* LAR w: Load array element, descriptor contains integers of size w */
 | |
| 	LOG(("@A6 DoLAR(%ld)", arg));
 | |
| 	arr(LAR, arg_wi(arg));
 | |
| }
 | |
| 
 | |
| void DoSAR(size arg)
 | |
| {
 | |
| 	/* SAR w: Store array element */
 | |
| 	LOG(("@A6 DoSAR(%ld)", arg));
 | |
| 	arr(SAR, arg_wi(arg));
 | |
| }
 | |
| 
 | |
| void DoAAR(size arg)
 | |
| {
 | |
| 	/* AAR w: Load address of array element */
 | |
| 	LOG(("@A6 DoAAR(%ld)", arg));
 | |
| 	arr(AAR, arg_wi(arg));
 | |
| }
 | |
| 
 | |
| 
 | |
| /********************************************************
 | |
| *		Array arithmetic			*
 | |
| *							*
 | |
| *	1. The address of the descriptor is popped.	*
 | |
| *	2. The index is popped.				*
 | |
| *	3. Calculate index - lower bound.		*
 | |
| *	4. Check if in range.				*
 | |
| *	5. Calculate object size.			*
 | |
| *	6. Perform the correct function.		*
 | |
| *********************************************************/
 | |
| 
 | |
| PRIVATE void arr(int type, /* operation TYPE */
 | |
| 		size elm_size /* ELeMent SIZE */
 | |
| 		)
 | |
| {
 | |
| 	register ptr desc = dppop();	/* array DESCriptor */
 | |
| 	register size obj_size;		/* OBJect SIZE */
 | |
| 	long index = spop(elm_size);
 | |
| 	long diff =		/* between index and lower bound */
 | |
| 		index - mem_lds(desc, elm_size);
 | |
| 	register ptr arr_addr = dppop();/* ARRay ADDRess */
 | |
| 
 | |
| 	if (must_test && !(IgnMask&BIT(EARRAY))) {
 | |
| 		if (diff < 0 || index > mem_lds(desc + elm_size, elm_size)) {
 | |
| 			trap(EARRAY);
 | |
| 		}
 | |
| 	}
 | |
| 	obj_size = mem_lds(desc + (2*elm_size), elm_size);
 | |
| 	obj_size = arg_o(((long) obj_size));
 | |
| 	spoilFRA();			/* array functions don't retain FRA */
 | |
| 	switch (type) {
 | |
| 		case LAR:
 | |
| 			push_m(arr_addr + diff * obj_size, obj_size);
 | |
| 			break;
 | |
| 		case SAR:
 | |
| 			pop_m(arr_addr + diff * obj_size, obj_size);
 | |
| 			break;
 | |
| 		case AAR:
 | |
| 			dppush(arr_addr + diff * obj_size);
 | |
| 			break;
 | |
| 	}
 | |
| }
 |