Commit 9008e02e authored by Michael Stolovitzsky's avatar Michael Stolovitzsky
Browse files

Initial commit

parents
bk
bin/
*.o
terakdisk
maketape
readtape
pngtorba
irps.log
everything
#
# This file is part of 'pdp', a PDP-11 simulator.
#
# For information contact:
#
# Computer Science House
# Attn: Eric Edwards
# Box 861
# 25 Andrews Memorial Drive
# Rochester, NY 14623
#
# Email: mag@potter.csh.rit.edu
# FTP: ftp.csh.rit.edu:/pub/csh/mag/pdp.tar.Z
#
# Copyright 1994, Eric A. Edwards
#
# Permission to use, copy, modify, and distribute this
# software and its documentation for any purpose and without
# fee is hereby granted, provided that the above copyright
# notice appear in all copies. Eric A. Edwards makes no
# representations about the suitability of this software
# for any purpose. It is provided "as is" without expressed
# or implied warranty.
#
# Makefile
#
#
#
# Change as needed
#
CC = gcc -std=gnu89
LD = gcc
CFLAGS = -g -DSHIFTS_ALLOWED -DEIS_ALLOWED
# CFLAGS = -O4 -fomit-frame-pointer # -DSHIFTS_ALLOWED
#
# Targets
#
TARGET = bk
UTILS = maketape readtape
#
# Source and Object Files
#
SRCS = access.c boot.c branch.c conf.c covox.c double.c ea.c itab.c \
main.c service.c ui.c scr.c timer.c tape.c disk.c mouse.c printer.c \
single.c weird.c tty.c io.c timing.c sound.c disas.c serial.c bkplip.c \
terakdisk.c synth.c emu2149.c
OBJS = access.o boot.o branch.o conf.o covox.o double.o ea.o itab.o icon.o \
main.o service.o ui.o scr.o timer.o tape.o disk.o mouse.o printer.o \
single.o weird.o tty.o io.o timing.o sound.o disas.o serial.o bkplip.o \
terakdisk.o synth.o emu2149.o
INCS = defines.h scr.h conf.h emu2149.h emutypes.h
USRCS = readtape.c maketape.c pngtorgba.c
TEXTS = README.html configure.in icon.c
#
# Build Rules
#
everything: $(TARGET) $(UTILS)
touch everything
.c.o:
$(CC) -c $(CFLAGS) $<
icon.c: pngtorgba bk.png
touch icon.c
if [ ! -s icon.c ] ; then ./pngtorgba bk.png > icon.c ; fi
$(TARGET): $(OBJS)
$(LD) $(CFLAGS) -o $(TARGET) $(OBJS) /usr/lib/x86_64-linux-gnu/libSDL.so -lpthread
readtape: readtape.c
$(CC) $(CFLAGS) -o readtape readtape.c
maketape: maketape.c
$(CC) $(CFLAGS) -o maketape maketape.c
#
# Cool Utilities
#
clean:
rm -f $(TARGET) $(OBJS) $(UTILS) everything
count:
wc -l $(SRCS) $(USRCS)
dist:
tar czvf bk-terak-emu.`date +%Y.%m.%d`.tar.gz \
--exclude CVS $(SRCS) $(INCS) $(USRCS) po Rom $(TEXTS) Makefile bk.png
depend:
makedepend -Dlinux=1 -Y $(SRCS) $(USRCS) $(INCS)
# DO NOT DELETE
access.o: defines.h
boot.o: defines.h
branch.o: defines.h
conf.o: conf.h defines.h scr.h
covox.o: defines.h
double.o: defines.h
ea.o: defines.h
itab.o: defines.h
main.o: defines.h scr.h
service.o: defines.h
ui.o: defines.h
scr.o: defines.h scr.h
timer.o: defines.h
tape.o: defines.h
disk.o: defines.h
mouse.o: defines.h
printer.o: defines.h
single.o: defines.h
weird.o: defines.h
tty.o: defines.h
io.o: defines.h
timing.o: defines.h
sound.o: defines.h
disas.o: defines.h
serial.o: defines.h
bkplip.o: defines.h
terakdisk.o: defines.h
synth.o: defines.h emu2149.h emutypes.h
emu2149.o: emu2149.h emutypes.h
conf.o: defines.h
emu2149.o: emutypes.h
<html><head>
<meta http-equiv="content-type" content="text/html;charset=koi8-r">
</head>
<body><pre>
-0010 ( -0010,
-0011()) ԣ
PDP-11, :
Copyright 1994, Eric A. Edwards
Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without
fee is hereby granted, provided that the above copyright
notice appear in all copies. Eric A. Edwards makes no
representations about the suitability of this software
for any purpose. It is provided "as is" without expressed
or implied warranty.
:
SDL (www.libsdl.org).
1.2.5.
gcc ( 3.2.2) .
, ,
maketape readtape, PATH.
.
(*.ROM, ,
) /usr/share/bk,
, BK_PATH.
,
.
:
-a -
-n - (no noise)
-f - full speed ( )
-f, -n,
-c -
-D -
-l - (, LLIST ) "",
,
,
-R - ROM 120000 ( -
, ,
); -R
16K RAM 120000-157777.
-r - ROM 160000
-c -D , ..
Scroll Lock.
: 2 Alt- (
), Win- (
Ctrl Alt), , KeySym LSuper.
( .bin, .. 2 , 2 , )
"-" (.
) - ,
16 ,
F12. ,
, NAME?
.
"-" (, SAVE CSAVE )
.bin ( ,
, )
(, , ,
).
, ,
"" .
:
2003-09-28: -0011 ,
( , ,
..)
2003-09-17:
, .
-. ( -m,
; / -
).
2003-09-15: -
326 327.
2003-09-10: ( )
.
-DFAKE_TAPE.
2003-09: - , BKDEMO .
reset ( 100000):
2 + F11.
Leo
</pre></body></html>
BK emulator
-----------
DISCLAIMER
==========
I (emestee@catnarok.net) am not the author of this software. The original code for the PDP11 emulator was
written by Eric A. Edwards in 1994. It was then modified by Leonid A. Broukhis to support the Soviet BK-0010,
BK-0010.01 and BK-0011(M).
The original license statement in Eric A. Edwards' source code is as follows:
> Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is
> hereby granted, provided that the above copyright notice appear in all copies. Eric A. Edwards makes no representations
> about the suitability of this software for any purpose. It is provided "as is" without expressed or implied warranty.
Leonid A. Broukhis preserved this license in his source code, and therefore this is free software.
My hat is off before these two gentlemen.
What is this?
-------------
This software is a Linux/SDL emulator for Soviet (russian) Electronica BK series:
* БК-0010
* БК-0010.01
* БК-0011(М)
You may read more about the series at http://en.wikipedia.org/wiki/Electronika_BK
Additionally, it supports emulation of Terak 8510/a, which is a 1976 american PDP-11/03 platform and of which
the Electronica BK series are indeed clones.
The Electronica BK computers were the first mass produced, affordable personal computers in Russia in the eighties of 20th century,
and have had tremendous effect on the development of Russian-speaking software community. Every russian computer, hardware or ham radio
geek born in seventies or eighties probably had one of those machines during their formational years. They are the C64s, ZX Spectrums
and Atari 2600s of the now defunct USSR.
I have discovered this software by accident, and I am publishing it to github in order to preserve it.
**All of the BK machines accept console commands in English, but respond mostly in Russian. Most of the software written for
these machines would also interact in Russian. Unless you are a native Russian speaker, or very curious about this technology,
this software is probably of very little use to you**
The version of the emulator published in this repository is derived from "BK-Terak-Emu 2005.08.26".tar.gz file. I do not know
if a more up to date version was ever made, or has been preserved. The original file is included unmodified in this repository.
The only alteration I made to the repository is a change to the Makefile to point the linker to libSDL as it appears on
modern x64 machines.
Virtually all of BK schematics, documentation, hardware hacks and software has been preserved and is available on the internet.
Unfortunately, most if not all of these things are in Russian.
Compilation and use
-------------------
This is very old software, but as all good C code, it works ten and twenty years thereafter. I have successfully compiled it,
booted a BK-0010.01 machine and played a game under Ubuntu 13.05, Linux 3.8.5 and libSDL 1.2.
* Edit the Makefile to correct the path to your libSDL.so
* Run `make`
* Run `./bk -?` for overview of emulation modes
For instance, to run BK-0010.01 emulation, execute
`./bk -1 -c`
When the emulation is running, you can issue a Ctrl-C in the emulator's console. This will stop the emulation and drop
you into the emulator's debugger. To load a game from a binary file (assuming you have one, none are distributed here), do:
`l <filename>` (the emulator will look for the file in /usr/share/bk)
`g 1000`
Please feel free to contact me if you are curious about this. I will do my best to try and answer your questions.
File added
File added
File added
/*
* This file is part of a BK-0010/11M simulator.
* Originally
* Copyright 1994, Eric A. Edwards
* After heavy modifications
* Copyright 1995-2003 Leonid A. Broukhis
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notices appear in all copies. Leonid A. Broukhis makes no
* representations about the suitability of this software
* for any purpose. It is provided "as is" without expressed
* or implied warranty.
*/
/*
* access.c - Access routines to read and write loactions on the QBUS
* and main memory.
*/
#include "defines.h"
#include <libintl.h>
#define _(String) gettext (String)
/*
* BK-0011 has 8 8Kw RAM pages and 4 8 Kw ROM pages.
* RAM pages 1 and 7 are video RAM.
*/
d_word ram[8][8192];
d_word rom[4][8192];
d_word system_rom[8192];
unsigned char umr[65536];
/*
* Page mapping, per 8 Kw page. Default is a mapping mimicking BK-0010
*/
d_word * pagemap[4] = { ram[6], ram[1], rom[0], system_rom };
#define mem(x) pagemap[(x)>>14][((x) & 037777) >> 1]
/*
* Each bit corresponds to a Kword,
* the lowest 8 Kwords are RAM, the next 8 are screen memory,
* the rest is usually ROM.
*/
unsigned long pdp_ram_map = 0x0000ffff;
unsigned long pdp_mem_map;
#define IS_RAM_ADDRESS(x) ((pdp_ram_map >> ((x) >> 11)) & 1)
#define IS_VALID_ADDRESS(x) ((pdp_mem_map >> ((x) >> 11)) & 1)
/*
* The QBUS memory map.
*/
int q_null(), q_err(c_addr, d_word), q_errb(c_addr, d_byte),
port_read(c_addr, d_word*), port_write(c_addr, d_word), port_bwrite(c_addr, d_byte);
int secret_read(c_addr, d_word*), secret_write(c_addr, d_word), secret_bwrite(c_addr, d_byte);
int force_read( c_addr, d_word*), terak_read(c_addr, d_word*);
typedef struct {
c_addr start;
c_addr size;
int (*ifunc)();
int (*rfunc)(c_addr, d_word*);
int (*wfunc)(c_addr, d_word);
int (*bwfunc)(c_addr, d_byte);
} pdp_qmap;
pdp_qmap qmap_bk[] = {
{ PORT_REG, PORT_SIZE, q_null, port_read, port_write, port_bwrite },
{ TTY_REG, TTY_SIZE, tty_init, tty_read, tty_write, tty_bwrite },
{ IO_REG, IO_SIZE, io_init, io_read, io_write, io_bwrite },
{ TIMER_REG, TIMER_SIZE, timer_init, timer_read, timer_write, timer_bwrite },
/* Line registers are available even if BASIC is mapped */
{ LINE_REG, LINE_SIZE, line_init, line_read, line_write, line_bwrite },
/* BASIC memory is not transparently readable, thus force_read */
{ BASIC, BASIC_SIZE, q_null, force_read, q_err, q_errb },
/* disk ports can only be available if there is no BASIC */
{ DISK_REG, DISK_SIZE, disk_init, disk_read, disk_write, disk_bwrite },
{ SECRET_REG, SECRET_SIZE, q_null, secret_read, secret_write, secret_bwrite },
{ 0, 0, 0, 0, 0, 0 }
};
tcons_read(c_addr a, d_word *d) {
switch (a & 077) {
case 064:
*d = 0200;
break; // done
case 066:
fprintf(stderr, "Reading %06o\n", a);
*d = 0;
break; // nothing
}
return OK;
}
tcons_write(c_addr a, d_word d) {
switch (a & 077) {
case 064:
fprintf(stderr, "Writing %06o: %06o\n", a, d);
break;
case 066:
// fprintf(stderr, "Writing %03o to console port %06o\n", d, a);
if (d != '\n' && d < 32 || d >= 127)
fprintf(stderr, "<%o>", d);
else
fprintf(stderr, "%c", d);
break;
}
return OK;
}
pdp_qmap qmap_terak[] = {
{ TERAK_DISK_REG, TERAK_DISK_SIZE, tdisk_init, tdisk_read,
tdisk_write, tdisk_bwrite },
{ 0177564, 4, q_null, tcons_read, tcons_write, tcons_write },
{ 0177764, 4, q_null, tcons_read, tcons_write, tcons_write },
{ 0177744, 2, q_null, port_read, port_write, port_bwrite },
{ 0177560, 2, q_null, port_read, port_write, port_bwrite },
{ 0173000, 0200, q_null, terak_read, q_err, q_errb },
{ 0, 0, 0, 0, 0, 0 }
};
pdp_qmap * qmap = qmap_bk;
pdp_qmap q_printer = {
PORT_REG, PORT_SIZE, printer_init, printer_read, printer_write, printer_bwrite
};
pdp_qmap q_mouse = {
PORT_REG, PORT_SIZE, mouse_init, mouse_read, mouse_write, mouse_bwrite
};
pdp_qmap q_covox = {
PORT_REG, PORT_SIZE, covox_init, covox_read, covox_write, covox_bwrite
};
pdp_qmap q_synth = {
PORT_REG, PORT_SIZE, synth_init, synth_read, synth_write, synth_bwrite
};
pdp_qmap q_bkplip = {
PORT_REG, PORT_SIZE, bkplip_init, bkplip_read, bkplip_write, bkplip_bwrite
};
void plug_printer() { qmap[0] = q_printer; }
void plug_mouse() { qmap[0] = q_mouse; }
void plug_covox() { qmap[0] = q_covox; }
void plug_synth() { qmap[0] = q_synth; }
void plug_bkplip() { qmap[0] = q_bkplip; }
/* When nothing is connected to the port */
int port_read(c_addr a, d_word *d) {
*d = 0; /* pulldown */
fprintf(stderr, "Reading port %06o\n", a);
return OK;
}
int port_write(c_addr a, d_word d) {
fprintf(stderr, "Writing %06o to port %06o\n", d, a);
return OK; /* goes nowhere */
}
int port_bwrite(c_addr a, d_byte d) {
fprintf(stderr, "Writing %03o to port %06o\n", d, a);
return OK; /* goes nowhere */
}
secret_read(addr, word)
c_addr addr;
d_word *word;
{
d_word offset = addr - SECRET_REG;
switch(offset) {
case 0: /* 177700 */
*word = 0177400;
fprintf(stderr, "Reading 0177700\n");
break;
case 2: /* 177702 */
fprintf(stderr, "Reading 0177702\n");
*word = 0177777;
break;
case 4: /* 177704 */
fprintf(stderr, "Reading 0177704\n");
*word = 0;
}
return OK;
}
int secret_write(c_addr a, d_word d) {
fprintf(stderr, "Writing %o to %o\n", d, a);
return OK; /* goes nowhere */
}
int secret_bwrite(c_addr a, d_byte d) {
fprintf(stderr, "Writing %o to %o\n", d, a);
return OK; /* goes nowhere */
}
/*
* lc_word() - Load a word from the given core address.
*/
int
lc_word( addr, word )
c_addr addr;
d_word *word;
{
int i;
addr &= ~1;
if ( IS_VALID_ADDRESS(addr)) {
if (!umr[addr]) {
// fprintf(stderr, "UMR @ %06o\n", addr);
}
*word = mem(addr);
return OK;
}
for ( i = 0; qmap[i].start; ++i ) {
if (( addr >= qmap[i].start ) &&
( addr < ( qmap[i].start + (qmap[i].size *2 )))) {
return (qmap[i].rfunc)( addr, word );
}
}
fprintf(stderr, _("Illegal read address %06o:"), addr);
return BUS_ERROR;
}
int
force_read(c_addr addr, d_word *word )
{
*word = mem(addr);
return OK;
}
int
terak_read(c_addr addr, d_word *word )
{
if (addr == 0173176) fprintf(stderr, "Reading serial num\n");
if (addr >= 0173000 && addr < 0173200) {
*word = mem(addr);
return OK;
}
return BUS_ERROR;
}
/*
* If the address corresponds to a video page (1 or 2)
* returns 1 or 2, otherwise 0.
*/
unsigned char video_map[4] = { 0, 1, 0, 0};
#define VIDEO_PAGE(x) video_map[(x)>>14]
/*
* bits 14-12 - page mapped to addresses 040000-077777
* bits 10-8 - page mapped to addresses 100000-137777
* bit 0 - ROM 0 mapped to addresses 100000-137777
* bit 1 - ROM 1 mapped to addresses 100000-137777
* bit 3 - ROM 2 mapped to addresses 100000-137777
* bit 4 - ROM 3 mapped to addresses 100000-137777
*/
static d_word oldmap;
void pagereg_write(d_word word) {
if (oldmap == word) return;
oldmap = word;
pagemap[1] = ram[(word >> 12) & 7];
pagemap[2] = ram[(word >> 8) & 7];
switch (word & 033) {
case 000:
pdp_ram_map |= 0x00ff0000;
pdp_mem_map |= 0x00ff0000;
break;
case 001:
pagemap[2] = rom[0];
pdp_ram_map &= 0xff00ffff;
pdp_mem_map |= 0x00ff0000;
break;
case 002:
pagemap[2] = rom[1];
pdp_ram_map &= 0xff00ffff;
pdp_mem_map |= 0x00ff0000;
break;
case 010:
pagemap[2] = rom[2];
pdp_ram_map &= 0xff00ffff;
pdp_mem_map &= 0xff00ffff;
break;
case 020:
pagemap[2] = rom[3];
pdp_ram_map &= 0xff00ffff;
pdp_mem_map &= 0xff00ffff;
break;
default: fprintf(stderr, "Bad ROM map %o\n", word & 033);
}
video_map[1] = video_map[2] = 0;
if (pagemap[1] == ram[1]) video_map[1] = 1;
else if (pagemap[1] == ram[7]) video_map[1] = 2;
if (pagemap[2] == ram[1]) video_map[2] = 1;