Esempio n. 1
0
void jump(unsigned short addr)
{
        if (swtpc) {
                pc = addr;
                return;
        } else {
                switch (addr) {
/* Too many programs access ACIA directly */
#if 0
                        case 0xF9CF: case 0xF9DC: /* Output a character */ {
                                term_out(acca);
                                /* putchar(acca); fflush(stdout); */
                                c_flag = 0; /* Carry is error status */
                                break;
                        }
#endif
                        case 0xFA8B: /* Input a character */ {
                                acca = term_in();
                                if (!mem[0xFF53]) { /* Echo */
                                        term_out(acca);
                                        /* putchar(c);
                                        fflush(stdout); */
                                } else {
                                        mem[0xFF53] = 0;
                                }
                                c_flag = 0; /* No error */
                                break;
                        }
                        case 0xE800: /* OSLOAD (no modified parms) */ {
                                printf("\nOSLOAD...\n");
                                getsect(0, 0x0020, 23, 128);
                                getsect(0, 0x0020 + 0x0080, 24, 128);
                                pc = 0x0020;
                                sp = 0x00FF;
                                return;
                        } case 0xE822: /* FDINIT (no modified parms) */ {
                                c_flag = 0;
                                break;
                        } 
#if 0
                          case 0xF853: /* CHKERR */ {
                                break;
                        } case 0xE85A: /* PRNTER */ {
                                break;
                        } 
#endif
                          case 0xE869: /* READSC (read full sectors) */ {
                                mem[LSCTLN] = 128;
                        } case 0xE86D: /* READPS (read partial sectors) (FDSTAT, carry, sides) */ {
                                int x;
                                int n = mem[CURDRV];
                                int first = (mem[STRSCT] << 8) + mem[STRSCT + 1];
                                int num = (mem[NUMSCT] << 8) + mem[NUMSCT + 1];
                                int addr = (mem[CURADR] << 8) + mem[CURADR + 1];
                                int last = mem[LSCTLN];
                                if (trace_disk) printf("Read sectors: drive=%d, first=%d, number=%d, addr=%x, size of last=%d\n", n, first, num,
                                       addr, last);
                                if (check_drive(n))
                                        break;
                                for (x = 0; x != num; ++x) {
                                        if (check_sect(n, first + x))
                                                goto oops;
                                        getsect(n, addr + 128 * x, first + x, ((x + 1 == num) ? mem[LSCTLN] : 128));
                                }
                                mem[FDSTAT] = ER_NON;
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                c_flag = 0;
                                oops: break;
                        } case 0xE86F: /* RDCRC */ {
                                if (trace_disk) printf("RDCRC\n");
                                int x;
                                int n = mem[CURDRV];
                                int first = (mem[STRSCT] << 8) + mem[STRSCT + 1];
                                int num = (mem[NUMSCT] << 8) + mem[NUMSCT + 1];
                                int addr = (mem[CURADR] << 8) + mem[CURADR + 1];
                                int last = mem[LSCTLN];
                                if (trace_disk) printf("RDCRC: drive=%d, first=%d, number=%d, addr=%x, size of last=%d\n", n, first, num,
                                       addr, last);
                                if (check_drive(n))
                                        break;
                                for (x = 0; x != num; ++x) {
                                        if (check_sect(n, first + x))
                                                goto oops;
                                }
                                mem[FDSTAT] = ER_NON;
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                c_flag = 0;
                                break;
                        } case 0xE875: /* RESTOR */ {
                                int n = mem[CURDRV];
                                if (trace_disk) printf("RESTOR\n");
                                if (check_drive(n))
                                        break;
                                mem[FDSTAT] = ER_NON;
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                c_flag = 0;
                                break;
                        } case 0xE878: /* SEEK */ {
                                int n = mem[CURDRV];
                                int first = (mem[STRSCT] << 8) + mem[STRSCT + 1];
                                if (trace_disk) printf("SEEK\n");
                                if (check_drive(n))
                                        break;
                                if (check_sect(n, first))
                                        break;
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                c_flag = 0;
                                break;
                        } case 0xE872: /* RWTEST */ {
                                if (trace_disk) printf("RWTEST\n");
                        } case 0xE87B: /* WRTEST */ {
                                unsigned char buf[128];
                                int x;
                                int n = mem[CURDRV];
                                int first = (mem[STRSCT] << 8) + mem[STRSCT + 1];
                                int num = (mem[NUMSCT] << 8) + mem[NUMSCT + 1];
                                int addr = (mem[CURADR] << 8) + mem[CURADR + 1];
                                int last = mem[LSCTLN];
                                if (trace_disk) printf("WRTEST\n");
                                if (check_drive(n))
                                        break;
                                for (x = 0; x != 128; x += 2) {
                                        buf[x] = mem[addr];
                                        buf[x + 1] = mem[addr + 1];
                                }
                                for(x=0; x != num; ++x) {
                                        if (check_sect(n, first + x))
                                                goto oops;
                                        if (trace_disk) printf("Wrtest sector %d drive %d\n", first + x, n);
                                        fseek(drive[n].f, (first + x) * 128, SEEK_SET);
                                        fwrite(buf, 128, 1, drive[n].f);
                                        fflush(drive[n].f);
                                }
                                c_flag = 0;
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                mem[FDSTAT] = ER_NON;
                                break;
                        } case 0xE87E: /* WRDDAM */ {
                                int n = mem[CURDRV];
                                printf("\r\nFloppy error: we do not support WRDDAM\n");
                                c_flag = 1;
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                mem[FDSTAT] = ER_WRT;
                                break;
                        } case 0xE884: /* WRITSC */ {
                                if (trace_disk) printf("WRITSC\n");
                        } case 0xE881: /* WRVERF */ {
                                int x;
                                int n = mem[CURDRV];
                                int first = (mem[STRSCT] << 8) + mem[STRSCT + 1];
                                int num = (mem[NUMSCT] << 8) + mem[NUMSCT + 1];
                                int addr = (mem[CURADR] << 8) + mem[CURADR + 1];
                                int last = mem[LSCTLN];
                                if (trace_disk) printf("WRVERF: drive=%d, first=%d, number=%d, addr=%x, size of last=%d\n", n, first, num,
                                       addr, last);
                                if (check_drive(n))
                                        break;
                                for(x=0; x != num; ++x) {
                                        if (check_sect(n, first + x))
                                                goto oops;
                                        putsect(n, addr + 128 * x, first + x, 128);
                                }
                                if (drive[n].tracks == 77)
                                        mem[SIDES] = 0x80;
                                else
                                        mem[SIDES] = 0;
                                mem[FDSTAT] = ER_NON;
                                c_flag = 0;
                                break;
                        } case 0xE887: /* CLOCK */ {
                                printf("Floppy: Someone called CLOCK?\n");
                                c_flag = 0;
                                break;
                        } case 0xEBC0: /* LPINIT */ {
                                if (trace_disk) printf("LPINIT\n");
                                c_flag = 0;
                                break;
                        } case 0xEBCC: /* LIST */ {
                                if (trace_disk) printf("LIST\n");
                                term_out(acca);
                                /* putchar(acca); fflush(stdout); */
                                c_flag = 0;
                                break;
                        } case 0xEBE4: /* LDATA */ {
                                if (trace_disk)printf("LDATA\n");
                                while (mem[ix] != 4) {
                                        term_out(mem[ix]);
                                        /* putchar(mem[ix]); */
                                        ++ix;
                                }
                                term_out('\r');
                                term_out('\n');
                                /* printf("\n"); */
                                c_flag = 0;
                                break;
                        } case 0xEBF2: /* LDATA1 */ {
                                if (trace_disk) printf("LDATA1\n");
                                while (mem[ix] != 4) {
                                        /* putchar(mem[ix]); */
                                        term_out(mem[ix]);
                                        ++ix;
                                }
                                /* fflush(stdout); */
                                c_flag = 0;
                                break;
                        } default: {
                                pc = addr;
                                return;
                        }
                }
                simulated(addr);
                addr = pull2();
                jump(addr);
        }
}
Esempio n. 2
0
/*eject*/
pboslist()
{

/*
 * Process the BLDOUTSC List
 */

	register OUTSECT *osptr;
	register INSECT *insptr;
	register INFILE *inflptr;
#if !ONEPROC
	ACTITEM a;
#endif
	OUTSECT *dfn_scn_grp();
	long	check_sect();


/*
 * Process the list of output sections.  Output sections can be 
 * defined in two places:
 *
 *	1. PASS 1: user-supplied; bldcnt will be > 0, and the bldoutsc 
 *			list head will be NULL
 *	2. PASS 2: default-generation; bldcnt will be 0, and the
 *			bldoutsc list will describe the output
 *			sections
 *
 *	These two uses are mutually exclusive
 */

#if DEBUG
	if( dflag > 2 )
		fprintf( stderr, "\nBLDOSCN data structures:" );
#endif
#if !ONEPROC
	while( bldcnt-- ) {

		fread( &a, 1, sizeof(ACTITEM), trnfdes );
		a.dfnscn.aiinflnm = (char *) ((int) a.dfnscn.aiinflnm + (int) strbase);
		if (a.dfnscn.aibndadr != NULL)
			a.dfnscn.aibndadr = ldlimb( );
		if (a.dfnscn.aialign != NULL)
			a.dfnscn.aialign = ldlimb( );

		osptr = dfn_scn_grp(&a, 0);
		copy(osptr->oshdr.s_name, a.dfnscn.ainame, 8);
#if TRVEC
		/*
		 * User can define attributes of TV in two ways:
		 * (1) using TV { } directive
		 * (2) using SECTIONS { .tv : {} } directive
		 * so force them to agree
		 */
		if ( equal(a.dfnscn.ainame, _TV, 8) ) { /* defining .tv */
			if ( tvspec.tvbndadr == -1L )
			{
				lineno = a.dfnscn.aiinlnno;
				curfilnm = a.dfnscn.aiinflnm;
				tvspec.tvbndadr = eval( a.dfnscn.aibndadr) ;
			}
			else
				a.dfnscn.aibndadr = cnstnode( tvspec.tvbndadr );
		}
#endif
		if( a.dfnscn.aitype == AIDFNSCN )
			numoutsc++;

		osptr->oshdr.s_paddr = -1L;
		listadd(l_OS, &outsclst, osptr);
		}
#endif

	/*
	 * We now know everything there is to know about the
	 * transfer vector:
	 *	At the end of ploadfil(), we knew how big it
	 *	had to be.
	 *	Here we know whether it was defined by ld or
	 *	whether it is defined by .tv input sections
	 *	together with a .tv SECTION directive
	 * Go check everything and complete tvspec definition.
	 */

#if TRVEC
	if ( tvflag )
		tvupdat();	/* update definition of tv */
#endif

	if( bldoutsc.head ) {
		register ACTITEM *aptr, *a2ptr;

		aptr = (ACTITEM *) bldoutsc.head;
		while( aptr ) {

			osptr = dfn_scn_grp(aptr, 1);
	
			copy(osptr->oshdr.s_name, aptr->dfnscn.ainame, 8);
			if( aptr->dfnscn.aitype == AIDFNSCN )
				numoutsc++;
	
			osptr->oshdr.s_paddr = -1L;
			listadd(l_OS, &outsclst, osptr);

			a2ptr = aptr;
			aptr = aptr->dfnscn.ainext;
			free( (char *) a2ptr);
			}
		}

/*
 * Make sure all input sections are allocated
 * into some output section.
 */

	for( inflptr = (INFILE *) infilist.head; inflptr; inflptr = inflptr->flnext ) {
		for( insptr = inflptr->flishead; insptr; insptr=insptr->isnext ) {
			if (insptr->isoutsec == 0) {
				if ((osptr = fndoutsec(insptr->ishdr.s_name)) != NULL)
					inscadd(insptr,osptr);
				else {
					osptr = (OUTSECT *) mycalloc( sizeof( OUTSECT ));
					numoutsc++;
					copy(osptr->oshdr.s_name, insptr->ishdr.s_name, 8);
					osptr->osfill = globfill;
					osptr->oshdr.s_paddr = -1l;
					osptr->osnlnno = 1;
					osptr->osnflnm = "*default*";
					listadd(l_OS,&outsclst,osptr);
					inscadd(insptr,osptr);
					}
				}
			}
		}

	/*
	 * for each output section, check the flags, and for a group,
	 * check the size.
	 */

	for( osptr = (OUTSECT *) outsclst.head; osptr; osptr = osptr->osnext ) 
		{
#if PAGING
			ACTITEM *aptr;
			ADDRESS textbegin, textsize;
			textbegin = hflag + FILHSZ + SCNHSZ * numoutsc + memorg;
#endif
		if (osptr->oshdr.s_flags & STYP_GROUP) {
			OUTSECT *op;
			for( op = ((OUTSECT *) osptr->osinclhd); op; op = op->osnext ) {
#if PAGING
				if (bond_t_d && !Nflag && equal(op->oshdr.s_name,_DATA,8)) {
					osptr->osalign = NULL;
					aptr = (ACTITEM *) mycalloc(sizeof(ACTITEM));
					aptr->bond.aitype = AIBOND;
					aptr->bond.aiinflnm = "*default.bond.file*";
					aptr->bond.aiinlnno = 3;
					aptr->bond.aioutsec = osptr;
					aptr->bond.aiadrbnd =  cnstnode(((textsize + textbegin) / BOUNDARY + 1) 
						* BOUNDARY + (textsize + textbegin) % K8);
					listadd(l_AI,&bondlist,aptr);
					}
#endif
				osptr->oshdr.s_size += check_sect( op );
				}
			if (osptr->oshdr.s_size > MAXSCNSIZE)
				lderror(1,0,NULL, "GROUP containing section %.8s is too big",
				    osptr->osinclhd->ishdr.s_name);
		} else {
#if PAGING
			if (bond_t_d && !Nflag && equal(osptr->oshdr.s_name,_TEXT,8)) {
				textsize = osptr->oshdr.s_size;
				aptr = (ACTITEM *) mycalloc(sizeof(ACTITEM));
				aptr->bond.aitype = AIBOND;
				aptr->bond.aiinflnm = "*default.bond.file*";
				aptr->bond.aiinlnno = 2;
				aptr->bond.aioutsec = osptr;
				aptr->bond.aiadrbnd = cnstnode( textbegin );
				listadd(l_AI,&bondlist,aptr);
				}
#endif
			check_sect( osptr );
			}
		}

	/*
	 * If .tv is user-defined, we now know the true size of
	 * the section ( the sum of the sizes of the input
	 * sections) which we didn't know before. Now call the
	 * the final update routine to insure .tv symtab entry
	 * is correct
	 */

#if TRVEC
	if ( tvflag )
		tvupdt2();	/* final update of tvrange and tvlength */
#endif

#if DEBUG
	if (dflag)
		dmp_outsects();
#endif
}