To keep things fast, I use memory and disk space like a "good" HOG.
Instead of loading "rom" it loads "bigrom" which is a 512K file
containing the expanded rom nibbles. I have included a program called
mkbigrom.c that does the conversion from rom as a filter.
(ie % mkbigrom <rom >bigrom )
You will need a -DMY48 on the compile line in the makefile to get my
changes to take effect.
Enjoy
arthur
--
"The first fact to face is that UNIX was not developed with security, in any
reliable sense, in mind; this fact alone guarantees a vast number of holes."
-- "On the Security of UNIX", Dennis M. Ritchie
Arthur Tateishi ruh...@turing.utoronto.ca
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, use "sh file -c".
# If this archive is complete, you will see the following message at the end:
# "End of shell archive."
#
# Contents:
# patches mkbigrom.c
#
# Wrapped by ruh...@turing.toronto.edu.utoronto.ca on Fri Mar 20 19:46:44 1992
#
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f patches -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"patches\"
else
echo shar: Extracting \"patches\" \(11208 characters\)
sed "s/^X//" >patches <<'END_OF_patches'
X*** ../em48o/command.c Fri Mar 13 11:48:43 1992
X--- command.c Mon Mar 16 12:03:43 1992
X***************
X*** 964,975 ****
X--- 964,983 ----
X /***********************************************/
X /* Save I/O address space. */
X /***********************************************/
X+ #ifdef MY48
X+ fwrite(cpu.ram, 0x100*2*sizeof(Nibble), 1, fp);
X+ #else
X fwrite(cpu.ram, 0x100, 1, fp);
X+ #endif
X /***********************************************/
X /* Save internal 32K memory plus two 128K */
X /* card slots. */
X /***********************************************/
X+ #ifdef MY48
X+ fwrite(&cpu.ram[0x70000], (32 + 128 + 128) * 1024*sizeof(Nibble), 1, fp);
X+ #else
X fwrite(&cpu.ram[0x70000 >> 1], (32 + 128 + 128) * 1024, 1, fp);
X+ #endif
X fclose(fp);
X }
X /**********************************************************************/
X***************
X*** 992,1006 ****
X perror(filename);
X return;
X }
X! if (fread(&cpu, sizeof cpu, 1, fp) != 1) {
X fprintf(stderr, "Error reading CPU state info\n");
X exit(1);
X }
X if (fread(cpu.ram, 0x100, 1, fp) != 1) {
X fprintf(stderr, "Error reading RAM area\n");
X exit(1);
X }
X if (fread(&cpu.ram[0x70000 >> 1], (32 + 128 + 128) * 1024, 1, fp) != 1) {
X fprintf(stderr, "Error reading RAM area\n");
X exit(1);
X }
X--- 1000,1022 ----
X perror(filename);
X return;
X }
X! if (fread(&cpu, sizeof(cpu), 1, fp) != 1) {
X fprintf(stderr, "Error reading CPU state info\n");
X exit(1);
X }
X+ #ifdef MY48
X+ if (fread(cpu.ram, 0x100*2*sizeof(Nibble), 1, fp) != 1) {
X+ #else
X if (fread(cpu.ram, 0x100, 1, fp) != 1) {
X+ #endif
X fprintf(stderr, "Error reading RAM area\n");
X exit(1);
X }
X+ #ifdef MY48
X+ if (fread(&cpu.ram[0x70000], (32 + 128 + 128) * 1024*sizeof(Nibble), 1, fp) != 1) {
X+ #else
X if (fread(&cpu.ram[0x70000 >> 1], (32 + 128 + 128) * 1024, 1, fp) != 1) {
X+ #endif
X fprintf(stderr, "Error reading RAM area\n");
X exit(1);
X }
X*** ../em48o/dis48.h Fri Mar 13 11:48:48 1992
X--- dis48.h Fri Mar 13 11:47:37 1992
X***************
X*** 4,9 ****
X--- 4,19 ----
X # include <io.h>
X # endif
X
X+ #ifdef MY48
X+ #ifndef FILE_EM48
X+ extern CPU cpu;
X+ #endif
X+ #endif
X+
X+ #ifdef MY48
X+ #define get_nibble(a) cpu.rom[a]
X+ #endif
X+
X typedef char Nybble;
X typedef unsigned long NAddr;
X
X***************
X*** 28,34 ****
X--- 38,46 ----
X char *AppendStr(char *buf, char *str);
X #else
X long GetInt();
X+ #ifndef MY48
X int get_nibble();
X+ #endif
X WORD20 Disassemble();
X NAddr Instruction_length();
X
X*** ../em48o/disasm.c Fri Mar 13 11:48:44 1992
X--- disasm.c Mon Mar 16 12:03:43 1992
X***************
X*** 76,81 ****
X--- 76,83 ----
X target = NOADDR;
X return Instruction(addr, istr);
X }
X+
X+ #ifndef MY48
X int
X #ifdef ANSI
X get_nibble(NAddr addr)
X***************
X*** 89,94 ****
X--- 91,100 ----
X else
X return cpu.rom[addr >> 1] & 0x0f;
X }
X+ #endif
X+
X+
X+
X
X long
X #ifdef ANSI
X*** ../em48o/dobj.c Fri Mar 13 11:48:44 1992
X--- dobj.c Wed Mar 18 11:19:44 1992
X***************
X*** 11,16 ****
X--- 11,19 ----
X Nybble n;
X #endif
X {
X+ #ifdef MY48
X+ mem[addr]=n&0x0f;
X+ #else
X char t;
X
X t = mem[addr >> 1] & ((addr & 1) ? 0x0f : 0xf0);
X***************
X*** 19,24 ****
X--- 22,28 ----
X n <<= 4;
X
X mem[addr >> 1] = t | n;
X+ #endif
X }
X
X #define NSIZE 524288
X*** ../em48o/em48.c Fri Mar 13 11:48:45 1992
X--- em48.c Mon Mar 16 12:03:43 1992
X***************
X*** 2,7 ****
X--- 2,10 ----
X /* Program to emulate the Saturn CPU and provide an emulation of */
X /* the HP48 on other machines. */
X /**********************************************************************/
X+ #ifdef MY48
X+ #define FILE_EM48
X+ #endif
X # include "hp48.h"
X # include "dis48.h"
X # include "proto.h"
X***************
X*** 299,304 ****
X--- 302,311 ----
X /* Get first two nibbles -- we always */
X /* need these. */
X /***********************************************/
X+ #ifdef MY48
X+ n1 = get_nibble(cpu.pc);
X+ n2 = get_nibble(cpu.pc+1);
X+ #else
X if (cpu.pc & 1) {
X n1 = cpu.rom[cpu.pc >> 1] >> 4;
X n2 = cpu.rom[(cpu.pc + 1) >> 1] & 0x0f;
X***************
X*** 307,312 ****
X--- 314,320 ----
X n1 = cpu.rom[cpu.pc >> 1] & 0x0f;
X n2 = cpu.rom[(cpu.pc + 1) >> 1] >> 4;
X }
X+ #endif
X /* n1 = get_nibble(cpu.pc);
X n2 = get_nibble(cpu.pc+1);*/
X
X***************
X*** 1397,1403 ****
X /* RESET */
X /***********************************************/
X cpu.pc += 3;
X! memset(cpu.configs, 0, sizeof cpu.configs);
X cpu.daisy_state = 0;
X if (io_flag & IO_CONFIG) {
X printf("%05lx: RESET [instr=%lx]\n", cpu.pc, cpu.instr_count);
X--- 1405,1411 ----
X /* RESET */
X /***********************************************/
X cpu.pc += 3;
X! memset((char *)cpu.configs, 0, sizeof cpu.configs);
X cpu.daisy_state = 0;
X if (io_flag & IO_CONFIG) {
X printf("%05lx: RESET [instr=%lx]\n", cpu.pc, cpu.instr_count);
X***************
X*** 1494,1500 ****
X /* map -- we need a mechanism to indicate */
X /* that a key is release. */
X /***********************************************/
X! memset(&cpu.keybuf, 0, sizeof cpu.keybuf);
X cpu.intr_pending = 0;
X /* cpu.ien = TRUE;*/
X if (io_flag & IO_OTHER) {
X--- 1502,1508 ----
X /* map -- we need a mechanism to indicate */
X /* that a key is release. */
X /***********************************************/
X! memset((char *)&cpu.keybuf, 0, sizeof cpu.keybuf);
X cpu.intr_pending = 0;
X /* cpu.ien = TRUE;*/
X if (io_flag & IO_OTHER) {
X*** ../em48o/get.c Fri Mar 13 11:48:46 1992
X--- get.c Wed Mar 18 11:20:47 1992
X***************
X*** 1,5 ****
X--- 1,6 ----
X #include "dis48.h"
X
X+ #ifndef MY48
X Nybble
X #ifdef ANSI
X get_nibble(NAddr addr)
X***************
X*** 16,21 ****
X--- 17,23 ----
X
X return(n & 0xf);
X }
X+ #endif
X
X int
X #ifdef ANSI
X*** ../em48o/hp48.h Fri Mar 13 11:48:49 1992
X--- hp48.h Mon Mar 16 11:53:30 1992
X***************
X*** 6,11 ****
X--- 6,17 ----
X /* Following macro used to allow compilation with ANSI C and */
X /* non-ANSI C compilers automatically. */
X /**********************************************************************/
X+ #ifdef MY48
X+ typedef unsigned char Nibble;
X+ #else
X+ typedef unsigned char Nibble;
X+ #endif
X+
X # if !defined(PROTO)
X # if defined(__STDC__) || defined(MSDOS)
X # define PROTO(x) x
X***************
X*** 179,186 ****
X int field_size; /* Used during address calculation. */
X int field_offset; /* Number of nibbles. */
X
X! unsigned char *rom;
X! unsigned char *ram;
X
X WORD20 ram_32k; /* Based on the CONFIG instruction */
X /* figure out where RAM is. */
X--- 185,192 ----
X int field_size; /* Used during address calculation. */
X int field_offset; /* Number of nibbles. */
X
X! Nibble *rom;
X! Nibble *ram;
X
X WORD20 ram_32k; /* Based on the CONFIG instruction */
X /* figure out where RAM is. */
X*** ../em48o/lcd.c Fri Mar 13 11:48:47 1992
X--- lcd.c Wed Mar 18 11:30:26 1992
X***************
X*** 39,45 ****
X /* Save old copy of LCD and just draw */
X /* ints which are different. */
X /***********************************************/
X! memcpy((char *) &old_lcd, (char *) &lcd, sizeof lcd);
X addr = read_nibbles(DABR, 5);
X menu_offset = read_nibbles(MENU_OFFSET, 2) & 0x3f;
X for (i = 0; i <= menu_offset; i++)
X--- 39,45 ----
X /* Save old copy of LCD and just draw */
X /* ints which are different. */
X /***********************************************/
X! memcpy((char *) old_lcd, (char *) lcd, sizeof lcd);
X addr = read_nibbles(DABR, 5);
X menu_offset = read_nibbles(MENU_OFFSET, 2) & 0x3f;
X for (i = 0; i <= menu_offset; i++)
X***************
X*** 64,70 ****
X--- 64,77 ----
X int row;
X { int i, v, col;
X
X+ #ifdef MY48
X+ int adp;
X+ char *p=&lcd[row].bits[0];
X+ for(i=BYTES_PER_ROW,adp=addr;--i>=0;adp+=2)
X+ *p++=cpu.ram[adp]|(cpu.ram[adp+1]<<4);
X+ #else
X memcpy(&lcd[row].bits[0], &cpu.ram[addr >> 1], BYTES_PER_ROW);
X+ #endif
X for (i = 0; i < BYTES_PER_ROW; i++) {
X v = lcd[row].bits[i];
X if (v != old_lcd[row].bits[i]) {
X***************
X*** 81,86 ****
X void
X clear_lcd()
X {
X! memset((char *) &lcd, 0, sizeof lcd);
X x11_clear();
X }
X--- 88,93 ----
X void
X clear_lcd()
X {
X! memset((char *) lcd, 0, sizeof lcd);
X x11_clear();
X }
X*** ../em48o/mmu.c Fri Mar 13 11:48:47 1992
X--- mmu.c Mon Mar 16 12:03:43 1992
X***************
X*** 23,28 ****
X--- 23,41 ----
X mode |= O_BINARY;
X # endif
X
X+ #ifdef MY48
X+ if ((n = open("bigrom", mode)) < 0) {
X+ perror("bigrom");
X+ exit(1);
X+ }
X+
X+ if ((cpu.rom = (unsigned char *) malloc(ROM_SIZE)) == (unsigned char *) NULL) {
X+ fprintf(stderr, "malloc failed\n");
X+ exit(1);
X+ }
X+ if (read(n, cpu.rom, ROM_SIZE) != ROM_SIZE)
X+ printf("Warning: incorrect ROM size\n");
X+ #else
X if ((n = open("rom", mode)) < 0) {
X perror("rom");
X exit(1);
X***************
X*** 34,47 ****
X }
X if (read(n, cpu.rom, ROM_SIZE / 2) != ROM_SIZE / 2)
X printf("Warning: incorrect ROM size\n");
X
X if ((cpu.ram = (unsigned char *) malloc(RAM_SIZE)) == (unsigned char *) NULL) {
X! fprintf(stderr, "Couldnt allocate memory for RAM\n");
X exit(1);
X }
X /* memset(cpu.ram, 0x54, RAM_SIZE);*/
X memset(cpu.ram + (0x100/2), 0, 64);
X!
X (void) close(n);
X }
X /**********************************************************************/
X--- 47,69 ----
X }
X if (read(n, cpu.rom, ROM_SIZE / 2) != ROM_SIZE / 2)
X printf("Warning: incorrect ROM size\n");
X+ #endif
X
X+ #ifdef MY48
X+ if ((cpu.ram = (Nibble *) malloc(RAM_SIZE*2*sizeof(Nibble)) ) == (Nibble *) NULL) {
X+ fprintf(stderr, "Couldn't allocate memory for RAM\n");
X+ exit(1);
X+ }
X+ memset(cpu.ram + 0x100*sizeof(Nibble), 0, 64*sizeof(Nibble));
X+ #else
X if ((cpu.ram = (unsigned char *) malloc(RAM_SIZE)) == (unsigned char *) NULL) {
X! fprintf(stderr, "Couldn't allocate memory for RAM\n");
X exit(1);
X }
X /* memset(cpu.ram, 0x54, RAM_SIZE);*/
X memset(cpu.ram + (0x100/2), 0, 64);
X! #endif
X!
X (void) close(n);
X }
X /**********************************************************************/
X***************
X*** 135,145 ****
X--- 157,171 ----
X return;
X }
X
X+ #ifdef MY48
X+ cpu.ram[addr]=(Nibble)val&0x0f;
X+ #else
X cp = (char *) &cpu.ram[addr >> 1];
X if (addr & 1)
X *cp = (char) ((*cp & 0x0f) | (val << 4));
X else
X *cp = (char) ((*cp & 0xf0) | val);
X+ #endif
X }
X
X /**********************************************************************/
X***************
X*** 252,261 ****
X--- 278,291 ----
X return (cpu.timer2 >> ((addr - 0x138) * 4)) & 0x0f;
X }
X
X+ #ifdef MY48
X+ val = cpu.ram[addr];
X+ #else
X if (addr & 1)
X val = (cpu.ram[addr >> 1] >> 4) & 0x0f;
X else
X val = cpu.ram[addr >> 1] & 0x0f;
X+ #endif
X if (do_crc && addr >= 0x200) {
X calc_crc(val);
X }
X*** ../em48o/proto.h Fri Mar 13 11:48:49 1992
X--- proto.h Fri Mar 13 11:57:39 1992
X***************
X*** 1,6 ****
X--- 1,8 ----
X int check_breakpoint PROTO((int, long));
X WORD64 *get_imm_nibble PROTO((long, int));
X+ #ifndef MY48
X int get_nibble PROTO((long));
X+ #endif
X int read_byte PROTO((long));
X int read_nibble PROTO((long));
X long read_nibbles PROTO((long, int));
END_OF_patches
if test 11208 -ne `wc -c <patches`; then
echo shar: \"patches\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mkbigrom.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"mkbigrom.c\"
else
echo shar: Extracting \"mkbigrom.c\" \(243 characters\)
sed "s/^X//" >mkbigrom.c <<'END_OF_mkbigrom.c'
X/* mkbigrom.c - takes input from "rom" image and outputs bigger rom image.
Xusage: mkbigrom <rom >bigrom
X*/
X#include <stdio.h>
X
Xmain()
X{
Xint c;
X
Xwhile(!feof(stdin))
X{
Xc=getc(stdin);
Xif (c==EOF) break;
Xputchar(c&0x0f);
Xputchar((c>>4)&0x0f);
X}
X}
END_OF_mkbigrom.c
if test 243 -ne `wc -c <mkbigrom.c`; then
echo shar: \"mkbigrom.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
>On the machines I have here, I get a modest performance increase from
>~66000 inst/sec to ~80000 instr/sec.
On our machine the performance went up by almost a factor of 2!
From 30000 to 50000
Thanbks for a great patch!
JC
--
___ __ ____________________________________________________________________
|/ \ Jan Christiaan van Winkel j...@phoibos.cs.kun.nl
| Alternative e-mail addresses: j...@oreo.atcmp.nl and j...@atcmp.nl
__/ \__/ ____________________________________________________________________