Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

em48 patches to use lots of RAM

2 views
Skip to first unread message

Arthur Tateishi

unread,
Mar 20, 1992, 7:52:15 PM3/20/92
to
OK, here are my changes to the posted em48. Hopefully, Paul can
consider incorporating them into his version.
I've placed all the code within conditional compilation statements
to allow it to be selected/deselected.
On the machines I have here, I get a modest performance increase from
~66000 inst/sec to ~80000 instr/sec.
This only changes rom and ram nibbles to be char's.

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

Jan Christiaan van Winkel

unread,
Mar 23, 1992, 8:54:55 AM3/23/92
to

>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
__/ \__/ ____________________________________________________________________

0 new messages