diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b00b596 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +SRC=main.c apr.c mem.c +CFLAGS=-Wno-shift-op-parentheses -Wno-logical-op-parentheses\ + -L/usr/local/lib -I/usr/local/include -lSDL -lSDL_image -lpthread +pdp6: $(SRC) pdp6.h + $(CC) $(CFLAGS) $(SRC) -o pdp6 diff --git a/apr.c b/apr.c new file mode 100644 index 0000000..7656711 --- /dev/null +++ b/apr.c @@ -0,0 +1,506 @@ +#include "pdp6.h" + +typedef void *Pulse(void); +#define pulse(p) void *p(void) + +/* external pulses: + * KEY MANUAL + * MAI-CMC ADDR ACK + * MAI RD RS + */ + +Apr apr; +int extpulse; +Pulse *nextpulse; +Pulse *mc_rst1_ret; + +void +set_ex_mode_sync(bool value) +{ + apr.ex_mode_sync = value; + if(apr.ex_mode_sync) + apr.ex_user = 1; // 5-13 +} + +void +set_pi_cyc(bool value) +{ + apr.pi_cyc = value; + if(!apr.pi_cyc) + apr.ex_pi_sync = 1; // 5-13 +} + +void +set_mc_rq(bool value) +{ + apr.mc_rq = value; // 7-9 + if(value && (apr.mc_rd || apr.mc_wr)){ + membus0 |= MEMBUS_RQ_CYC; + wakemem(); + }else + membus0 &= ~MEMBUS_RQ_CYC; +} + +void +set_mc_wr(bool value) +{ + apr.mc_wr = value; // 7-9 + if(value) + membus0 |= MEMBUS_WR_RQ; + else + membus0 &= ~MEMBUS_WR_RQ; + set_mc_rq(apr.mc_rq); +} + +void +set_mc_rd(bool value) +{ + apr.mc_rd = value; // 7-9 + if(value) + membus0 |= MEMBUS_RD_RQ; + else + membus0 &= ~MEMBUS_RD_RQ; + set_mc_rq(apr.mc_rq); +} + +void +set_key_rim_sbr(bool value) +{ + apr.key_rim_sbr = value | apr.sw_rim_maint; // 5-2 +} + +bool +calcaddr(void) +{ + u8 ma18_25; + bool ma_ok, ma_fmc_select; + + // 5-13 + apr.ex_inh_rel = !apr.ex_user || apr.ex_pi_sync || + (apr.ma&0777760) == 0 || apr.ex_ill_op; + // 7-4 + ma18_25 = apr.ma>>10 & 0377; + ma_ok = ma18_25 <= apr.pr; + // 7-2 + ma_fmc_select = !apr.key_rim_sbr && (apr.ma&0777760) == 0; + // 7-5 + apr.rla = ma18_25; + if(!apr.ex_inh_rel) + apr.rla += apr.rlr; + + membus0 &= ~0007777777761; + membus0 |= ma_fmc_select ? MEMBUS_MA_FMC_SEL1 : MEMBUS_MA_FMC_SEL0; + membus0 |= (apr.ma&01777) << 4; + membus0 |= (apr.rla&017) << 14; + membus0 |= apr.rla & 0020 ? MEMBUS_MA21_1|MEMBUS_MA21 : MEMBUS_MA21_0; + membus0 |= apr.rla & 0040 ? MEMBUS_MA20_1 : MEMBUS_MA20_0; + membus0 |= apr.rla & 0100 ? MEMBUS_MA19_1 : MEMBUS_MA19_0; + membus0 |= apr.rla & 0200 ? MEMBUS_MA18_1 : MEMBUS_MA18_0; + membus0 |= apr.ma & 01 ? MEMBUS_MA35_1 : MEMBUS_MA35_0; + return ma_ok; +} + +pulse(kt4); +pulse(mc_wr_rs); + +// TODO: find PI REQ, A LONG + +pulse(pi_reset){ + printf("PI RESET\n"); + apr.pi_active = 0; // 8-4 + apr.pih = 0; // 8-4 + apr.pir = 0; // 8-4 + apr.pio = 0; // 8-3 + return NULL; +} + +pulse(ar_flag_clr){ + printf("AR FLAG CLR\n"); + apr.pc_chg_flag = 0; // 6-10 + apr.ar_ov_flag = 0; // 6-10 + apr.ar_cry0_flag = 0; // 6-10 + apr.ar_cry1_flag = 0; // 6-10 + apr.chf7 = 0; // 6-19 + return NULL; +} + +pulse(mr_clr){ + printf("MR CLR\n"); + apr.ir = 0; // 5-7 + apr.mq = 0; // 6-13 + apr.sc = 0; // 6-15 + apr.fe = 0; // 6-15 + + apr.mc_rd = 0; // 7-9 + apr.mc_wr = 0; // 7-9 + apr.mc_rq = 0; // 7-9 + apr.mc_stop = 0; // 7-9 + apr.mc_stop_sync = 0; // 7-9 + apr.mc_split_cyc_sync = 0; // 7-9 + + set_ex_mode_sync(0); // 5-13 + apr.ex_uuo_sync = 0; // 5-13 + apr.ex_pi_sync = 0; // 5-13 + // TODO: MP CLR, DS CLR + + /* sbr flip-flops */ + apr.key_rd_wr = 0; // 5-2 + mc_rst1_ret = NULL; + return NULL; +} + +pulse(mr_start){ + printf("MR START\n"); + // IOB RESET + apr.cpa_iot_user = 0; // 8-5 + apr.cpa_illeg_op = 0; // 8-5 + apr.cpa_non_exist_mem = 0; // 8-5 + apr.cpa_clock_en = 0; // 8-5 + apr.cpa_clock_flag = 0; // 8-5 + apr.cpa_pc_chg_en = 0; // 8-5 + apr.cpa_pdl_ov = 0; // 8-5 + apr.cpa_arov_en = 0; // 8-5 + apr.cpa_pia33 = 0; // 8-5 + apr.cpa_pia34 = 0; // 8-5 + apr.cpa_pia35 = 0; // 8-5 + apr.pi_ov = 0; // 8-4 + set_pi_cyc(0); // 8-4 + pi_reset(); // 8-4 + ar_flag_clr(); // 6-10 + apr.ex_user = 0; // 5-13 + apr.ex_ill_op = 0; // 5-13 + apr.pr = 0; // 5-13, 7-4 + apr.rlr = 0; // 5-13, 7-5 + apr.rla = 0; + +// apr.ex_user = 1; +// apr.rlr = 2; +// apr.pr = 1; + return NULL; +} + +pulse(mr_pwr_clr){ + printf("MR PWR CLR\n"); + apr.run = 0; // 5-1 + /* order matters because of EX PI SYNC */ + mr_start(); // 5-2 + mr_clr(); // 5-2 + return NULL; +} + +pulse(st7){ + printf("ST7\n"); + return NULL; +} + +pulse(it1a){ + printf("IT1A\n"); + return NULL; +} + +/* + * Memory Control + */ + +pulse(mc_rs_t1){ + printf("MC RS T1\n"); + set_mc_rd(0); + if(apr.key_ex_next || apr.key_dep_next) + apr.mi = apr.mb; // 7-7 + return mc_rst1_ret; +} + +pulse(mc_rs_t0){ + printf("MC RS T0\n"); + apr.mc_stop = 0; + return mc_rs_t1; +} + +pulse(mc_wr_rs){ + printf("MC WR RS\n"); + if(apr.ma == apr.mas) + apr.mi = apr.mb; // 7-7 + membus1 = apr.mb; + membus0 |= MEMBUS_MAI_WR_RS; + wakemem(); + if(!apr.mc_stop) + return mc_rs_t0; + return NULL; +} + +pulse(mc_addr_ack){ + printf("MC ADDR ACK\n"); + set_mc_rq(0); + if(!apr.mc_rd && apr.mc_wr) + return mc_wr_rs; + return NULL; +} + +pulse(mc_non_exist_rd){ + printf("MC NON EXIST RD\n"); + if(!apr.mc_stop) + return mc_rs_t0; + return NULL; +} + +pulse(mc_non_exist_mem_rst){ + printf("MC NON EXIST MEM RST\n"); + if(apr.mc_rd){ + /* call directly - no other pulses after it in this case */ + mc_addr_ack(); + return mc_non_exist_rd; + }else + return mc_addr_ack(); + return NULL; +} + +pulse(mc_non_exist_mem){ + printf("MC NON EXIST MEM\n"); + apr.cpa_non_exist_mem = 1; + // TODO: IOB PI REQ CPA PIA + if(!apr.sw_mem_disable) + return mc_non_exist_mem_rst; + return NULL; +} + +pulse(mc_illeg_address){ + printf("MC ILLEG ADDRESS\n"); + apr.cpa_illeg_op = 1; + // TODO: IOB PI REQ CPA PIA + return st7; +} + +pulse(mc_rq_pulse){ + printf("MC RQ PULSE\n"); + apr.mc_stop = 0; // 7-9 + /* catch non-existent memory */ + extpulse |= 4; + if(calcaddr() == 0 && !apr.ex_inh_rel) + return mc_illeg_address; + set_mc_rq(1); + if(apr.key_mem_stop || apr.ma == apr.mas && apr.sw_addr_stop){ + apr.mc_stop = 1; // 7-9 + // TODO: what is this? does it make any sense? + if(apr.key_mem_cont) + return kt4; + } + return NULL; +} + +pulse(mc_rdwr_rq_pulse){ + printf("MC RD/RW RQ PULSE\n"); + set_mc_rd(1); // 7-9 + set_mc_wr(1); // 7-9 + apr.mb = 0; + apr.mc_stop_sync = 1; // 7-9 + return mc_rq_pulse; +} + +pulse(mc_rd_rq_pulse){ + printf("MC RD RQ PULSE\n"); + set_mc_rd(1); // 7-9 + set_mc_wr(0); // 7-9 + apr.mb = 0; + return mc_rq_pulse; +} + +pulse(mc_split_rd_rq){ + printf("MC SPLIT RD RQ\n"); + return mc_rd_rq_pulse; +} + +pulse(mc_wr_rq_pulse){ + printf("MC WR RQ PULSE\n"); + set_mc_rd(0); // 7-9 + set_mc_wr(1); // 7-9 + return mc_rq_pulse; +} + +pulse(mc_split_wr_rq){ + printf("MC SPLIT WR RQ\n"); + return mc_wr_rq_pulse; +} + +pulse(mc_rd_wr_rs_pulse){ + printf("MC RD/WR RS PULSE\n"); + return apr.mc_split_cyc_sync ? mc_split_wr_rq : mc_wr_rs; +} + +/* + * Keys + */ + +pulse(key_rd_wr_ret){ + printf("KEY RD WR RET\n"); + apr.key_rd_wr = 0; // 5-2 +// apr.ex_ill_op = 0; // ?? not found on 5-13 + return kt4; // 5-2 +} + +pulse(key_rd){ + printf("KEY RD\n"); + apr.key_rd_wr = 1; // 5-2 + mc_rst1_ret = key_rd_wr_ret; + return mc_rd_rq_pulse; +} + +pulse(key_wr){ + printf("KEY WR\n"); + apr.key_rd_wr = 1; // 5-2 + apr.mb = apr.ar; // 6-3 + mc_rst1_ret = key_rd_wr_ret; + return mc_wr_rq_pulse; +} + +pulse(key_go){ + printf("KEY GO\n"); + apr.run = 1; + apr.key_ex_st = 0; + apr.key_dep_st = 0; + apr.key_ex_sync = 0; + apr.key_dep_sync = 0; + return NULL; +} + +pulse(kt4){ + printf("KT4\n"); + if(apr.run && + (apr.key_ex || apr.key_ex_next || apr.key_dep || apr.key_dep_next)) + return key_go; // 5-2 + // TODO check repeat switch + return NULL; +} + +pulse(kt3){ + printf("KT3\n"); + if(apr.key_readin || apr.key_start) + apr.pc = apr.ma; // 5-12 + if(apr.key_execute && !apr.run){ + apr.mb = apr.ar; // 6-3 + // TODO: go to KT4 to check repeat (when processor is idle) + return it1a; // 5-3 + } + if(apr.key_ex || apr.key_ex_next) + return key_rd; // 5-2 + if(apr.key_dep || apr.key_dep_next) + return key_wr; // 5-2 + if(apr.key_start || apr.key_readin || apr.key_inst_cont) + return key_go; // 5-4 + return NULL; +} + +#define KEY_MANUAL (apr.key_readin || apr.key_start || apr.key_inst_cont ||\ + apr.key_mem_cont || apr.key_ex || apr.key_dep ||\ + apr.key_ex_next || apr.key_dep_next || apr.key_execute ||\ + apr.key_io_reset) + +pulse(kt12){ + printf("KT1,2\n"); + if(apr.key_io_reset) + mr_start(); // 5-2 + if(KEY_MANUAL && !apr.key_mem_cont) + mr_clr(); // 5-2 + if(!(apr.key_readin || apr.key_inst_cont || apr.key_mem_cont)) + set_key_rim_sbr(0); // 5-2 + + if(apr.key_readin){ + set_key_rim_sbr(1); // 5-2 + apr.ma = apr.mas; + } + if(apr.key_start) + apr.ma = apr.mas; + if(apr.key_execute && !apr.run) + apr.ar = apr.data; + if(apr.key_ex) + apr.ma = apr.mas; + if(apr.key_ex_next) + apr.ma = (apr.ma+1)&0777777; + if(apr.key_dep){ + apr.ma = apr.mas; + apr.ar = apr.data; + } + if(apr.key_dep_next){ + apr.ma = (apr.ma+1)&0777777; + apr.ar = apr.data; + } + + if(apr.key_mem_cont && apr.mc_stop) + return mc_rs_t0; + if(KEY_MANUAL && apr.mc_stop && apr.mc_stop_sync && !apr.key_mem_cont){ + /* Finish rd/wr which should stop the processor. + * Set flag to continue at KT3 */ + extpulse |= 2; + return mc_wr_rs; + } + return kt3; // 5-2 +} + +pulse(kt0a){ + printf("KT0A\n"); + apr.key_ex_st = 0; // 5-1 + apr.key_dep_st = 0; // 5-1 + apr.key_ex_sync = apr.key_ex || apr.key_ex_next; // 5-1 + apr.key_dep_sync = apr.key_dep || apr.key_dep_next; // 5-1 + if(!apr.run || apr.key_mem_cont) + return kt12; // 5-2 + return NULL; +} + +pulse(kt0){ + printf("KT0\n"); + return kt0a; // 5-2 +} + +pulse(key_manual){ + printf("KEY MANUAL\n"); + return kt0; // 5-2 +} + +pulse(mai_addr_ack){ + printf("MAI ADDR ACK\n"); + return mc_addr_ack; +} + +pulse(mai_rd_rs){ + printf("MAI RD RS\n"); + apr.mb = membus1; + if(apr.ma == apr.mas) + apr.mi = apr.mb; // 7-7 + if(!apr.mc_stop) + return mc_rs_t0; + return NULL; +} + +void* +aprmain(void *p) +{ + mr_pwr_clr(); + while(apr.sw_power){ + if(extpulse & 1){ + if(nextpulse) + printf("whaa: cpu wasn't idle\n"); + extpulse &= ~1; + nextpulse = key_manual; + } + if(nextpulse) + nextpulse = nextpulse(); + else if(membus0 & MEMBUS_MAI_ADDR_ACK){ + membus0 &= ~MEMBUS_MAI_ADDR_ACK; + extpulse &= ~4; + nextpulse = mai_addr_ack; + }else if(membus0 & MEMBUS_MAI_RD_RS){ + membus0 &= ~MEMBUS_MAI_RD_RS; + nextpulse = mai_rd_rs; + }else if(extpulse & 2){ + /* continue at KT3 after finishing rd/wr from a stop */ + extpulse &= ~2; + nextpulse = kt3; + }else if(extpulse & 4){ + extpulse &= ~4; + if(apr.mc_rq && !apr.mc_stop) + nextpulse = mc_non_exist_mem; + } + } + printf("power off\n"); + return NULL; +} diff --git a/extra_panel.png b/extra_panel.png new file mode 100644 index 0000000..bd1ec02 Binary files /dev/null and b/extra_panel.png differ diff --git a/ind_panel.png b/ind_panel.png new file mode 100644 index 0000000..0c1a40c Binary files /dev/null and b/ind_panel.png differ diff --git a/key_d.png b/key_d.png new file mode 100644 index 0000000..4f531fa Binary files /dev/null and b/key_d.png differ diff --git a/key_n.png b/key_n.png new file mode 100644 index 0000000..1d1a4d0 Binary files /dev/null and b/key_n.png differ diff --git a/key_u.png b/key_u.png new file mode 100644 index 0000000..2a00b00 Binary files /dev/null and b/key_u.png differ diff --git a/lamp_off.png b/lamp_off.png new file mode 100644 index 0000000..b9e0d9c Binary files /dev/null and b/lamp_off.png differ diff --git a/lamp_on.png b/lamp_on.png new file mode 100644 index 0000000..ed58b8f Binary files /dev/null and b/lamp_on.png differ diff --git a/main.c b/main.c new file mode 100644 index 0000000..2581740 --- /dev/null +++ b/main.c @@ -0,0 +1,863 @@ +#include "pdp6.h" +#include +#include +#include + +SDL_Surface *screen; + +SDL_Surface *keysurf[3]; +SDL_Surface *lampsurf[2]; +SDL_Surface *switchsurf[2]; + +typedef struct Key Key; +struct Key { + SDL_Surface **surfs; + SDL_Rect r; + int state; +}; + +typedef struct Light Light; +struct Light { + SDL_Surface **surfs; + SDL_Rect r; + int state; +}; + +typedef struct Switch Switch; +struct Switch { + SDL_Surface **surfs; + SDL_Rect r; + int state; + int active; /* mouse down */ +}; + +Key keys[] = { + { keysurf, { 646, 139, 18, 32 }, 0 }, + { keysurf, { 714, 139, 18, 32 }, 0 }, + { keysurf, { 782, 139, 18, 32 }, 0 }, + { keysurf, { 850, 139, 18, 32 }, 0 }, + { keysurf, { 918, 139, 18, 32 }, 0 }, + { keysurf, { 985, 139, 18, 32 }, 0 }, + { keysurf, { 1051, 139, 18, 32 }, 0 }, + { keysurf, { 1117, 139, 18, 32 }, 0 }, +}; + +Light op_lights[] = { + /* IR */ + { lampsurf, { 79, 43, 12, 12 }, 0 }, + { lampsurf, { 93, 43, 12, 12 }, 0 }, + { lampsurf, { 107, 43, 12, 12 }, 0 }, + { lampsurf, { 122, 43, 12, 12 }, 0 }, + { lampsurf, { 136, 43, 12, 12 }, 0 }, + { lampsurf, { 150, 43, 12, 12 }, 0 }, + { lampsurf, { 165, 43, 12, 12 }, 0 }, + { lampsurf, { 179, 43, 12, 12 }, 0 }, + { lampsurf, { 193, 43, 12, 12 }, 0 }, + { lampsurf, { 208, 43, 12, 12 }, 0 }, + { lampsurf, { 222, 43, 12, 12 }, 0 }, + { lampsurf, { 236, 43, 12, 12 }, 0 }, + { lampsurf, { 250, 43, 12, 12 }, 0 }, + { lampsurf, { 265, 43, 12, 12 }, 0 }, + { lampsurf, { 280, 43, 12, 12 }, 0 }, + { lampsurf, { 294, 43, 12, 12 }, 0 }, + { lampsurf, { 308, 43, 12, 12 }, 0 }, + { lampsurf, { 322, 43, 12, 12 }, 0 }, + /* MI */ + { lampsurf, { 79, 75, 12, 12 }, 0 }, + { lampsurf, { 93, 75, 12, 12 }, 0 }, + { lampsurf, { 107, 75, 12, 12 }, 0 }, + { lampsurf, { 122, 75, 12, 12 }, 0 }, + { lampsurf, { 136, 75, 12, 12 }, 0 }, + { lampsurf, { 150, 75, 12, 12 }, 0 }, + { lampsurf, { 165, 75, 12, 12 }, 0 }, + { lampsurf, { 179, 75, 12, 12 }, 0 }, + { lampsurf, { 193, 75, 12, 12 }, 0 }, + { lampsurf, { 208, 75, 12, 12 }, 0 }, + { lampsurf, { 222, 75, 12, 12 }, 0 }, + { lampsurf, { 236, 75, 12, 12 }, 0 }, + { lampsurf, { 251, 75, 12, 12 }, 0 }, + { lampsurf, { 265, 75, 12, 12 }, 0 }, + { lampsurf, { 279, 75, 12, 12 }, 0 }, + { lampsurf, { 294, 75, 12, 12 }, 0 }, + { lampsurf, { 308, 75, 12, 12 }, 0 }, + { lampsurf, { 322, 75, 12, 12 }, 0 }, + { lampsurf, { 337, 75, 12, 12 }, 0 }, + { lampsurf, { 351, 75, 12, 12 }, 0 }, + { lampsurf, { 365, 75, 12, 12 }, 0 }, + { lampsurf, { 380, 75, 12, 12 }, 0 }, + { lampsurf, { 394, 75, 12, 12 }, 0 }, + { lampsurf, { 408, 75, 12, 12 }, 0 }, + { lampsurf, { 423, 75, 12, 12 }, 0 }, + { lampsurf, { 437, 75, 12, 12 }, 0 }, + { lampsurf, { 451, 75, 12, 12 }, 0 }, + { lampsurf, { 466, 75, 12, 12 }, 0 }, + { lampsurf, { 480, 75, 12, 12 }, 0 }, + { lampsurf, { 494, 75, 12, 12 }, 0 }, + { lampsurf, { 509, 75, 12, 12 }, 0 }, + { lampsurf, { 523, 75, 12, 12 }, 0 }, + { lampsurf, { 537, 75, 12, 12 }, 0 }, + { lampsurf, { 552, 75, 12, 12 }, 0 }, + { lampsurf, { 566, 75, 12, 12 }, 0 }, + { lampsurf, { 580, 75, 12, 12 }, 0 }, + /* PC */ + { lampsurf, { 643, 43, 12, 12 }, 0 }, + { lampsurf, { 657, 43, 12, 12 }, 0 }, + { lampsurf, { 671, 43, 12, 12 }, 0 }, + { lampsurf, { 686, 43, 12, 12 }, 0 }, + { lampsurf, { 700, 43, 12, 12 }, 0 }, + { lampsurf, { 714, 43, 12, 12 }, 0 }, + { lampsurf, { 729, 43, 12, 12 }, 0 }, + { lampsurf, { 743, 43, 12, 12 }, 0 }, + { lampsurf, { 757, 43, 12, 12 }, 0 }, + { lampsurf, { 772, 43, 12, 12 }, 0 }, + { lampsurf, { 786, 43, 12, 12 }, 0 }, + { lampsurf, { 800, 43, 12, 12 }, 0 }, + { lampsurf, { 815, 43, 12, 12 }, 0 }, + { lampsurf, { 829, 43, 12, 12 }, 0 }, + { lampsurf, { 843, 43, 12, 12 }, 0 }, + { lampsurf, { 857, 43, 12, 12 }, 0 }, + { lampsurf, { 872, 43, 12, 12 }, 0 }, + { lampsurf, { 886, 43, 12, 12 }, 0 }, + /* MA */ + { lampsurf, { 643, 75, 12, 12 }, 0 }, + { lampsurf, { 657, 75, 12, 12 }, 0 }, + { lampsurf, { 671, 75, 12, 12 }, 0 }, + { lampsurf, { 686, 75, 12, 12 }, 0 }, + { lampsurf, { 700, 75, 12, 12 }, 0 }, + { lampsurf, { 714, 75, 12, 12 }, 0 }, + { lampsurf, { 729, 75, 12, 12 }, 0 }, + { lampsurf, { 743, 75, 12, 12 }, 0 }, + { lampsurf, { 757, 75, 12, 12 }, 0 }, + { lampsurf, { 772, 75, 12, 12 }, 0 }, + { lampsurf, { 786, 75, 12, 12 }, 0 }, + { lampsurf, { 800, 75, 12, 12 }, 0 }, + { lampsurf, { 815, 75, 12, 12 }, 0 }, + { lampsurf, { 829, 75, 12, 12 }, 0 }, + { lampsurf, { 843, 75, 12, 12 }, 0 }, + { lampsurf, { 857, 75, 12, 12 }, 0 }, + { lampsurf, { 872, 75, 12, 12 }, 0 }, + { lampsurf, { 886, 75, 12, 12 }, 0 }, + /* PIO */ + { lampsurf, { 974, 43, 12, 12 }, 0 }, + { lampsurf, { 988, 43, 12, 12 }, 0 }, + { lampsurf, { 1002, 43, 12, 12 }, 0 }, + { lampsurf, { 1016, 43, 12, 12 }, 0 }, + { lampsurf, { 1030, 43, 12, 12 }, 0 }, + { lampsurf, { 1044, 43, 12, 12 }, 0 }, + { lampsurf, { 1058, 43, 12, 12 }, 0 }, + /* PIR */ + { lampsurf, { 974, 75, 12, 12 }, 0 }, + { lampsurf, { 988, 75, 12, 12 }, 0 }, + { lampsurf, { 1002, 75, 12, 12 }, 0 }, + { lampsurf, { 1016, 75, 12, 12 }, 0 }, + { lampsurf, { 1030, 75, 12, 12 }, 0 }, + { lampsurf, { 1044, 75, 12, 12 }, 0 }, + { lampsurf, { 1058, 75, 12, 12 }, 0 }, + /* PIH */ + { lampsurf, { 974, 107, 12, 12 }, 0 }, + { lampsurf, { 988, 107, 12, 12 }, 0 }, + { lampsurf, { 1002, 107, 12, 12 }, 0 }, + { lampsurf, { 1016, 107, 12, 12 }, 0 }, + { lampsurf, { 1030, 107, 12, 12 }, 0 }, + { lampsurf, { 1044, 107, 12, 12 }, 0 }, + { lampsurf, { 1058, 107, 12, 12 }, 0 }, + /* Address stop, Repeat */ + { lampsurf, { 1126, 75, 12, 12 }, 0 }, + { lampsurf, { 1126, 107, 12, 12 }, 0 }, + /* Disable memory, Power */ + { lampsurf, { 1194, 75, 12, 12 }, 0 }, + { lampsurf, { 1194, 107, 12, 12 }, 0 }, + /* Run, Mem stop, PI on */ + { lampsurf, { 946, 43, 12, 12 }, 0 }, + { lampsurf, { 946, 75, 12, 12 }, 0 }, + { lampsurf, { 946, 107, 12, 12 }, 0 }, +}; + +Light ind_lights[] = { + /* MB */ + { lampsurf, { 713, 74, 12, 12 }, 0 }, + { lampsurf, { 727, 74, 12, 12 }, 0 }, + { lampsurf, { 741, 74, 12, 12 }, 0 }, + { lampsurf, { 756, 74, 12, 12 }, 0 }, + { lampsurf, { 770, 74, 12, 12 }, 0 }, + { lampsurf, { 784, 74, 12, 12 }, 0 }, + { lampsurf, { 799, 74, 12, 12 }, 0 }, + { lampsurf, { 813, 74, 12, 12 }, 0 }, + { lampsurf, { 827, 74, 12, 12 }, 0 }, + { lampsurf, { 842, 74, 12, 12 }, 0 }, + { lampsurf, { 856, 74, 12, 12 }, 0 }, + { lampsurf, { 870, 74, 12, 12 }, 0 }, + { lampsurf, { 885, 74, 12, 12 }, 0 }, + { lampsurf, { 899, 74, 12, 12 }, 0 }, + { lampsurf, { 913, 74, 12, 12 }, 0 }, + { lampsurf, { 928, 74, 12, 12 }, 0 }, + { lampsurf, { 942, 74, 12, 12 }, 0 }, + { lampsurf, { 956, 74, 12, 12 }, 0 }, + { lampsurf, { 971, 74, 12, 12 }, 0 }, + { lampsurf, { 985, 74, 12, 12 }, 0 }, + { lampsurf, { 999, 74, 12, 12 }, 0 }, + { lampsurf, { 1014, 74, 12, 12 }, 0 }, + { lampsurf, { 1028, 74, 12, 12 }, 0 }, + { lampsurf, { 1042, 74, 12, 12 }, 0 }, + { lampsurf, { 1057, 74, 12, 12 }, 0 }, + { lampsurf, { 1071, 74, 12, 12 }, 0 }, + { lampsurf, { 1085, 74, 12, 12 }, 0 }, + { lampsurf, { 1100, 74, 12, 12 }, 0 }, + { lampsurf, { 1114, 74, 12, 12 }, 0 }, + { lampsurf, { 1128, 74, 12, 12 }, 0 }, + { lampsurf, { 1143, 74, 12, 12 }, 0 }, + { lampsurf, { 1157, 74, 12, 12 }, 0 }, + { lampsurf, { 1171, 74, 12, 12 }, 0 }, + { lampsurf, { 1186, 74, 12, 12 }, 0 }, + { lampsurf, { 1200, 74, 12, 12 }, 0 }, + { lampsurf, { 1214, 74, 12, 12 }, 0 }, + /* AR */ + { lampsurf, { 713, 110, 12, 12 }, 0 }, + { lampsurf, { 727, 110, 12, 12 }, 0 }, + { lampsurf, { 741, 110, 12, 12 }, 0 }, + { lampsurf, { 756, 110, 12, 12 }, 0 }, + { lampsurf, { 770, 110, 12, 12 }, 0 }, + { lampsurf, { 784, 110, 12, 12 }, 0 }, + { lampsurf, { 799, 110, 12, 12 }, 0 }, + { lampsurf, { 813, 110, 12, 12 }, 0 }, + { lampsurf, { 827, 110, 12, 12 }, 0 }, + { lampsurf, { 842, 110, 12, 12 }, 0 }, + { lampsurf, { 856, 110, 12, 12 }, 0 }, + { lampsurf, { 870, 110, 12, 12 }, 0 }, + { lampsurf, { 885, 110, 12, 12 }, 0 }, + { lampsurf, { 899, 110, 12, 12 }, 0 }, + { lampsurf, { 913, 110, 12, 12 }, 0 }, + { lampsurf, { 928, 110, 12, 12 }, 0 }, + { lampsurf, { 942, 110, 12, 12 }, 0 }, + { lampsurf, { 956, 110, 12, 12 }, 0 }, + { lampsurf, { 971, 110, 12, 12 }, 0 }, + { lampsurf, { 985, 110, 12, 12 }, 0 }, + { lampsurf, { 999, 110, 12, 12 }, 0 }, + { lampsurf, { 1014, 110, 12, 12 }, 0 }, + { lampsurf, { 1028, 110, 12, 12 }, 0 }, + { lampsurf, { 1042, 110, 12, 12 }, 0 }, + { lampsurf, { 1057, 110, 12, 12 }, 0 }, + { lampsurf, { 1071, 110, 12, 12 }, 0 }, + { lampsurf, { 1085, 110, 12, 12 }, 0 }, + { lampsurf, { 1100, 110, 12, 12 }, 0 }, + { lampsurf, { 1114, 110, 12, 12 }, 0 }, + { lampsurf, { 1128, 110, 12, 12 }, 0 }, + { lampsurf, { 1143, 110, 12, 12 }, 0 }, + { lampsurf, { 1157, 110, 12, 12 }, 0 }, + { lampsurf, { 1171, 110, 12, 12 }, 0 }, + { lampsurf, { 1186, 110, 12, 12 }, 0 }, + { lampsurf, { 1200, 110, 12, 12 }, 0 }, + { lampsurf, { 1214, 110, 12, 12 }, 0 }, + /* MQ */ + { lampsurf, { 713, 146, 12, 12 }, 0 }, + { lampsurf, { 727, 146, 12, 12 }, 0 }, + { lampsurf, { 741, 146, 12, 12 }, 0 }, + { lampsurf, { 756, 146, 12, 12 }, 0 }, + { lampsurf, { 770, 146, 12, 12 }, 0 }, + { lampsurf, { 784, 146, 12, 12 }, 0 }, + { lampsurf, { 799, 146, 12, 12 }, 0 }, + { lampsurf, { 813, 146, 12, 12 }, 0 }, + { lampsurf, { 827, 146, 12, 12 }, 0 }, + { lampsurf, { 842, 146, 12, 12 }, 0 }, + { lampsurf, { 856, 146, 12, 12 }, 0 }, + { lampsurf, { 870, 146, 12, 12 }, 0 }, + { lampsurf, { 885, 146, 12, 12 }, 0 }, + { lampsurf, { 899, 146, 12, 12 }, 0 }, + { lampsurf, { 913, 146, 12, 12 }, 0 }, + { lampsurf, { 928, 146, 12, 12 }, 0 }, + { lampsurf, { 942, 146, 12, 12 }, 0 }, + { lampsurf, { 956, 146, 12, 12 }, 0 }, + { lampsurf, { 971, 146, 12, 12 }, 0 }, + { lampsurf, { 985, 146, 12, 12 }, 0 }, + { lampsurf, { 999, 146, 12, 12 }, 0 }, + { lampsurf, { 1014, 146, 12, 12 }, 0 }, + { lampsurf, { 1028, 146, 12, 12 }, 0 }, + { lampsurf, { 1042, 146, 12, 12 }, 0 }, + { lampsurf, { 1057, 146, 12, 12 }, 0 }, + { lampsurf, { 1071, 146, 12, 12 }, 0 }, + { lampsurf, { 1085, 146, 12, 12 }, 0 }, + { lampsurf, { 1100, 146, 12, 12 }, 0 }, + { lampsurf, { 1114, 146, 12, 12 }, 0 }, + { lampsurf, { 1128, 146, 12, 12 }, 0 }, + { lampsurf, { 1143, 146, 12, 12 }, 0 }, + { lampsurf, { 1157, 146, 12, 12 }, 0 }, + { lampsurf, { 1171, 146, 12, 12 }, 0 }, + { lampsurf, { 1186, 146, 12, 12 }, 0 }, + { lampsurf, { 1200, 146, 12, 12 }, 0 }, + { lampsurf, { 1214, 146, 12, 12 }, 0 }, + /* flags */ + /* FE */ + { lampsurf, { 539, 161, 14, 22 }, 0 }, + { lampsurf, { 451, 42, 14, 22 }, 0 }, + { lampsurf, { 451, 59, 14, 22 }, 0 }, + { lampsurf, { 451, 76, 14, 22 }, 0 }, + { lampsurf, { 451, 93, 14, 22 }, 0 }, + { lampsurf, { 451, 110, 14, 22 }, 0 }, + { lampsurf, { 451, 127, 14, 22 }, 0 }, + { lampsurf, { 451, 144, 14, 22 }, 0 }, + { lampsurf, { 451, 161, 14, 22 }, 0 }, + /* SC */ + { lampsurf, { 539, 144, 14, 22 }, 0 }, + { lampsurf, { 495, 42, 14, 22 }, 0 }, + { lampsurf, { 495, 59, 14, 22 }, 0 }, + { lampsurf, { 495, 76, 14, 22 }, 0 }, + { lampsurf, { 495, 93, 14, 22 }, 0 }, + { lampsurf, { 495, 110, 14, 22 }, 0 }, + { lampsurf, { 495, 127, 14, 22 }, 0 }, + { lampsurf, { 495, 144, 14, 22 }, 0 }, + { lampsurf, { 495, 161, 14, 22 }, 0 }, + /* misc flip-flops */ + /* column 1 */ + { lampsurf, { 55, 42, 14, 22 }, 0 }, + { lampsurf, { 55, 59, 14, 22 }, 0 }, + { lampsurf, { 55, 76, 14, 22 }, 0 }, + { lampsurf, { 55, 93, 14, 22 }, 0 }, + { lampsurf, { 55, 110, 14, 22 }, 0 }, + { lampsurf, { 55, 127, 14, 22 }, 0 }, + { lampsurf, { 55, 144, 14, 22 }, 0 }, + { lampsurf, { 55, 161, 14, 22 }, 0 }, + /* */ + { lampsurf, { 319, 110, 14, 22 }, 0 }, + { lampsurf, { 319, 127, 14, 22 }, 0 }, + /* column 12 */ + { lampsurf, { 539, 42, 14, 22 }, 0 }, + { lampsurf, { 539, 59, 14, 22 }, 0 }, + { lampsurf, { 539, 76, 14, 22 }, 0 }, + { lampsurf, { 539, 93, 14, 22 }, 0 }, + { lampsurf, { 539, 110, 14, 22 }, 0 }, + { lampsurf, { 539, 127, 14, 22 }, 0 }, + /* column 13 */ + { lampsurf, { 583, 42, 14, 22 }, 0 }, + { lampsurf, { 583, 59, 14, 22 }, 0 }, + { lampsurf, { 583, 76, 14, 22 }, 0 }, + { lampsurf, { 583, 93, 14, 22 }, 0 }, + { lampsurf, { 583, 110, 14, 22 }, 0 }, + { lampsurf, { 583, 127, 14, 22 }, 0 }, + { lampsurf, { 583, 144, 14, 22 }, 0 }, + { lampsurf, { 583, 161, 14, 22 }, 0 }, + /* column 14 */ + { lampsurf, { 627, 42, 14, 22 }, 0 }, + { lampsurf, { 627, 59, 14, 22 }, 0 }, + { lampsurf, { 627, 76, 14, 22 }, 0 }, + { lampsurf, { 627, 93, 14, 22 }, 0 }, + { lampsurf, { 627, 110, 14, 22 }, 0 }, + { lampsurf, { 627, 127, 14, 22 }, 0 }, + { lampsurf, { 627, 144, 14, 22 }, 0 }, + { lampsurf, { 627, 161, 14, 22 }, 0 }, + /* column 9 */ + { lampsurf, { 407, 42, 14, 22 }, 0 }, + { lampsurf, { 407, 59, 14, 22 }, 0 }, + { lampsurf, { 407, 76, 14, 22 }, 0 }, + { lampsurf, { 407, 93, 14, 22 }, 0 }, + { lampsurf, { 407, 110, 14, 22 }, 0 }, + { lampsurf, { 407, 127, 14, 22 }, 0 }, + { lampsurf, { 407, 144, 14, 22 }, 0 }, + { lampsurf, { 407, 161, 14, 22 }, 0 }, +}; +Light extra_lights[] = { + /* MEMBUS */ + { lampsurf, { 693, 26, 12, 12 }, 0 }, + { lampsurf, { 707, 26, 12, 12 }, 0 }, + { lampsurf, { 721, 26, 12, 12 }, 0 }, + { lampsurf, { 736, 26, 12, 12 }, 0 }, + { lampsurf, { 750, 26, 12, 12 }, 0 }, + { lampsurf, { 764, 26, 12, 12 }, 0 }, + { lampsurf, { 779, 26, 12, 12 }, 0 }, + { lampsurf, { 793, 26, 12, 12 }, 0 }, + { lampsurf, { 807, 26, 12, 12 }, 0 }, + { lampsurf, { 822, 26, 12, 12 }, 0 }, + { lampsurf, { 836, 26, 12, 12 }, 0 }, + { lampsurf, { 850, 26, 12, 12 }, 0 }, + { lampsurf, { 865, 26, 12, 12 }, 0 }, + { lampsurf, { 879, 26, 12, 12 }, 0 }, + { lampsurf, { 893, 26, 12, 12 }, 0 }, + { lampsurf, { 908, 26, 12, 12 }, 0 }, + { lampsurf, { 922, 26, 12, 12 }, 0 }, + { lampsurf, { 936, 26, 12, 12 }, 0 }, + { lampsurf, { 951, 26, 12, 12 }, 0 }, + { lampsurf, { 965, 26, 12, 12 }, 0 }, + { lampsurf, { 979, 26, 12, 12 }, 0 }, + { lampsurf, { 994, 26, 12, 12 }, 0 }, + { lampsurf, { 1008, 26, 12, 12 }, 0 }, + { lampsurf, { 1022, 26, 12, 12 }, 0 }, + { lampsurf, { 1037, 26, 12, 12 }, 0 }, + { lampsurf, { 1051, 26, 12, 12 }, 0 }, + { lampsurf, { 1065, 26, 12, 12 }, 0 }, + { lampsurf, { 1080, 26, 12, 12 }, 0 }, + { lampsurf, { 1094, 26, 12, 12 }, 0 }, + { lampsurf, { 1108, 26, 12, 12 }, 0 }, + { lampsurf, { 1123, 26, 12, 12 }, 0 }, + { lampsurf, { 1137, 26, 12, 12 }, 0 }, + { lampsurf, { 1151, 26, 12, 12 }, 0 }, + { lampsurf, { 1166, 26, 12, 12 }, 0 }, + { lampsurf, { 1180, 26, 12, 12 }, 0 }, + { lampsurf, { 1194, 26, 12, 12 }, 0 }, + /* PR */ + { lampsurf, { 74, 26, 12, 12 }, 0 }, + { lampsurf, { 88, 26, 12, 12 }, 0 }, + { lampsurf, { 102, 26, 12, 12 }, 0 }, + { lampsurf, { 117, 26, 12, 12 }, 0 }, + { lampsurf, { 131, 26, 12, 12 }, 0 }, + { lampsurf, { 145, 26, 12, 12 }, 0 }, + { lampsurf, { 160, 26, 12, 12 }, 0 }, + { lampsurf, { 174, 26, 12, 12 }, 0 }, + /* RLR */ + { lampsurf, { 274, 26, 12, 12 }, 0 }, + { lampsurf, { 288, 26, 12, 12 }, 0 }, + { lampsurf, { 302, 26, 12, 12 }, 0 }, + { lampsurf, { 317, 26, 12, 12 }, 0 }, + { lampsurf, { 331, 26, 12, 12 }, 0 }, + { lampsurf, { 345, 26, 12, 12 }, 0 }, + { lampsurf, { 360, 26, 12, 12 }, 0 }, + { lampsurf, { 374, 26, 12, 12 }, 0 }, + /* RLA */ + { lampsurf, { 475, 26, 12, 12 }, 0 }, + { lampsurf, { 489, 26, 12, 12 }, 0 }, + { lampsurf, { 503, 26, 12, 12 }, 0 }, + { lampsurf, { 518, 26, 12, 12 }, 0 }, + { lampsurf, { 532, 26, 12, 12 }, 0 }, + { lampsurf, { 546, 26, 12, 12 }, 0 }, + { lampsurf, { 561, 26, 12, 12 }, 0 }, + { lampsurf, { 575, 26, 12, 12 }, 0 }, +}; +Light *ir_lght, *mi_lght, *pc_lght, *ma_lght, *pio_lght, *pir_lght, + *pih_lght, *rest_lght; +Light *mb_lght, *pc_lght, *ar_lght, *mq_lght, *fe_lght, *sc_lght, + *ff_lght; +Light *membus_lght, *pr_lght, *rlr_lght, *rla_lght; + +Switch switches[] = { + /* DATA */ + { switchsurf, { 78, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 92, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 106, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 121, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 135, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 149, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 164, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 178, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 192, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 207, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 221, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 235, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 250, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 264, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 278, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 293, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 307, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 321, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 336, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 350, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 364, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 379, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 393, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 407, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 422, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 436, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 450, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 465, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 479, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 493, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 508, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 522, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 536, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 551, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 565, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 579, 102, 14, 22 }, 0, 0 }, + /* MAS */ + { switchsurf, { 642, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 656, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 670, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 685, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 699, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 713, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 728, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 742, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 756, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 771, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 785, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 799, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 814, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 828, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 842, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 857, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 871, 102, 14, 22 }, 0, 0 }, + { switchsurf, { 885, 102, 14, 22 }, 0, 0 }, + /* Address stop, Repeat */ + { switchsurf, { 1111, 70, 14, 22 }, 0, 0 }, + { switchsurf, { 1111, 102, 14, 22 }, 0, 0 }, + /* Disable memory, Power */ + { switchsurf, { 1179, 70, 14, 22 }, 0, 0 }, + { switchsurf, { 1179, 102, 14, 22 }, 0, 0 }, + + /* RIM MAINT */ + { switchsurf, { 633, 21, 14, 22 }, 0, 0 }, +}; +Switch *data_sw, *ma_sw, *rest_sw, *rim_maint_sw; + +void +setlights(word w, Light *l, int n) +{ + int i; + for(i = 0; i < n; i++) + l[n-i-1].state = !!(w & 1L<x || x > r->x+r->w || + y < r->y || y > r->y+r->h){ + switches[i].active = 0; + continue; + } + if(!switches[i].active){ + prevst = switches[i].state; + if(buttonstate & 1) + switches[i].state = !switches[i].state; + if(buttonstate & 2) + switches[i].state = 1; + if(buttonstate & 4) + switches[i].state = 0; + switches[i].active = 1; + + /* state changed */ + if(prevst != switches[i].state){ + /* power */ + if(&switches[i] == &rest_sw[3]){ + if(prevst == 0) + poweron(); + } + /* rim maint */ + if(&switches[i] == rim_maint_sw){ + if(prevst == 0) + apr.key_rim_sbr = 1; + } + } + } + } + + for(i = 0; i < nelem(keys); i++){ + r = &keys[i].r; + if(buttonstate == 0 || + x < r->x || x > r->x+r->w || + y < r->y || y > r->y+r->h){ + keys[i].state = 0; + continue; + } + prevst = keys[i].state; + if(buttonstate & 1) + keys[i].state = 1; + if(buttonstate & 4) + keys[i].state = 2; + if(prevst != keys[i].state){ + switch(i){ + case 0: /* start */ + case 1: /* cont */ + case 3: /* execute, reset */ + case 4: /* deposit */ + case 5: /* examine */ + if(keys[i].state && apr.sw_power) + extpulse |= 1; + break; + case 2: /* stop */ + case 6: /* on off reader */ + case 7: /* punch */ + break; + } + } + } +} + +int +main() +{ + SDL_Event ev; + SDL_MouseButtonEvent *mbev; + SDL_MouseMotionEvent *mmev; + SDL_Surface *op_surf, *ind_surf, *extra_surf; + SDL_Rect op_panel = { 0, 274, 1280, 210 }; + SDL_Rect ind_panel = { 0, 64, 1280, 210 }; + SDL_Rect extra_panel = { 0, 0, 1280, 210 }; + int i; + Light *l; + Switch *sw; + + if(SDL_Init(SDL_INIT_VIDEO) < 0){ +error: + fprintf(stderr, "error: %s\n", SDL_GetError()); + return 1; + } + screen = SDL_SetVideoMode(1280, 484, 32, SDL_DOUBLEBUF); + if(screen == NULL) + goto error; + + if((IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG) != IMG_INIT_PNG){ + fprintf(stderr, "error: init SDL_Image: %s\n", IMG_GetError()); + return 1; + } + + op_surf = IMG_Load("op_panel.png"); + if(op_surf == NULL){ + fprintf(stderr, "Couldn't load op_panel.png\n"); + return 1; + } + ind_surf = IMG_Load("ind_panel.png"); + if(ind_surf == NULL){ + fprintf(stderr, "Couldn't load ind_panel.png\n"); + return 1; + } + extra_surf = IMG_Load("extra_panel.png"); + if(extra_surf == NULL){ + fprintf(stderr, "Couldn't load extra_panel.png\n"); + return 1; + } + + keysurf[0] = IMG_Load("key_n.png"); + if(keysurf[0] == NULL){ + fprintf(stderr, "Couldn't load key_n.png\n"); + return 1; + } + keysurf[1] = IMG_Load("key_d.png"); + if(keysurf[1] == NULL){ + fprintf(stderr, "Couldn't load key_d.png\n"); + return 1; + } + keysurf[2] = IMG_Load("key_u.png"); + if(keysurf[2] == NULL){ + fprintf(stderr, "Couldn't load key_u.png\n"); + return 1; + } + + lampsurf[0] = IMG_Load("lamp_off.png"); + if(lampsurf[0] == NULL){ + fprintf(stderr, "Couldn't load lamp_off.png\n"); + return 1; + } + lampsurf[1] = IMG_Load("lamp_on.png"); + if(lampsurf[1] == NULL){ + fprintf(stderr, "Couldn't load lamp_on.png\n"); + return 1; + } + + switchsurf[0] = IMG_Load("switch_d.png"); + if(switchsurf[0] == NULL){ + fprintf(stderr, "Couldn't load switch_d.png\n"); + return 1; + } + switchsurf[1] = IMG_Load("switch_u.png"); + if(switchsurf[1] == NULL){ + fprintf(stderr, "Couldn't load switch_u.png\n"); + return 1; + } + + l = op_lights; + ir_lght = l; l += 18; + mi_lght = l; l += 36; + pc_lght = l; l += 18; + ma_lght = l; l += 18; + pio_lght = l; l += 7; + pir_lght = l; l += 7; + pih_lght = l; l += 7; + rest_lght = l; + sw = switches; + data_sw = sw; sw += 36; + ma_sw = sw; sw += 18; + rest_sw = sw; sw += 4; + rim_maint_sw = sw; + l = ind_lights; + mb_lght = l; l += 36; + ar_lght = l; l += 36; + mq_lght = l; l += 36; + fe_lght = l; l += 9; + sc_lght = l; l += 9; + ff_lght = l; + l = extra_lights; + membus_lght = l; l += 36; + pr_lght = l; l += 8; + rlr_lght = l; l += 8; + rla_lght = l; + for(i = 0; i < nelem(keys); i++){ + keys[i].r.x += op_panel.x; + keys[i].r.y += op_panel.y; + } + for(i = 0; i < nelem(op_lights); i++){ + op_lights[i].r.x += op_panel.x; + op_lights[i].r.y += op_panel.y; + } + for(i = 0; i < nelem(ind_lights); i++){ + ind_lights[i].r.x += ind_panel.x; + ind_lights[i].r.y += ind_panel.y; + } + for(i = 0; i < nelem(extra_lights); i++){ + extra_lights[i].r.x += extra_panel.x; + extra_lights[i].r.y += extra_panel.y; + } + for(i = 0; i < nelem(switches)-1; i++){ + switches[i].r.x += op_panel.x; + switches[i].r.y += op_panel.y; + } + rim_maint_sw->r.x += extra_panel.x; + rim_maint_sw->r.y += extra_panel.y; + + initmem(); + memset(&apr, 0xff, sizeof apr); + + for(;;){ + while(SDL_PollEvent(&ev)) + switch(ev.type){ + case SDL_MOUSEMOTION: + mmev = (SDL_MouseMotionEvent*)&ev; + mouse(0, mmev->state, + mmev->x, mmev->y); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + mbev = (SDL_MouseButtonEvent*)&ev; + mouse(mbev->button, mbev->state, + mbev->x, mbev->y); + break; + case SDL_QUIT: + SDL_Quit(); + return 0; + } + setlights(apr.ir, ir_lght, 18); + setlights(apr.mi, mi_lght, 36); + setlights(apr.pc, pc_lght, 18); + setlights(apr.ma, ma_lght, 18); + setlights(apr.pio, pio_lght, 7); + setlights(apr.pir, pir_lght, 7); + setlights(apr.pih, pih_lght, 7); + rest_lght[4].state = apr.run; + rest_lght[5].state = apr.mc_stop; + rest_lght[6].state = apr.pi_active; + rest_lght[0].state = apr.sw_addr_stop = rest_sw[0].state; + rest_lght[1].state = apr.sw_repeat = rest_sw[1].state; + rest_lght[2].state = apr.sw_mem_disable = rest_sw[2].state; + rest_lght[3].state = apr.sw_power = rest_sw[3].state; + apr.sw_rim_maint = rim_maint_sw->state; + apr.data = getswitches(data_sw, 36); + apr.mas = getswitches(ma_sw, 18); + apr.key_start = keys[0].state == 1; + apr.key_readin = keys[0].state == 2; + apr.key_inst_cont = keys[1].state == 1; + apr.key_mem_cont = keys[1].state == 2; + apr.key_inst_stop = keys[2].state == 1; + apr.key_mem_stop = keys[2].state == 2; + apr.key_io_reset = keys[3].state == 1; + apr.key_execute = keys[3].state == 2; + apr.key_dep = keys[4].state == 1; + apr.key_dep_next = keys[4].state == 2; + apr.key_ex = keys[5].state == 1; + apr.key_ex_next = keys[5].state == 2; + apr.key_rd_off = keys[6].state == 1; + apr.key_rd_on = keys[6].state == 2; + apr.key_pt_rd = keys[7].state == 1; + apr.key_pt_wr = keys[7].state == 2; + + setlights(apr.mb, mb_lght, 36); + setlights(apr.ar, ar_lght, 36); + setlights(apr.mq, mq_lght, 36); + setlights(apr.fe, fe_lght, 9); + setlights(apr.sc, sc_lght, 9); + ff_lght[0].state = apr.key_ex_st; + ff_lght[1].state = apr.key_ex_sync; + ff_lght[2].state = apr.key_dep_st; + ff_lght[3].state = apr.key_dep_sync; + ff_lght[4].state = apr.key_rd_wr; + ff_lght[5].state = apr.mc_rd; + ff_lght[6].state = apr.mc_wr; + ff_lght[7].state = apr.mc_rq; + ff_lght[8].state = apr.mc_split_cyc_sync; + ff_lght[9].state = apr.mc_stop_sync; + ff_lght[10].state = !apr.ex_user; + ff_lght[11].state = apr.cpa_illeg_op; + ff_lght[12].state = apr.ex_ill_op; + ff_lght[13].state = apr.ex_uuo_sync; + ff_lght[14].state = apr.ex_pi_sync; + ff_lght[15].state = apr.mq36; + ff_lght[16].state = apr.key_rim_sbr; + ff_lght[17].state = apr.cry0_cry1; + ff_lght[18].state = apr.ar_cry0; + ff_lght[19].state = apr.ar_cry1; + ff_lght[20].state = apr.ar_ov_flag; + ff_lght[21].state = apr.ar_cry0_flag; + ff_lght[22].state = apr.ar_cry1_flag; + ff_lght[23].state = apr.pc_chg_flag; + ff_lght[24].state = apr.cpa_non_exist_mem; + ff_lght[25].state = apr.cpa_clock_en; + ff_lght[26].state = apr.cpa_clock_flag; + ff_lght[27].state = apr.cpa_pc_chg_en; + ff_lght[28].state = apr.cpa_arov_en; + ff_lght[29].state = apr.cpa_pia33; + ff_lght[30].state = apr.cpa_pia34; + ff_lght[31].state = apr.cpa_pia35; + ff_lght[32].state = apr.pi_ov; + ff_lght[33].state = apr.pi_cyc; + ff_lght[34].state = apr.pi_req; + ff_lght[35].state = apr.iot_go; + ff_lght[36].state = apr.a_long; + ff_lght[37].state = apr.ma == apr.mas; + ff_lght[38].state = apr.uuo_f1; + ff_lght[39].state = apr.cpa_pdl_ov; + + setlights(membus0, membus_lght, 36); + setlights(apr.pr, pr_lght, 8); + setlights(apr.rlr, rlr_lght, 8); + setlights(apr.rla, rla_lght, 8); + + SDL_BlitSurface(op_surf, NULL, screen, &op_panel); + SDL_BlitSurface(ind_surf, NULL, screen, &ind_panel); + SDL_BlitSurface(extra_surf, NULL, screen, &extra_panel); + for(i = 0; i < nelem(keys); i++) + SDL_BlitSurface(keys[i].surfs[keys[i].state], + NULL, screen, &keys[i].r); + for(i = 0; i < nelem(op_lights); i++) + SDL_BlitSurface(op_lights[i].surfs[op_lights[i].state && apr.sw_power], + NULL, screen, &op_lights[i].r); + for(i = 0; i < nelem(ind_lights); i++) + SDL_BlitSurface(ind_lights[i].surfs[ind_lights[i].state && apr.sw_power], + NULL, screen, &ind_lights[i].r); + for(i = 0; i < nelem(extra_lights); i++) + SDL_BlitSurface(extra_lights[i].surfs[extra_lights[i].state && apr.sw_power], + NULL, screen, &extra_lights[i].r); + for(i = 0; i < nelem(switches); i++) + SDL_BlitSurface(switches[i].surfs[switches[i].state], + NULL, screen, &switches[i].r); + SDL_Flip(screen); + } +} diff --git a/mem b/mem new file mode 100644 index 0000000..1c50af2 --- /dev/null +++ b/mem @@ -0,0 +1,23 @@ +1234 +4321 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +11111 +22222 +33333 +44444 +55555 +66666 +77777 diff --git a/mem.c b/mem.c new file mode 100644 index 0000000..e963b93 --- /dev/null +++ b/mem.c @@ -0,0 +1,50 @@ +#include "pdp6.h" + +word memory[256*1024]; +//hword maxmem = 256*1024; +hword maxmem = 64*1024; +word fmem[16]; +word membus0, membus1; +word *hold; + +void +initmem(void) +{ + FILE *f; + word w; + hword a; + if(f = fopen("mem", "r"), f == NULL) + return; + for(a = 0; a < maxmem && fscanf(f, "%lo", &w) != EOF; a++) + memory[a] = w; + fclose(f); +} + +void +wakemem(void) +{ + hword a; + if(membus0 & MEMBUS_RQ_CYC){ + a = membus0>>4 & 037777; + if(membus0 & MEMBUS_MA21_1) a |= 0040000; + if(membus0 & MEMBUS_MA20_1) a |= 0100000; + if(membus0 & MEMBUS_MA19_1) a |= 0200000; + if(membus0 & MEMBUS_MA18_1) a |= 0400000; + if(a >= maxmem || + membus0 & MEMBUS_MA_FMC_SEL1 && a >= 16) + return; + + membus0 |= MEMBUS_MAI_ADDR_ACK; + hold = membus0 & MEMBUS_MA_FMC_SEL1 ? &fmem[a] : &memory[a]; + if(membus0 & MEMBUS_RD_RQ){ + membus1 = *hold; + membus0 |= MEMBUS_MAI_RD_RS; + hold = NULL; + } + } + if(membus0 & MEMBUS_MAI_WR_RS && hold){ + *hold = membus1; + membus0 &= ~MEMBUS_MAI_WR_RS; + hold = NULL; + } +} diff --git a/op_panel.png b/op_panel.png new file mode 100644 index 0000000..95b8f67 Binary files /dev/null and b/op_panel.png differ diff --git a/pdp6.h b/pdp6.h new file mode 100644 index 0000000..2a1877b --- /dev/null +++ b/pdp6.h @@ -0,0 +1,95 @@ +#include +#include +#include + +#define nelem(a) (sizeof(a)/sizeof(a[0])) + +typedef uint64_t word; +typedef uint32_t hword; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; +typedef char bool; + +typedef struct Apr Apr; +struct Apr { + hword ir; + word mi; + word data; + hword pc; + hword ma; + hword mas; + word mb; + word ar; + word mq; + u8 pio, pir, pih; + u16 sc, fe; + u8 pr, rlr, rla; + bool run, pi_active; + bool sw_addr_stop, sw_repeat, sw_mem_disable, sw_power; + bool sw_rim_maint; + /* keys */ + bool key_start, key_readin; + bool key_mem_cont, key_inst_cont; + bool key_mem_stop, key_inst_stop; + bool key_io_reset, key_execute; + bool key_dep, key_dep_next; + bool key_ex, key_ex_next; + bool key_rd_off, key_rd_on; + bool key_pt_rd, key_pt_wr; + + /* flip-flops */ + bool ex_mode_sync, ex_uuo_sync, ex_pi_sync, ex_ill_op, ex_user; + bool pc_chg_flag, ar_ov_flag, ar_cry0_flag, ar_cry1_flag; + bool pi_ov, pi_cyc, pi_req; + + bool key_ex_st, key_ex_sync; + bool key_dep_st, key_dep_sync; + bool key_rd_wr, key_rim_sbr; + + bool mc_rd, mc_wr, mc_rq, mc_stop, mc_stop_sync, mc_split_cyc_sync; + + bool cpa_iot_user, cpa_illeg_op, cpa_non_exist_mem, + cpa_clock_en, cpa_clock_flag, cpa_pc_chg_en, cpa_pdl_ov, + cpa_arov_en, cpa_pia33, cpa_pia34, cpa_pia35; + + bool cry0_cry1, ar_cry0, ar_cry1; + /* ?? */ + bool mq36; + bool iot_go, a_long, uuo_f1; + + /* sbr flip-flops */ + bool chf7; + + /* temporaries */ + bool ex_inh_rel; +}; +extern Apr apr; +void *aprmain(void *p); +extern int extpulse; + +void initmem(void); +void wakemem(void); +// 7-2, 7-10 +enum { + MEMBUS_MA21 = 0000000000001, + MEMBUS_WR_RQ = 0000000000004, + MEMBUS_RD_RQ = 0000000000010, + MEMBUS_MA_FMC_SEL0 = 0000001000000, + MEMBUS_MA_FMC_SEL1 = 0000002000000, + MEMBUS_MA35_0 = 0000004000000, + MEMBUS_MA35_1 = 0000010000000, + MEMBUS_MA21_0 = 0000020000000, + MEMBUS_MA21_1 = 0000040000000, + MEMBUS_MA20_0 = 0000100000000, + MEMBUS_MA20_1 = 0000200000000, + MEMBUS_MA19_0 = 0000400000000, + MEMBUS_MA19_1 = 0001000000000, + MEMBUS_MA18_0 = 0002000000000, + MEMBUS_MA18_1 = 0004000000000, + MEMBUS_RQ_CYC = 0020000000000, + MEMBUS_MAI_WR_RS = 0100000000000, + MEMBUS_MAI_RD_RS = 0200000000000, + MEMBUS_MAI_ADDR_ACK = 0400000000000, +}; +extern word membus0, membus1; diff --git a/switch_d.png b/switch_d.png new file mode 100644 index 0000000..4f83e4f Binary files /dev/null and b/switch_d.png differ diff --git a/switch_u.png b/switch_u.png new file mode 100644 index 0000000..ca60077 Binary files /dev/null and b/switch_u.png differ