Professional Documents
Culture Documents
Abstract
This report describes my successful project to build a working reproduction of the 1964 prototype for the Block I Apollo Guidance Computer. The AGC is the flight computer for the Ap ollo m oon lan din gs, and is the wo rlds first in tegra ted c ircuit com pu ter. I built it in my ba sem ent. It took me 4 yea rs. If you like, you can build one too. It will take you less time, and yours will be better than mine. I docum ented m y project in 9 separate .pdf files: Part 1 Part 2 Part 3 Part 4 Part 5 Part 6 Part 7 Part 8 O v ervie w : Introdu ces the p roject. CTL Module: Design and construction of the control module. PROC M odule: Design and construction of the processing (CPU) modu le. MEM Module: Design and construction of the mem ory module. IO Module: Design and construction of the display/keyboard (DSKY) m odule. Assem bler: A cross-a ssem bler for AG C softw are dev elopm ent. C+ + S imu lator: A low-level simulator that runs assemb led AGC code. Flight Software: My translation of portions of the COLOSSUS 249 flight software. Test & Che ckou t: A suite of test programs in AG C assembly langu age.
Part 9
Original AGC:
Designed by M.I.T. in 1964 World's first microchip computer Prototype computer for Apollo moon landing Memory: 12K fixed (ROM), 1K eraseable (RAM) Clock: 1.024 MHz Com pu ting : 11 instru ction s, 16 bit w ord Logic: ~5 000 ICs (3 -input N OR g ates, RTL logic)
My AGC:
Built from origina l M.I.T. desig n do cum ents Started November 2000, completed October 2004 ~1 5K han d-w rapped wire con nec tion s; ~ 35 00 feet of w ire Cost (parts only): $2,980. Lab or: ~ 25 00 hou rs Logic: ~5 00 ICs (LST TL logic) Runs flight software (1969 program name: COLOSSUS 249)
Three AGCs
To succeed, I had to b uild the AG C three tim es. Or rather, I had to bu ild three AGC s. Each one is a fully functional computer. Each one is a step toward building the next. The last one is the one I wanted. Heres the faces of my three AG Cs:
AG C # 1: m y C+ + A GC sim ula tor. It has eve ry register an d logic signal in the original doc um entation. I use it to develop and debug AG C assem bly lan gu age cod e. When I got this working, I knew I understood the AGC. I knew I could do the rest of the proje ct.
AG C # 2: m y Circu itMa ker dig ital circuit simulator AGC. What you see here are front panel log ic indicators for signals and registers. The remaining pa rt: about 60 or so pages of logic diagrams; the same schem atics youll see in the CTL, PROC, MEM, and IO .pdf files that follow this overview. This AGC literally runs about a half-million times slower than the first! I used it to debug m y log ic de sign . When I got this working, I knew I still had a yea r (14 m onths, a ctua lly) o f tedio us w ork ahead.
AG C # 3: Th is is the final one. My hardware AGC is built into a relay rack to give it th e sa m e prototyped appearance as the original. The dim ens ions are abo ut 3 x 5 feet. The up per le ft m odu le (CT L) is the control logic. The low er left m odu le (PR OC ) is the CPU. The lower right m odu le (ME M) is the memory. The up per le ft module (IO) has the inputs and outputs. The keyboard and display (DSKY) for use r inp ut a re on th e up perm iddle -right. The white KYNAR wires look like cobwebs to me. This was pho tograp hed in my back yard. Can you see the blue sky and tree branch reflections in the upper panels?
Here I am, plugging COLOSSUS 249 flight software EPRO Ms into Z IF sockets. We lugged the AGC out of the basement and took it ou tdoors for th ese ph otogra phs . Its in the bac kya rd, pro pp ed a gainst the b ack of m y house.
A close-up of COLOSSU S EPROM s. I put red tape over the quartz windows to keep them from erasing th em selves. A b oug ht th e tog gle s wit che s a few years ago from a surplus ven dor. They w ere so cheap, I bought a 100 of them. Arent they great?
I really like flashing ligh ts and con trol panels. There s no wa y to deb ug so m ethin g this co mp lex w ith ou t th em . I bought LED s in bulk from the sam e place that sold m e the switches.
AGC Demonstration
Heres a demonstration of my AGC. Its running my version of the COLOSSUS 249 flight software load:
Display CM clock:
<VERB> <0> <6> <NOUN> <3> <6> <ENTER> The red buttons were from Radio Shack.
The AGC samples and displays the CM clock. 58 hours, 44 m inutes, 34.27 seconds.
All D SK Y lam ps an d disp lay seg m ents illu m inate for 5 sec. The Verb and Noun displays flash. After 5 sec, the DSKY lamps extinguish. The 88888 displays are left in the registers.
Verb/no un disp lay flashes: wa iting for address <5> <0> <ENTER>
Verb/noun display flash continues: waiting for data <1> <2> <3> <ENTER>
Start a monitor program to continuously display elapsed time from the CM clock:
<VERB> <1> < 6> <NOUN> <3> <6> <ENTER>
The m onitor p rogram starts to con tinuo usly display the CM clock, updating the display about about 1 second intervals. The time shown is 58 hours, 47 m inutes, and 23.67 secon ds.
<NOUN> <0> <1> <ENTER> verb/nou n display flashe s: waiting for address
The o ctal w ord from add ress 50 is displa yed in R1 . In a p revio us o pera tion , we had set th e w ord to 123.
The octal word in address 51 is displayed in R1, incremented address in R3. <ENTER>
Verb 16, noun 36 reappears, along with the clock d isplay . The ke y release light g oes ou t. (Im not sure wh y the photos suddenly turned darker; I th ink som eon e m ust h ave turn ed o ff a light in an adjoining room)
E-mailed Eldon Hall, designer of the AGC, telling him about my project. His reply was gracious an d encou raging. W rote man y em ails to others asking for Block I source code. I order a 2.048 MHz crystal from D igiKey. My first hardware purchase. September - October 2001: Cant find any original Block I source code, except tiny fragm ents in the docu me nts. Recoded m y own EXEC , WAITLIST, and interrupt handlers using specifications from R-393 and others. Im starting to become a good AGC programmer. Now my simulator can multitask! Dis cove red B lock II flight softw are (C OLOS SU S 2 49 ) is no w d ow nloadable from MIT . 300+ pages of blurry assembler source code listing. Is that an eight, a six, number zero with a slash th roug h it, or th e lette r O, or m ayb e G? Prin ted a hard cop y. I think I can m ake m ost of it out. The second half of COLOSSUS is missing! The missing part has the INTERBANK COMM UNICATION, EXEC, and WAITLIST. E-mailed MIT. Their reply: they dont have the missing portion. November - December 2001: Tried to reproduce DSKY code using flowcharts from Greens Keyboard and Display System Program. Green calls it PINBALL GAME. Very confusing. Started writing a C+ + sim ula tion from Gree ns flow cha rts. Th ing s are b ecom ing clearer. Loca ted P INB ALL in m y CO LOSS US fragm ent. Abandon ed effort to code m y ow n. I will use the real thing. January - February 2002: Rety ped mo st of CO LOS SU S PIN BA LL ba ck into m achin e-read able form . 95% is alread y Block I instruction s; recode d the rem ainin g 5% into Blo ck I equ ivalen t. Finished all the octal display verbs (1-5) and decimal verb (6) and the load verbs (21- 25), b ut the yre only teste d for octal loa ds so far. No un ta bles are stubb ed, bu t I can manually set them for different scaling. Integrated PINBALL into m y EXEC and W AITLIST. Coded up a few missing pieces for interbank com mu nication. Also ha d to code a m ath library (yikes). But it works. The AGC simulator is running at abou t 1/30 the speed of the original. I need to speed it up. March - May 2002: Bought a new , faster PC. The simu lator now runs at about 1/5 speed. Recoded some simulator pieces. Now its 1:1. Finished PINBALL. All regular verbs (0-39) work. Also, normal nouns 1, 2, 3, 9, 15, 26, an d 36 . Very coo l. My fav orites: verb 16, no un 3 6, a m onitor rou tine to con tinu ous ly displa y the AG C clo ck, an d ve rb 35 wh ich d oes th e lam p tes t. Now that I ha ve som e proficien cy, I am reluctan t to leave A GC softwa re, but its tim e to start hardware logic design.
June - December 2002: Decided to use 74LS logic family. Started designing AGC logic, subsystem-bysubsystem, using the C++ simulator code as my guide. Began with MBF. Posted a subsystem block diagram on the w all. Im coloring in blocks as I finish each subsystem design. Entered logic de sign s into th e Circu itMa ker PC tool. Usin g Circu itMa kers digita l circuit sim u la tio n to u nit-test ea ch su bsy stem . Struggling with ALU and read/write bus design. The original AGC ORed everything onto the bus, and the default bus state was logical zero: sometimes, they read the bu s witho ut w riting to clea r registers. O ther tim es, they w rote m ultip le reg isters sim ulta neo usly to OR the d ata. The se trick s wont w ork w ith tri- state bus driv ers. I identify where tricks are used and add ALU logic to handle the cases. My ALU sort-of feeds back on itself. Confusing, but it should work. Logic design the old way: Karnaugh maps, excitation tables, and bubble-pushing. Fun, sort of. Logic design is now finished, except for the DSKY. Un it tests are done. I start ordering pa rts from JAME CO. Th e first order is for more than 2 00 ICs. January 2003: DSKY logic design is now finished and unit tested in CircuitMaker. All blocks on my dia gram are co lored in. W ill the sub syste m s work to geth er? February - May 2003: Using Circu itM ake r to int egra te su bsy stem s. Dia gram s for each su bsy stem are hooked into CircuitMaker macros; rectangular components with all inputs and outp uts for tha t subs ystem . Wired all sub system ma cros toge ther. W ill it run? I call it AG C2 , to differe ntia te it from the C ++ sim ula tor, w hich I now call A GC 1. Now I have two AG Cs! When I build the hardware, that will make three. Started debugging a TC instruction, the simplest, in AGC2. Worked it through, stepby-step, fixing logic and interface errors. Finally, it works. Debugging the remaining 8 basic instructions. Massive snowstorm; snowed in, 3 days straight. Lots of time for AGC2 debugging and testing. I estim ate m y po wer budg et an d ord er a 1 5A 5V sup ply. Mo re ICs a nd sock ets are ordered, too. Sick of hand-assembling test code for AGC2. W rote a version of the cross-assemb ler that produ ces object code for AGC 2. Broke TECO 1 into 8 pa rts; one for each instruction. One-by-one, I get all portions of TECO1 to run on AGC2. Broke TECO2 and TECO3 into pieces and got them to run on AG C2 also. INTEGRATION TESTING IS DONE! How to build it? There are too m any sub system s and interfaces.
June - August 2003 Grouped the 20 subsystems into 4 assemblies (soon to be called modules): I/O, CTL, PROC, and M EM. This is more manag eable. W rote C+ + cod e that ch ecks th e netlists p rodu ced b y Circu itMa ker for fan-ou t. Esta blish ed a lim it of 8 T TL lo ads, an d ad ded buffers w here necessa ry. Ad ded buffers between the 4 modules to make the fan-in for each module/module interface 1 TTL load. Stuffed IC sockets into 13 circuit boards; each board is 13"x5". What connectors and cables to use between boards? Between modules? Should I worry about bus termina tion? W hat kind of chassis? Decided to build each module as a small relay rack. Board-to-board connections inside each module are wire-wrapped--no connectors. Between modules, 40-pin IDE cab les, m atin g to 3 0-p in w ire-w rap con nec tors, are for m odu le/m odu le interfaces. Too lazy to pull 500 IC sockets and redo the boards. Ill work in connectors and additio nal bu ffers w here I can. B etter b uy the lo ng est ID E cab les (3 feet). M ore w orry about bus termination. Mod ule/Mo dule interfaces are now defined: 6 IDE ca bles. Built a rack for the I/O module out of 1x2 pine boards. Spray-painted gray; it looks pretty g ood. H ired m y eng ineerin g stud ent son to wire-w rap som e I/O m odu le logic during su mm er vacation. He w ires most of the DS KY. It lights up an d m ultiplexes, but operation is erratic; set aside for now. September - December 2003: Built control panels for PROC, CTL, and MEM modules by mounting switches on a woo den frame . Used thick styre ne p lastic for a facep late, ha nd- lettered w ith ind elible marker. It doesnt look too bad. Built indicator light panels for PROC, CTL, and MEM by punching holes in styrene plastic with a push-pin and then shoving LEDs through the plastic into the PCB. Hu nd reds of LED s; m y thum b has a bliste r. Built 3 more relay racks for the PROC, CTL, and MEM modules. Laid all the boards out on the racks. Will the IDE cables reach? Yes, but in some cases, barely. Bought an EPR OM program mer. Learned Motorola S-format. Wrote yet another version of the cross-assembler that outputs S-Record (s2f) format object code. Burned EPRO Ms with TECO 1, TECO2, TECO3, and the A GC flight software. Modified the C++ sim ulator (AGC1) so it dumps its microinstructions (subsystem CPM-A ) in Motorola S-format. Burned EPR OMS for CPM-A . Created a special version of AGC1 that reads CPM-A S-format microinstructions to verify the tables and reads AG C ob ject co de in S-form at to v erify th e cross-as sem bler. January - April 2004 Powered up, and started debugging the partly completed I/O module. Corrected a desig n error a nd a few m ino r wirin g errors; cle an ed up som e cold- solder join ts. It now w orks reliably. Finished wiring the I/O modu le. Its difficult to test, but it seems to work.
May - September 2004 Wired the power connections for all sockets on the CTL module; added a bypassing cap acito r for every 2 p ackages, an d a 1 0u f tant alu m cap acito r for each row of ICs. W ired the LED la m ps an d drive rs, and th en th e logic for ea ch su bsyste m . Plugg ed all the CTL ch ips into the sockets. Dis cove red a ll con trol sig nals from CPM -A w ere in verte d: th e EPRO M ta bles we re generated from AGC 1, which uses positive logic. The hardware AGC uses negative logic, because TTL inputs float high; I wanted floating inputs to assume the inactive state during assembly and test. Pried the EPROMs out of their sockets, bit-flipped the tables, erased and reprogram me d the chips, an d reinserted them . Now it wo rks. Completed wiring for the other modules. Now to hook them up. September - October 2004 Built a large rack to hold the 4 modules. Screwed the 4 modules into the rack and hooked up the IDE cables. Powered it on. Everything lights up. No smoke. Amazing! It runs part of TECO1, getting through dozens of instructions including subroutine calls, before b om bing out. Trying to debug the AGC by burning test EPROMs, single-stepping the clock, and comparing the results to the AGC1 C++ simulator. Its acting flaky. Could it be a su pp ly p ro blem ? Tore out m y flimsy pow er distribution; replaced it with heavy alu min um bus bars. Supply lines look cleaner on the scope, but the operation is just as flaky as before. Ma ybe w orse. Its bom bing out in d ifferent plac es. Is there som e com m on elem ent? Com mon element: the problem always involves read bus m icroinstructions. The ALU sets a default state on the read bus if no other subsystem is using it. My bus arbitratio n sch em e stinks : if a read sig nal is a sserted, th e ALU disab les its defau lt state, but propagation delays cause both drivers to enable simultaneously for a brief period. Is this the problem? I kludg e-in log ic to disab le the rea d bu s durin g CL K1 . This giv es the rea d bu s logic tim e to settle. I add propa gation delay to the C LK1 inpu t to TPG so the b us is disabled before the TPG state transition occurs. Will this fix the problem? No. It gets farth er alon g, bu t still bom bs ou t on read bus o peratio ns. Its time to download internet advice on bus termination. I add 220/330 ohm passive termination to the read bus input in the ALU. IT WORKS!! TECO1 and TECO3 run flawlessly. TECO2 bombs out while testing the DV (divide) instruction. It produces different results than the AGC1 simulator in the tests that involve division by zero. Do I care? I decide I do nt. I load the COLOSSUS EPROMs. The AGC flight software hangs at first; but I add some passive termination to the busy bus driver (for the read bus, of course) and then it works flaw lessly too. The project is finished (except, I have to write up th ese reports!)
Logic Design
The original AGC4 was built almost entirely from 1964-era 3-input NOR gate ICs; about 5,000 of them. Original gate-level logic designs are not available. Log ic for m y rep lica w as rec reate d using spec ifications in R -39 3, an d arc hite cture information/diagrams from R-700. Since R-39 3 defines (in detail) AGC registers, register tran sfers, m icroin struc tion s, an d m ost co ntrol pu lses (l ogic signals), th e arch itectu re of m y replica clo sely m irrors the origin al to a low level. The logic design for my replica uses late 1960's-early 1970's 74LS TTL logic, which affords about a 10-to-1 reduction in package count. Flip-flop and register chips are used instead of constructing ea ch elem ent from N OR g ates. The replica successfully runs those portions of the original COLOSSUS flight software that hav e been loade d on to it.
Clock
The original AGC4 divided its 2.048 MHz clock down into 4-phase 1.024 MHz signals to drive asynch ronous, level-triggered, register logic. My replica d ivides th e 2.04 8 M Hz clo ck into a 2 ph ased , non- overlap ping 1.02 4 M Hz clo ck to drive synchron ous, edge-triggered register logic. Phase 1 of the clock (CLK1 ) steps a sequ encer (T PG), w hich sets up the con trol signa ls. Those signa ls hav e tim e to prop aga te (settle) between phase 1 and phase 2. Phase 2 (CLK2) clocks the registers using the control signals established in phase 1. Data transfer occurs at phase 2.
393. Table 1-1 in R-393 says AG C4 has 20 (base 10 , I assume) counters. This is supported by Figure 2-5 which numbers counters from 1-20. However, Table 3-1 which shows AGC special registers assigns the cou nters to addresses 00 30 throug h 005 6 (base 8 ) which translates to 23 (base 10) counters. And Table 5-1, section D gives the counter addresses from 00 34 for OVC TR throu gh 00 56 for TRK R R, w hich translates to 19 (base 10 ) counters. So, its unclear whether AGC4 had 19, 20, or 23 counters and whether the counter addresses start at 0030 or 0034. To resolv e the a m bigu ity, I set the startin g ad dress for the coun ters to 34 (octal), w hich is the starting address used in the Block II AGC (COLOS SUS p rogram listing). For convenience, I only im plem ented coun ters that w ere used by the AG C EX EC a nd W AITLIS T, the rea l-tim e clock, and the overflow (5 in all). These are: address 34 35 36 37 40 counter OVCTR TIME2 TIME1 TIME3 TIME4
I also used the Block II ordering of TIME1 and TIME2, for compatibility with the COLOSSUS flight software. In the AGC 4, TIME1 is at the low er address.
Number of Interrupts
The original AGC had 5 vectored interrupts: UPRUPT, ERUPT, KEYRUPT, T3RUPT, and DS RU PT. U PR UP T w as u sed for up link ed co m m ands; E RU PT w as g ene rated wh en h ardwa re errors w ere detected. S ince I didn t plan to us e the se in terrupts, I elim ina ted th e ha rdw are that supports them from my replica. My replica implements the remaining 3 interrupts: KEYRUPT, T3RUPT, and DSRUPT (T4RU PT).
Memory
AG C m em ory is 16 -bit w ords, orga nized into 10 24 w ord ba nks. Th e low est ban k (ba nk 0 ) is erasable mem ory, originally core, but implemented in my replica as static RAM. All banks abo ve ba nk 0 are fixed m em ory (origin ally im plem ented as rope co re, but im plem ented in my replica as EPROM). AGC4 initially had 12K words of fixed memory. My replica has 15K.
Buses
The original AGC ORed everything onto the bus, and the default bus state was logical zero: Registers were som etimes cleared by reading the default state off the bus. Other tim es, seve ral reg isters w ere sim ulta neo usly read to OR the d ata. Beca use thes e tricks wont w ork well w ith tri-state b us driv ers, I identified th ese insta nces a nd a dde d logic to the A LU to h an dle th em .
Flight Software
The orig ina l Blo ck I fligh t softw are is not a vailable (at leas t, to m e). Th e Blo ck II softw are (CO LOS SU S 24 9) is av ailab le. Block II is an exten sion of th e Block I instruction set. However, most of the Block II software was originally coded as Block I, so translating the Block II code bac k to Blo ck I only in volves chan ging abou t 5% of the instru ctions b ack to their Block I equivalents. This is what I did. Back in 2002, only a portion of the COLO SSUS Block II code was available. Some key portions, such as the EXEC and WAITLIST, were missing. I coded these parts in, using inform ation from th e M.I.T. doc um ents a nd th e interface s and function al requ irem ents implied by their use in the portions of COLOSSU S that were available.
Sources
Many of these sources are now (2004) available (free!) online at http://hrst.mit.edu /hrs/apollo/pu blic/ R. Alonso, J. H. Laning , Jr. and H . Blair-Sm ith, "Preliminary M OD 3 C Program me r's Manual", E-1077, MIT Instrumentation Laboratory, Cambridge, MA, Nov. 1961. Useful information on AGC 4's predecessor: AGC 3. AGC 3 had fewer instructions (8 vs. 11) and a shorter instruction cycle (8 vs 12 timing pu lses). It is primarily helpful for its presentation of AGC B lock I program ming techniques a nd exa mp les. A. I. Green and J. J. Rocchio, "Keyboard and Display System Program for AGC (Program Sunrise)", E-1574, MIT Instrumentation Laboratory, Cambridge, MA, Aug. 1964. Flowcharts for DSKY software; no source code. Gives input codes for the DSKY keyboa rd and the output cod es for display characters and registers. E. C. Hall, "Journey to the Moon: The History of the Apollo Guidance Computer", AIAA, Reston VA, 1996. Nice information on the AGC development history with photos; R-700 (also by E.C. Hall) is a better technical summary. E. C . Ha ll, "M IT's R ole in P roject A pollo, V olu m e III, Co m pu ter S ub system ", R-700 , MIT Charles Stark Draper Laboratory, Cambridge, MA, Aug. 1972. An excellent overview of the AGC; more technical than Hall's "Journey to the Moon" book. It contains an excellent diagram of the Block II register architecture and a n ice diagram of a bit-slice of the register/bus logic. My copy from N TIS is somewhat poor quality. There is also a useful discussion of the AGC test and checkout software. A. H opkin s, "G uid an ce C om pu ter D esign , Part VI" Extracted from som e (unkn own ) larger docum ent. An excellent overview of the B lock II AGC with emp hasis on the I/O circuits. A very useful discussion of numb er rep rese nta tion an d overflow ha nd ling in th e AGC , wh ich is un con ven tion al. A. Hopkin s, R. Alonso, and H . Blair-Sm ith, "Logical Description for the Apollo G uidan ce Computer (AGC4)", R-393, MIT Instrumentation Laboratory, Cambridge, MA, Mar. 1963. My prim ary sou rce. It has a n early com plete spe cification of the A GC 4 (Bloc k I) instruction set, register transfers, and control pulses. Information on the logic design is largely absent, however. There are some internal inconsistencies and gaps in the definition of the control logic: particularly at TP12, in the memory cycle, and at the intersection of the control logic with the interrupts an d involuntary cou nters. Unfortun ately, there are few diagram s; its mostly text and tables. There are also som e exam ples of double-precision m ath routines. B. I. S avag e an d A . Dra ke, "AG C4 Ba sic T rain ing Ma nu al, V olu m e I", E-205 2, M IT Instrumentation Laboratory, Cambridge, MA, Jan. 1967. The software manual for the Block II AGC. It has a fairly complete presentation of the instruction set, but lacks example code.
Now, what?
Theres 8 more parts to this report. Download and read the parts youre interested in. Perhaps you want to build your own A GC. You can use m y software and logic designs, or develop your own. Theres lots of room for improvement in my work. You could use it as your sta rting p oint. If you like, you can contact m e at: agcproject@msn .com
Abstract
This report describes my successful project to build a working reproduction of the 1964 prototype for the Block I Apollo Guidance Computer. The AGC is the flight computer for the Ap ollo m oon lan din gs, and is the wo rlds first in tegra ted c ircuit com pu ter. I built it in my ba sem ent. It took me 4 yea rs. If you like, you can build one too. It will take you less time, and yours will be better than mine. I docum ented m y project in 9 separate .pdf files: Part 1 Part 2 Part 3 Part 4 Part 5 Part 6 Part 7 Part 8 O v ervie w : Introdu ces the p roject. CTL Module: Design and construction of the control module. PROC M odule: Design and construction of the processing (CPU) modu le. MEM Module: Design and construction of the mem ory module. IO Module: Design and construction of the display/keyboard (DSKY) m odule. Assem bler: A cross-a ssem bler for AG C softw are dev elopm ent. C+ + S imu lator: A low-level simulator that runs assemb led AGC code. Flight Software: My translation of portions of the COLOSSUS 249 flight software. Test & Che ckou t: A suite of test programs in AG C assembly langu age.
Part 9
Overview
The Control Module (CTL) has 9 subsystems: CMI, MON, CLK, SCL, TPG, SEQ, CPM-A, CPM -B, CPM -C CMI (Control Module external Interface) The CMI interfaces the other control module subsystems (described below) to external AGC modules. 40-pin IDE connectors interface to the PROC, MEM , and IO modules. Inputs from those modules are buffered to 1 LSTTL load. MO N (A GC M onitor) The monitor subsystem has the front-panel switches that control AGC operation, and also implements the pow er-up reset circuit. CLK (Clock) The AGC is controlled by a 2.048 MHz crystal clock . The cloc k is divid ed to produce a 2-phase, non-overlapping 1.024 MH z AGC system clock for nom inal operation. For test purpo ses, a low-frequency RC clock can also be selected, or the clock can be single-stepped. SCL (Scaler) The 1.024 MHz AGC clock is divided by two to produce a 512 kHz signal called the MASTER FREQUENC Y; this signal is further divided through a SCALER, first by five to produce a 102.4 kHz signal. This is then divided by two through 17 successive stages called F1 (51.2 kH z) through F17 (0.78 125 H z). The F10 stage (100 Hz) is fed back into the AGC to increment the real-time clock and other priority counters in the PROC module. The F17 stage is used to intermittently run the AGC when it operates in the STANDBY mode. TPG (Tim e Pu lse Gen erator) AGC instructions are implemented in groups of 12 steps, called timing pulses. The timing pulses, named TP1 through TP12, are produced by the Time Pulse Generator (TPG). Each set of 12 timing pulses is called an instruction subsequence. Simple instructions, such as TC, execute in a single subsequence of 12 pulses. More complex instructions require several subseq uences. SEQ (Seq uen ce Ge nerato r) The sequence generator has the SQ register, which holds the next op-code, and the CTR
register--a counter used to count instruction subsequences during multiplication. The sequence generator also has the branch register (BR) which controls conditional processing during instruction execution, and the STAGE registers (STA and STB) which select the instruction subsequences for complex instructions that have more than one subsequ ence. CPM-A (Control Pulse Matrix A) The CPM-A is the com bina tiona l logic matrix that imp lemen ts most of the control logic. It is driven by inputs from the SQ register (which selects the instruction), the STB stage register (which selects the instruction subsequence), and the BR branch register (which selects conditional steps in a subseq uence). CPM-B (Control Pulse Matrix B) The CP M-B decodes read and write control signals for special me mo ry location associated w ith input/ou tput registers, central registers (A, Q, Z, and LP), and the editing registers used for rotation and shifting. CPM-C (Control Pulse Matrix C) The CPM -C decodes control signals primarily associated with interrupts, the mem ory cycle, and th e selection of new instruction s and instruction subsequ ences.
This is a functiona l diagram show ing the interrelationsh ips betwe en the Tim e Pulse Gen erator (TP G), the Con trol Pulse Ma trix (CPM -A, B, an d C), a nd th e registers th at are in the Sequ ence Generator (SE Q). The d iagram is m ine, bu t the style is borrowed from original AGC documentation: con trol sig nals are represented by diamonds. The arrows show the direction of data flow. When a control signal is asserted, data is allow ed to flow through the diamon d. For example, when WSQ is asserted, the opcode is written from th e Rea d/W rite bus into the SQ regis ter. Registers (LOOPC TR, STA, STB, SQ, BR, and SN I) are represented by rectangles. The lower bit of the 2-bit STA register is set by ST1. The upper bit is set by any one of the 3 control signals flowing into it. The STA register is cleared by CLRSTA. Wh en W STB is asserted, the S TA register is copied to STB . STB an d the SQ register select the instruction subsequence. The instruction subsequence, time pulse generator, BR register, and SNI all feed into the Control Pulse M atrix to select the active control pulses. The diag ram w as develope d by an alyzing th e R-39 3 docum ent. It was one of m y first diagrams; a sort-of conceptual breakthrough that became my gateway for understanding the AGC control modu le.
The instruction subsequences executed by the AGC are shown in this diagram. Each yellow circle is a subseq uence; a set of 12 steps, with each step generating 0-5 control pulses. Eleven steps (TP 1-T P11 ) are in the yellow circle; the 12 th step, which selects the next subseq uence (TP12), is in the orange circle. This is discussed in m ore deta il in the TPG, SEQ, and C PM-A subsystem s.
A late a dditio n to the CTL d esign fixed a p roblem with the read bus lo gic. Du e to propa gation delay s (and som e poor d esign on m y part), th e tri-state bu ffers from m ultiple registers were simultaneously enabled for brief periods causing some transients. I kludged in a design change that suppressed output to the read bus during CLK1, thereby giving the bus control logic time to settle.
J100-CTL: CTL-to-PROC I/F J100 is a 40-pin IDE ribbon cable that connects the CTL m odule to the PROC m odule. OUT PUTS (from CTL): PIN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 signal WA3 WA2 WA1 WA0 RA3 RA2 RA1 RA0 WZ WYx WY WX WQ WOVR WOVI WOVC WLP WB WA LP WA F10X R24 R22 R2 R1C R1 RZ RU RSCT RSB RRPA RQ RLP RC RB14 RB RA KRPT CI fu ll n am e WRITE ADDR 3 (74) WRITE ADDR 2 (73) WRITE ADDR 1 (72) WRITE ADDR 0 (71) READ ADDR 3 (60) READ ADDR 2 (59) READ ADDR 1 (58) READ ADDR 0 (57) WRITE Z (50) WRITE Y NO RESET (49) WRITE Y (48) WRITE X (47) WRITE Q (45) WRITE OVF (41) WRITE OVF RUPT INH (40) WRITE OVF CNTR (39) WRITE LP (38) WRITE B (36) WRITE A/LP (35) WRITE A (34) F10 SCALER ONESHOT READ 24 (25) READ 22 (24) READ 2 (23) READ 1 COMP (22) READ 1 (21) READ Z (20) READ U (19) READ CNTR ADDR (18) READ SIGN (17) READ RUPT ADDR (16) READ Q (15) READ LP (13) READ C (11) READ BIT 14 (10) READ B (9) READ A (8) KNOCK DOW N RUPT (6) SET CARRY IN (1) state definition 0=W rite reg at address 3 (LP) 0=Write reg at address 2 (Z) 0=Write reg at address 1 (Q) 0=Write reg at address 0 (A) 0=Read reg at address 3 (LP) 0=Read reg at address 2 (Z) 0=Read reg at address 1 (Q) 0=Read reg at address 0 (A) 0=W rite Z 0= W rite Y (do n ot reset) 0=W rite Y 0=W rite X 0=W rite Q 0=W rite overflow 0= W rite overflow RU PT inh ibit 0=W rite overflow counter 0=W rite LP 0=W rite B 0=W rite A and LP 0=W rite A 1=timed out (100.0 Hz) 0=Read 24 0=Read 22 0=Read 2 0=R ead 1 comp limented 0=Read 1 0=Read Z 0=Read sum 0=R ead selected cou nter address 0= Rea d sign bit 0=R ead RU PT add ress 0=Read Q 0=R ead LP 0=Read C 0=Read bit 14 0=Read B 0=Read A 0= Kn ock do wn Rup t priority 0= Carry in
J101-CTL: CTL-to-PROC I/F J101 is a 40-pin IDE ribbon cable that connects the CTL m odule to the PROC m odule.
INPU TS (to CTL ): PIN 21 22 23 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 signal SB_01 SB_02 IRQ WB_01 WB_02 WB_03 WB_04 WB_05 WB_06 WB_07 WB_08 WB_09 WB_10 WB_11 WB_12 WB_13 WB_14 WB_15 WB_16 fu ll n am e SUB SEL 01 SUB SEL 02 INT RQST WRITE BUS 01 WRITE BUS 02 WRITE BUS 03 WRITE BUS 04 WRITE BUS 05 WRITE BUS 06 WRITE BUS 07 WRITE BUS 08 WRITE BUS 09 WRITE BUS 10 WRITE BUS 11 WRITE BUS 12 WRITE BUS 13 WRITE BUS 14 WRITE BUS 15 WRITE BUS 16 state definition SB_01 is LSB; SB_02 is MSB 00=no counter; 01=PINC; 10=MINC 0=interrupt requested. (lsb)
OUT PUTS (from CTL): PIN 1 2 3 4 5 6 7 8 19 20 signal R2000 WPCTR RPT INH CLRP CLINH1 CLINH GENRST CLK1 CLK2 fu ll n am e READ 2000 (101) WRITE PCTR (98) READ RUPT (94) SET INHINT (93) CLEAR RPCELL (92) CLEAR INHINT1 (88) CLEAR INHINT (87) GENERAL RESET (86) CLOCK1 CLOCK2 state definition 0=Read 2000 0=W rite PCTR (latch priority counter sequence) 0=Read RUPT opcode 0=Set INHINT 0=Clear RPCE LL 0=Clear INHINT1 0=Clear INHINT 0=G eneral Reset 1.024 MHz AGC clock 1 (normally low) 1.024 MHz AGC clock 2 (normally low)
J102-CTL: CTL-to-MEM I/F J102 is a 40-pin IDE ribbon cable that connects the CTL m odule to the MEM m odule.
INPU TS (to CTL ): PIN 31 32 33 34 35 36 37 38 38 40 signal EQU_16 EQU_17 GTR_17 EQU_25 GTR_27 GTR_1777 AD_1 AD_2 AD_3 AD_4 fu ll n am e ADDRESS ADDRESS ADDRESS ADDRESS ADDRESS ADDRESS ADDRESS ADDRESS ADDRESS ADDRESS state definition 0=CADR in register S = 016 0=CADR in register S = 017 0=CADR in register S > 017 0=CADR in register S = 025 0=CADR in register S > 027 0=CADR in register S > 01777 where AD_4 is MSB, AD_1 is LSB: (low-order bits of address)
= 016 (1) = 017 (2) > 017 (3) = 025 (4) > 027 (5) > 01777 (6) (1) (2) (3) (4)
OUT PUTS (from CTL): PIN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 signal WE S BW G GENRST W23 W22 W21 W20 WGn WBK RBK WS WP2 WPx WP WGx TP RP2 RG GP CLG CLK2 CLK1 NPURST SW CLK FCLK fu ll n am e WRITE EMEM (97) WRITE G (95) GENERAL RESET (86) WRITE ADDR 23 (85) WRITE ADDR 22 (84) WRITE ADDR 21 (83) WRITE ADDR 20 (82) WRITE G NORMAL (81) WRITE BNK (80) READ BNK (70) WRITE S (46) WRITE P2 (44) WRITE P NO RESET (43) WRITE P (42) WRITE G NO RESET (37) TEST PARITY (30) READ PARITY 2 (14) READ G (12) GEN PARITY (5) CLR G (2) CLOCK2 CLOCK1 POWER U P RESET DEBOUNCE CLOCK CLOCK MODE state definition 0=W rite E-MEM from G 0= W rite G from m em ory 0=G eneral Reset 0=Write into SL 0=W rite into CYL 0=Write into SR 0=W rite into CYR 0=W rite G (norm al gates) 0=W rite BNK reg 0=R ead BNK reg 0=W rite S 0=W rite P2 0= W rite P (do n ot reset) 0=W rite P 0= W rite G (do not reset) 0= Test pa rity 0=Read parity 2 0=Read G 0= Gen erate Pa rity 0= Clear G 1.024 MHz AGC clock 2 (normally low) 1.024 MHz AGC clock 1 (normally low) 0=reset, 1=normal operation. low freq clk for switch debou nce 1= free-runn ing clk mo de; 0= sing le clk mode
J103-CTL: CTL-to-I/O I/F J100 is a 40-pin IDE ribbon cable that connects the CTL m odule to the I/O m odule.
INPU TS (to CTL ): PIN 40 signal OUT1_8 fu ll n am e STANDBY ENA BLED state definition 1=standby enabled; works with STANDBY ALLOW ED sw itch
OUT PUTS (from CTL): PIN 1 2 3 5 6 7 8 9 20 signal CLK1 CLK2 NSA GENRST WA11 WA10 RA11 RA4 STBY fu ll n am e CLOCK1 CLOCK2 STANDBY ALLOW ED GENERAL RESET (86) WRITE OUT1 (76) WRITE OUT0 (75) READ OUT1 (66) READ IN0 (61) STANDBY state definition 1.024 MHz AGC clock 1 (normally low) 1.024 MHz AGC clock 2 (normally low) 0=standb y allowed 0=clear the DSKY, OUT1, and OUT2. 0=write into OUT1 from write bus 0=write into OUT0 (DSKY) from write bus 0=output OUT1 register to read bus 0=output IN0 register to read bus 0= AG C is in th e stan dby state
STEP MODE SW
CLOCK MODE SW
STANDBY ALLOWED SW
INST STEP SW
CLOCK STEP SW
MASTER RESET SW
MON OUTPUTS:
signal NRUN INST NSTEP NSA MCLK FCLK NPURST SENAB fu ll n am e RUN /HALT INST STEP MODE SINGLE STEP STANDBY ALLOW ED CLOCK STEP CLOCK MODE POWER U P RESET SCALER ENABLE state definition 0=run, 1= step 1=instruction step, 0=sequen ce step 0=step (momentary) 0=standb y allowed 1= step (m om enta ry); trigge rs a sing le clock pulse. Ignored if FCLK is 1. 1=continuous clock output at 1.024 MHz, 0=sin gle clock 0=reset, 1=normal operation. 1= ena ble cou nting ; 0= hold
Clo ck Co ntrol: RATE Controls the slow clock rate when the 1MHZ/SLOW switch is in the SLOW position. Selects the free-running clock rate when the RUN/STEP switch is in the RUN position. The 1M HZ po sition gates a 2M Hz signa l into the 2-ph ased clock which produces a 1M Hz 2-phased clock rate. The SLOW position gates a low frequency clock; the frequency is controlled by RATE. Selects a free-running (RUN) or a single-stepped (STEP) clock. In the RUN position, the rate is controlled by the 1MHZ/SLOW switch. In the STEP position, the clock steps each time the STEP button is depressed. Manually steps the clock when the RUN/STEP switch is in the STEP position. The clock is 2-phased, so each press steps an alternate phase.
1MHZ/SLOW
RUN/STEP
STEP
Scaler: ENAB/DISAB F10 F13 F17 Enables or disables the SCALER. Manually triggers the F10 stage of the SCALER. Manually triggers the F13 stage of the SCALER. Manually triggers the F17 stage of the SCALER.
Ex ec ution Co ntrol: RUN/STEP In the RU N position, the A GC free-runs at a rate determ ined by th e clock controls. In the STEP position, the AGC single-steps to the next instruction or next sequence when the STEP button is depressed; the rate is determined by the clock controls. Selects whether the AGC single-steps all the way to the next instruction (INST) or just to the next sequence (SEQ). Some instructions, such as TC, have a sin gle sequen ce; on these instructions, the sw itch has the sam e effect in either position. Single-steps the AGC when the RUN/STEP switch is in the STEP position. Reset the entire AGC. Puts the TPG into the standby state.
INST/SEQ
STEP RESET
Standby: ALLOW/DISA The ALLOWED position authorizes the AGC software to put the AGC in standby mode. The AGC is released from standby mode by a signal from F17 in the SCALER. If the scaler switch is in the DISAB position, the scaler is disabled, and the A GC will rem ain in the stan dby state. W hen the stan dby switch is in the DISAB position, the standby mode is inhibited.
Normal Operation: Set the following switch positions for nominal operation: switch 1MHZ/SLOW RUN/STEP ENAB/DISAB RUN/STEP ALLOW/DISA position 1MHZ RU N (cloc k contro l) EN AB (scaler) RU N (ex ecution control) ALLOWED (standby)
RESET SCALER DISAB (SLOW) CLOCK CO NTROL RATE Clock control: 1MHZ/SLOW
CTL INDICATORS
The CTL module has a panel of indicator lamps (LEDs) to show the state of CTL registers and critical logic signals. These indicator lamps show the curren t state of all registers and some add itiona l, im portan t logic signals produced by the CTL mod ule. The matrix of lamps in the lower portion show active subseq uences. M uch of the con trol logic is negative (active low) where an illu m in ated la m p means that the signal is NOT asserted. At the time the photo was taken the AGC was running the COLOSSUS 249 flight software load, executing Verb 16, Noun 36: a monitor verb which displays the AGC real time clock.
CLK (Clock)
The original AGC used asynchronous logic driven by a 4-phase clock. This recreation uses synchronous logic driven by a 2-phase nonoverlap ping clock. Th e sync hron ous clo ck logic wa s desig ned to produ ce the follow ing sta te transitions: FFA 0 0 1 1 FFB 0 1 1 0
The outputs of FFA and FFB are decoded by combinational logic to produce the nonoverlappin g pha se 1 and phase 2 clock signals. The se que nce is a rrang ed so th ere is a sing le logic lev el transitio n for each state tran sition to prevent transients.
CLK INPUTS:
I/F signal MON: MCLK FCLK NPURST fu ll n am e CLOCK STEP CLOCK MODE POWER U P RESET state definition 1= step (m om enta ry); trigge rs a sing le clock pulse. Ignored if FCLK is 1. 1= con tinu ous clock outp ut at 1.024 MH z, 0=single clock whenever MCLK is 1. 0=pow er up reset
OUTPUTS:
signal CLK1 CLK2 fu ll n am e CLOCK1 CLOCK2 state definition 1.024 MHz AGC clock 1 (normally low) 1.024 MHz AGC clock 2 (normally low)
SCL (Scaler)
The 1 .024 MH z AG C clock is divided by two to produce a 512 kHz signal called the MA STE R FR EQU ENC Y; this signal is further divided through a SCALER, first by five to produce a 102.4 kHz signal. This is then divided by two through 17 successive stages called F1 (51.2 kHz) through F17 (0.78125 Hz). The F10 stage (100 Hz) is fed back into the AGC to increment the real-time clock and other priority counters in the PROC m odu le. The F 17 sta ge is used to intermittently run the A GC wh en it op erates in the STAND BY m ode. The F10, F13, and F17 outputs of the SCALER feed into a synchronous one-shot that produces a short output pulse on the rising edge of the in put.
SCALER (SCL) ONE-SHOT LOGIC DESIGN Boolean operators: * (AN D), + (OR ), ' (NOT) Scale r Divid e-by- 10 E xcitation Table : The divide-by-10 state machine is implemented with a 74161 parallel counter. Control Mode for 74 16 1 Pa rallel Cou nter: NPE 0 1 1 CET x 1 0
State 0 1 2 3 4 5 6 7 8 9
Current D C B A 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1
Next D C B A 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1 0 0 0 0
NPE 1 1 1 1 1 1 1 1 1 0
Par In CET D C B A 1 1 1 1 1 1 1 1 1 x 0 0 0 0
On e-sho t Excitatio n Ta ble: The on e-shot state m achine is im plem ented w ith two J-K F Fs.
FN is th e one -shot trig ger; Q (A) is th e one -shot o utpu t. Cur B A 0 0 0 0 Inp FN 0 1 Nxt B A 0 0 0 1 ffB J K 0 x 0 x ffA J K 0 x 1 x
State IDLE
HIGH
0 1 0 1 1 0 1 0 1 1 1 1
0 1 0 1 0 1
1 0 1 0 0 0 1 0 x x x x
1 x 1 x x 1 x 0 x x x x
x 1 x 1 0 x 0 x x x x x
LOW
UNUSED
The e xcitation table a nd lo gic eq uatio ns w ere derive d from the CL K su bsyste m state machine which also performs a one-shot function. The CLK subsystems's FCLK signal was factored out by setting it to zero. The MCLK input is the one-shot trigger; it was renamed FN. ff(B) J = QA ff(B) K = FN' ff(A) J = QB' * FN ff(A) K = QA
SCL INPUTS:
I/F CLK: signal CLK1 MON: SW-SEN 0= hold NPURST POWER U P RESET 0=pow er up reset SCALER ENABLE 1=enable counting; fu ll n am e CLOCK1 state definition 1.024 M Hz AG C clock
SCL OUTPUTS:
signal F10X F13X F17X fu ll n am e F10 SCALER ONESHOT F13 SCALER ONESHOT F17 SCALER ONESHOT Hz) SCALER SCALER SCALER SCALER SCALER SCALER SCALER SCALER SCALER SCALER SCALER SCALER SCALER SCALER SCALER SCALER SCALER OUT OUT OUT OUT OUT OUT OUT OUT OUT OUT OUT OUT OUT OUT OUT OUT OUT F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 state definition 1=timed out (100.0 Hz) 1=timed out ( 12.5 Hz) 1=timed out ( 0.78125
51.2 KHz square wave 25.6 KHz square wave 12.8 KHz square wave 6,4 KHz square wave 3.2 KHz square wave 1.6 KHz square wave 0.8 KHz square wave 0.4 KHz square wave 0.2 KHz square wave 0.1 KHz square wave (100 Hz) 50.0 Hz square wave 25.0 Hz square wave 12.5 Hz square wave 6.25 Hz square wave 3.125 Hz square wave 1.5625 Hz square wave 0.78125 Hz square wave
Note: One shot outputs are active for one clock pulse. State transitions occur on the rising edge of CLK1
TPG_5 = STEP + RUN TPG Excitatio n Ta ble: Con trol M ode for 74 16 1 Pa rallel Cou nter: NPE 0 1 1 CET x 1 0
*denotes active low Current D C B A 0 0 0 0 *Current Decoder NSTBY TPG_x 0 1 2 3 4 5 0 x x x x x 1 x x x x x x 0 x x x x x 1 x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x Next D C B A 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 1 1 1 0 0 1 1 0 0 1 1 0 0 1 0 1 0 1 0 1 0 1 0 1 Par In D C B A
State STBY
*NPE 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
CET 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1
PWRON0 0 0 1
NPWRON
TP1 TP2 TP3 TP4 TP5 TP6 TP7 TP8 TP9 TP10 TP11
0 0 0 0 0 0 1 1 1 1 1
0 0 1 1 1 1 0 0 0 0 1
1 1 0 0 1 1 0 0 1 1 0
0 1 0 1 0 1 0 1 0 1 0
NTP1 NTP2 NTP3 NTP4 NTP5 NTP6 NTP7 NTP8 NTP9 NTP10 NTP11
TP12
1 1 0 1
NTP12
x x x 1 x x x x 1 0 x x x x 0 0 x x x x x x 0 x x x x x 1 x x x x x x 1 x x x x x 0
0 0 0 0 0 0 1 0 1 1 1 0 1 1 1 0 1 1 1 1 0 0 1 0 1 1 1 1
0 0 1 1 1 0 1
x x 1 0 1 x 0
0 0 0 0 0 0 1 0
SRLSE 1 1 1 0
NSRLSE
W AIT
1 1 1 1
NW AIT
0 0 1 0
M ax term s: NP E = (NTP 12 + TPG_ 3') * (NT P1 2 + TPG_ 2' + TPG_ 3) * (NW AIT + TPG_ 5') CET = (NSTBY + TPG_0) * (NPWRON + TPG_1) * (NSRLSE + TPG_4) * (NWAIT + TPG_5)
TPG INPUTS:
I/F signal MON: NRUN INST 0=sequen ce step NSTEP FCLK NSA NPURST CLK: CLK1 SEQ: SNI SCL: F17X F13X OUT: OUT1_8 STANDBY ENA BLED 1=standby enabled; works with STANDBY ALLOW ED sw itch F17 SCALER ONESHOT F13 SCALER ONESHOT 1=timed out 1=timed out SELECT NEXT INST 1=select next instruction CLOCK1 1024 MHz AGC clock 1 fu ll n am e RUN /HALT INST STEP MODE SINGLE STEP CLOCK MODE STANDBY ALLOW ED POWER U P RESET state definition 0=run, 1= step 1=instruction step, 0=step (momentary) 1= contin uou s, 0= sing le clock 0=standb y allowed 0=pow er up reset
TPG OUTPUTS:
signal TPG_Q3 TPG_Q2 TPG_Q1 TPG_Q0 fu ll n am e TPG STATE state definition where Q0 is LSB, Q3 is MSB: 00 = STBY 01 = PWRON 02 = TP1 03 = TP2 04 = TP3 05 = TP4 06 = TP5 07 = TP6 08 = TP7 09 = TP8 10 = TP9 11 = TP10 12 = TP11 13 = TP12 14 = SRLSE 15 = W AIT
Som e back-of-the-en velope desig n that w ent into the bran ch register logic is shown in the next few charts. This is the conceptual design for the branch register. It has 2 flip-flops nam ed B R2 and BR1 . The flip-flop s are set by the con trol signa ls shown as diamonds in this diagram.
The J and K inputs to the BR1 flip-flo p are deve loped in this chart.
This chart shows the J an d K in puts to the BR2 flip-flop. Logic to sen se a 1's compliment minus zero from the w rite bus is also developed.
Here are some charts showing the stage register design. This is the conceptual design. Th ere are (2) 2-bit stage registers: ST A and STB .
This is my initial cut at STA and ST B. My initial attempt at CLSTB is scratched out and then developed into the correct solution on the later charts.
This is the J input to the STA2 flipflop. The initial design is at the top. In the m idd le, I D eM org an iz e it u sin g so me bubble-pushing to get the final im p lem en ta tio n a t th e b otto m.
Heres the J and K inp uts to STB1 and STB2. This is the logic that transfers the contents of the STA flipflops to STB.
The J a nd K inpu ts to STB 1 an d ST B2 m ove th roug h a m ulti-step DeM organ izing process in the next 2 charts to reach their final state:
SEQ INPUTS:
I/F CLK: signal CLK2 CPM-C: GENRST WSQ CLISQ CLSTA WSTB CLSTB SETSTB CPM-A: TRSM TSGN TSGN2 ST1 ST2 CLCTR CTR TMZ TOV NISQ fu ll n am e CLOCK 2 state definition data transfer occurs on falling edge
GENERAL RESET WRITE SQ CLEAR SNI CLEAR STA WRITE STB CLEAR STB SET ST1
0=G eneral Reset 0=Write SQ 0=Clear SNI 0= Clear sta te cou nter A (STA) 0= W rite sta ge co un ter B (STB) 0= Clear sta te cou nter B (STB) 0=Set the ST1 bit of STB
TEST RESUME TEST SIGN TEST SIGN 2 SET STAGE 1 SET STAGE 2 CLR LOOP CTR INCR LOOP CTR TEST MINUS ZERO TEST OVF NEW INSTRUCT SQ reg
0=Test for resume 0=Test sign 0=Test sign 2 0=Stag e 1 0=Stag e 2 0=Clear loop counter 0=Loop coun ter 0= Test for m inu s zero 0=Test for overflow 0=New instruction to the
WBUS: WB_01 ... ... WB_14 WB_15 WB_16 ADR: EQU_25 ADDRESS = 025 0=CADR in register S evaluates to = 025 WRITE BUS 01 WRITE BUS 14 WRITE BUS 15 WRITE BUS 16
US (overflow) bit for write bus SG (sign) bit for write bus
SEQ OUTPUTS:
I/F signal CPM-A: BR1 BR2 fu ll n am e BRANCH REG 1 BRANCH REG 2 state definition where BR00 BR01 BR10 BR11 BR1 =0 =1 =2 =3 is MSB, BR1=0, BR1=0, BR1=1, BR1=1, BR2 is LSB BR2=0 BR2=1 BR2=0 BR2=1
INST REG
STAGE REG
CTR subsequence (2) register SQ (4) register STB (2) register SG (4) register BR1 (1) register BR2 (1)
Bits 7-14 (STB, SQ, and CTR ) select the instruction subsequence. Bits 1-6 select the control pulses (control logic signals) that are asserted from that subsequ ence.
CTR (EPROM address bits 13-14) The CTR signal has 2 lines: SB_02 is the MSB; SB_01 is the LSB. The signal comes from the CTR subs ystem in the P RO C m odu le. It indicate s wh ether p rocessin g ne eds to b e briefly interrup ted to in sert a PINC or MIN C su bseq uen ce to increm ent or d ecrem ent a p riority cou nter. CTR00: SB_02=0, SB_01=0 no coun ter; do the next sub sequen ce CTR01: SB_02=0, SB_01=1 PINC CTR10: SB_02=1, SB_01=0 MINC CTR11: SB_02=1, SB_01=1 both; they cancel out, so do the next subseq uence
Register SQ (EPROM address bits 9-12) The 4-bit SQ register holds the currently executing instruction. The code in the SQ register is the sam e as the op cod e for these four instructions. NMEM TC CCS INDEX XCH SQ REG 00 01 02 03 OPCODE 00 01 02 03 USAGE TC K CCS K INDEX K XCH K DESCRIPTION CYCLES Transfer Control 1 MCT Count, Compare, Skip 2 MCT Index 2 MCT Exchange 2 MCT
The SQ register code for these four instructions is the op code + 010 (octal). This happens because all of these instructions have bit 15 set (the sign (SG) bit) while in mem ory. When
the instruction is copied from memory to the memory buffer register (G) to register B, the SG bit moves from bit 15 to bit 16 and the sign is copied back into bit 15 (US). Therefore, the CS op code (04) becomes (14), and so on. NMEM CS TS AD MASK SQ REG 014 015 016 017 OPCODE 04 05 06 07 USAGE CS K TS K AD K MASK K DESCRIPTION Clear and Subtract Transfer to Storage Add Bitwise AND CYCLES 2 MCT 2 MCT 2 or 3 MCT 2 MCT
These are the three extended instructions. They are accessed by executing an INDEX 5777 before each instruction. By convention, address 5777 contains 47777. The INDEX instruction adds 47777 to the extended instruction to form the SQ op code. For example, the INDEX adds 4 to the 4 op code for MP to produce the 11 (octal; the addition generates an end-arou nd-carry). SQ reg ister code (the 7777 part is a negative zero). NMEM MP DV SU SQ REG 011 012 013 OPCODE 04 05 06 USAGE MP K DV K SU K DESCRIPTION Multiply Divide Subtract CYCLES 10 MCT 18 MCT 4 or 5 MCT
STB (EPROM address bits 7-8) The stage register B (STB) selects the subsequence for a given instruction. Some instructions have m ultiple subsequences; others (TC) have only one. The sta ge reg ister has 2 bits: ST B2 is th e MS B; S TB1 is the LS B. All in struction s initiallly begin with the stage register set to zero. If an instruction needs more than one subsequ ence, the stage register is incremented to select the next subsequence. STB00: STB2=0, STB1=0 STB01: STB2=0, STB1=1 STB10: STB2=1, STB1=0 STB11: STB2=1, STB1=1
INSTRUCTION SUBSEQUENCES
There are 22 in struction subseq uences: TC0 CCS0 CCS1 NDX0 NDX1 RSM3 XCH0 CS0 TS0 AD0 MASK0 MP0 MP1 0 1 2 3 4 5 6 7 8 9 10 11 12
13 14 15 16 17 18 19 20 21
If the CTR signals are 01 (SB_02=0, SB_01=1) the PINC subsequence is selected. If the CTR signals are 10 (SB_02= 1, SB_01= 0) the MINC subsequen ce is selected. Otherwise, subsequences for each instruction are selected using the 4-bit SQ register and the 2-bit stage register (STB2, STB1, where STB2 is the MSB). Some instructions (TC) have only one subsequence. At the start of each instruction, the stage counter is initially set to zero. The interrupt call and resturn sequences are also stored at SQ=00. SQ 00: 01: 02: 03: 04: 05: 06: 07: 10: MP DV SU CS TS AD MASK 11: 12: 13: 14: 15: 16: 17: STB00 TC0 CCS0 NDX0 XCH0 ---------------MP0 DV0 SU0 CS0 TS0 AD0 MASK0 STB01 RUPT1 CCS1 NDX1 ------------------MP1 DV1 ---------------STB10 STD2 ------STD2 ------------------STD2 STD2 STD2 STD2 STD2 STD2 STB11 RUPT3 ---RSM3 ------------------MP3 -------------------
3-6: 2: 1:
The colu m n on the fa r left is th e step ; colu m ns to the rig ht sp ecify th e con trol pulse s tha t are asserted for that step. Som e steps have n o control pulses.
subsequence TP1 TP2 TP3 TP4 TP5 TP6 TP7 TP8 TP9 TP10 TP11
TC0: RB WG RA
WY ---WOVI
WS -------
CI -------
----------
RG RZ RB RU NISQ
WB GP WG -------
WP TP ----------
----------------
subsequence CCS0: TP1 RB TP2 RZ TP3 WG TP4 TP5 TP6 RG TP7 BR00, RC BR01, RC BR10, RB BR11, RB TP8 BR00, GP BR01, R1 BR10, R2 BR11, R1 TP9 RB TP10 BR00, RC BR01, W A BR10, RB BR11, W A TP11 RU
WS WY ----
----------
----------
----------
WB ---------------GP GP WX WG ------------WZ
WP ---------------------TP, -------------------
CCS1: RZ WG RU RA RG RU
WY ---WZ WY RSC WB
WS ------CI WB GP
CI ---------WP TP
-------------------
RC RG
WA RSC
WOVI WB
---NISQ
-------
subsequence TP1 TP2 TP3 TP4 TP5 TP6 TP7 TP8 TP9 TP10 TP11
NDX0: RB WG RA
WS ---WOVI
----------
----------
----------
RG GP RB TRSM ST1
WB ---WG -------
WP -------------
----------------
subsequence TP1 TP2 TP3 TP4 TP5 TP6 TP7 TP8 TP9 TP10 TP11
NDX1: RZ WG RU RB RG RB RB RU
WS ---------WB GP WG WOVI
CI ---------WP TP ---NISQ
-------------------------
subsequence TP1 TP2 TP3 TP4 TP5 TP6 TP7 TP8 TP9 TP10 TP11
RSM3: R24 WG
WS ----
-------
-------
-------
RG
WZ
----
----
----
NISQ
----
----
----
----
XCH0: RB RA WG WP2
WS WP -------
-------------
-------------
-------------
RG GP RA RB ST2
----------------
subsequence TP1 TP2 TP3 TP4 TP5 TP6 TP7 TP8 TP9 TP10 TP11
CS0: RB WG
WS ----
-------
-------
-------
RG GP RB RC ST2
WP, -------------
----------------
subsequence TS0: TP1 RB TP2 RA TP3 WG TP4 BR00, ---BR01, RZ BR10, RZ BR11, ---TP5 BR00, ---BR01, R1 BR10, W A BR11, ---TP6 TP7 BR00, ---BR01, RU BR10, RU BR11, ---TP8 GP TP9 RB TP10 RA TP11 ST2 subsequence TP1 TP2 TP3 TP4 TP5 TP6 TP7 TP8 TP9 TP10 AD0: RB RA WG
---WP ----------------------------------------------------
----------------------------------------------------------
(overflow) (underflow)
WS WY ----
----------
----------
----------
RG RB RB
RSC WX WSC
WB GP WG
WP TP ----
----------
TP11
RU
WA
WOVC
ST2
WOVI
SU B_ MA SK 0 perform s a log ical A ND usin g D eM orga n's Th eorem : the inp uts a re inv erted , a logica l OR is perform ed, an d the res ult is inv erted. Th e im plem enta tion of the OR (at TP8 ) is somewhat unorthodox: the inverted inputs are in registers U and C. The OR is achieved by gating both registers onto the read/write bus simultaneously. (The bus only transfers logical 1's; register-to-register transfers are performed by clearing the destination register and then transferring the 1's from the sou rce register to th e destin ation ). Wh en th e 1's from both registers are sim ultan eous ly gate d on to the b us, the w ord on the bu s is a logica l OR of both regis ters. subsequence TP1 TP2 TP3 TP4 TP5 TP6 TP7 TP8 TP9 TP10 TP11 MASK0: RB RA WG RC
WS WB ---WY
-------------
-------------
-------------
RG RU RA RC
RSC RC WB WA
WB WA ---ST2
WP GP ---WOVI
---TP -------
subsequence MP0: TP1 RB TP2 RA TP3 RSC TP4 BR00, RB BR01, RB BR10, RC BR11, RC TP5 RLP TP6 TP7 BR00, RG BR01, RG BR10, RG BR11, RG TP8 BR00, GP BR01, GP BR10, RC BR11, RC TP9 RU TP10 BR00, RA BR01, RA BR10, RA BR11, RA TP11 BR00, ST1 BR01, R1 BR10, RU BR11, RU
WS WB WG WLP WLP WLP WLP WA WY WY WB WB TP TP WY WY WB WLP RB14 WLP RB14 WA LP ST1 ST1 ST1
----------------------------------------------------------------------------
subsequence MP1: TP1 RA TP2 RLP TP3 BR00, ---BR01, ---BR10, RB BR11, RB TP4 RA TP5 RLP TP6 RU TP7 RA TP8 BR00, ---BR01, ---BR10, RB BR11, RB TP9 RLP TP10 RA TP11 RU
---TSGN ---------------------------------------CTR WA LP
----------------------------------------------------
----------------------------------------------------
subsequence MP3: TP1 RZ TP2 RLP TP3 WG TP4 RU TP5 RA TP6 BR00, ---BR01, ---BR10, RB BR11, RB TP7 RG TP8 RLP TP9 RB TP10 RA TP11 RU
WS ------------------------WB GP WG ---NISQ
CI ------------------------WP TP ----------
-------------------------------------------
subsequence DV0: TP1 RB TP2 RA TP3 RSC TP4 BR00, RC BR01, RC BR10, ---BR11, ---TP5 BR00, R1 BR01, R1 BR10, R2 BR11, R2 TP6 RA TP7 RG TP8 RB TP9 BR00, RLP
---TSGN ------------------------------TSGN GP WB
------------------------------------WP TP ----
----------------------------------------------
TP10
TP11
RLP ------RB RB RC RC R1
WB ------------------WB
-------------------------
-------------------------
subsequence DV1: TP1 R22 TP2 RQ TP3 RG TP4 RA TP5 RLP TP6 TP7 RU TP8 BR00, ---BR01, ---BR10, RU BR11, RU TP9 BR00, RB BR01, RB BR10, RB BR11, RB TP10 RG TP11 BR00, ST1 BR01, ST1 BR10, RC BR11, RB
------RSB -------------------------------------------------
----------------------------------------------------------
subsequence TP1 TP2 TP3 TP4 TP5 TP6 TP7 TP8 TP9 TP10 TP11
SU0: RB RA WG
WS WY ----
----------
----------
----------
RG RC RB RU
RSC WX WSC WA
WB GP WG WOVC
WP TP ---ST2
---------WOVI
WY ----
WS ----
CI, ----
-------
RZ RU ST1
WG WZ ST2
----------
----------
----------
subsequence TP1 TP2 TP3 TP4 TP5 TP6 TP7 TP8 TP9 TP10 TP11
RUPT3: RZ RRPA RZ
WS WZ KRPT
------WG
----------
----------
RB ST2
WSC ----
WG ----
-------
-------
subsequence TP1 TP2 TP3 TP4 TP5 TP6 TP7 TP8 TP9 TP10 TP11
STD2: RZ WG RU
WY ---WZ
WS -------
CI, -------
----------
RG GP RB NISQ
WB ---WG ----
WP ----------
-------------
subsequence TP1 TP2 TP3 TP4 TP5 TP6 TP7 TP8 TP9 TP10 TP11
PINC: WS WG R1 RG TP WP RU RU
-------------------------
-------------------------
MINC: WS, WG WY
RSCT ---R1C
----------
----------
----------
RG TP WP RU RU
WX ------CLG WGx
WP ------WPx WOVR
----------------
----------------
Heres some of the analysis used to develop the instruction sequence decoder. This decoder takes in the STB and SQ inputs and decodes the instruction sequence for display to the ope rator.
WZ
50
Write Z
Control signa l outputs from CPM -A used as inputs to CP M-B only (not used outside of CPM ): SIGNAL RSC WSC WG # 51 52 53 DESCRIPTION Read special and central (output to B only, not outside CPM) Write special and central (output to B only, not outside CPM) Write G (output to B only, not outside CPM)
Control signa l outputs from CPM -A used as inputs to CP M-C only (not used outside of CPM ): SIGNAL SDV1 SMP1 SRSM3 # 54 55 56 DESCRIPTION Subsequence DV1 is currently active Subsequence MP1 is currently active Subsequence RSM3 is currently active
CPM-A INPUTS:
I/F TPG: signal TPG_Q3 TPG_Q2 TPG_Q1 TPG_Q0 fu ll n am e TPG STATE state definition wh ere Q3 is MS B, Q0 is LSB: 00 = STBY 01 = PWRON 02 = TP1 03 = TP2 04 = TP3 05 = TP4 06 = TP5 07 = TP6 08 = TP7 09 = TP8 10 = TP9 11 = TP10 12 = TP11 13 = TP12 14 = SRLSE 15 = W AIT
SEQ: BR1 BR2 BRANCH REG 1 BRANCH REG 2 BR1 is MSB, BR2 BR00=0:BR1=0, BR01=1:BR1=0, BR10=2:BR1=1, BR11=3:BR1=1, is LSB BR2=0 BR2=1 BR2=0 BR2=1
INST REG
STAGE REG
LOOPCNTR EQ 6
SNI
CTR: SB_01 SB_02 INT: SUB SEL 01 SUB SEL 02 SB_01 is LSB; SB_02 is MSB 00=no counter; 01=PINC; 10=MINC
INT RQST
0=interrupt requested.
RUN /HALT
0=run, 1= step
CPM-A OUTPUTS:
signal CI CLG CLCTR CTR GP KRPT NISQ RA RB RB14 RC RG RLP RP2 RQ RRPA RSB RSCT RU RZ R1 R1C R2 R22 R24 ST1 ST2 TMZ TOV TP TRSM TSGN TSGN2 WA WA LP WB WGx WLP WOVC WOVI WOVR WP WPx WP2 fu ll n am e SE T C AR RY IN CLR G CLR LOOP CTR INCR LOOP CTR GEN PARITY KNOCK DOW N RUPT NEW INSTRUCT READ A READ B READ BIT 14 READ C READ G READ LP READ PARITY 2 READ Q READ RUPT ADDR READ SIGN READ CNTR ADDR READ U READ Z READ 1 READ 1 COMP READ 2 READ 22 READ 24 SET STAGE 1 SET STAGE 2 TEST MINUS ZERO TEST OVF TEST PARITY TEST RESUME TEST SIGN TEST SIGN 2 WRITE A WR ITE A/LP WRITE B WRITE G NO RESET WR ITE LP WRITE OVF CNTR WRITE OVF RUPT INH WRITE OVF WRITE P WRITE P NO RESET WRITE P2 state definition 0= Carry in 0= Clear G 0=Clear loop counter 0=Loop coun ter 0= Gen erate Pa rity 0= Kn ock do wn Rup t priority 0=N ew instruction to the SQ reg 0=Read A 0=Read B 0=Read bit 14 0=Read C 0=Read G 0=R ead LP 0=Read parity 2 0=Read Q 0=R ead RU PT add ress 0= Rea d sign bit 0=R ead selected cou nter address 0=Read sum 0=Read Z 0=Read 1 0=R ead 1 comp limented 0=Read 2 0=Read 22 0=Read 24 0=Stag e 1 0=Stag e 2 0= Test for m inu s zero 0=Test for overflow 0= Test pa rity 0=Test for resume 0=Test sign 0=Test sign 2 0=W rite A 0=W rite A and LP 0=W rite B 0= W rite G (do not reset) 0=W rite LP 0=W rite overflow counter 0= W rite overflow RU PT inh ibit 0=W rite overflow 0=W rite P 0= W rite P (do n ot reset) 0=W rite P2
WQ WS WX WY WYx WZ
Q S X Y Y NO RESET Z
0=W rite 0=W rite 0=W rite 0=W rite 0= W rite 0=W rite
Q S X Y Y (do n ot reset) Z
OUTPUTS TO CPM -B ONLY; NOT USED OUTS IDE CPM RSC WSC WG READ SPECIAL REG WRITE SPECIAL REG WRITE G 0=Read special and central 0=W rite special and central 0=W rite G
OUTPUTS TO CPM -C ONLY; NOT USED OU TSIDE CPM SDV1 SMP1 SRSM3 SUBSEQ DV1 SUBSEQ M P1 SUBSEQ RSM3 0=Su bsequence DV 1 is selected 0=Su bsequence MP1 is selected 0=Su bsequence RSM 3 is selected
SPECIAL REGISTERS
These a dd resses called sp ecia l regis ters. A ll nu m bers are in octal. addr 00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17 Flip -Flo p reg isters A regis ter (accum ula tor) Q register Z regis ter (p rogra m cou nter) LP register IN0 inp ut reg ister 0 IN1 inp ut reg ister 1 IN2 inp ut reg ister 2 IN3 inp ut reg ister 3 OUT0 outpu t regis ter 0 OUT1 outpu t regis ter 1 OUT2 outpu t regis ter 2 OUT3 outpu t regis ter 3 OUT4 outpu t regis ter 4 BANK bank register RELINT INHINT Eraseab le m em ory reg isters CYR cycle right SR shift right CYL cycle left SL shift le ft ZRUPT BRUPT ARUPT QRUPT save save save save register register register register Z B A Q
20 21 22 23 24 25 26 27
CPM -B tran slates th e W G, RS C, an d W SC signa ls gen erated by S UB SYS TEM A into signa ls that read from o r write to these registers. The logic is given below (all num bers are in octal): if WG is asserted from CPM-A, ...and ...and ...and ...and the the the the address address address address bus bus bus bus = = = = 020: 021: 022: 023: assert:W20 assert:W21 assert:W22 assert:W23
...othe rwis e, if the add ress b us > 17: assert:W Gn (not a cen tral reg ister)
if RSC is asserted from CPM -A ...and ...and ...and ...and ...and ...and ...and ...and ...and ...and ...and ...and ...and ...and ...and ...and the the the the the the the the the the the the the the the the address address address address address address address address address address address address address address address address bus bus bus bus bus bus bus bus bus bus bus bus bus bus bus bus = = = = = = = = = = = = = = = = 00: 01: 02: 03: 04: 05: 06: 07: 010: 011: 012: 013: 014: 015: 016: 017: assert:RA0 assert:RA1 assert:RA2 assert:RA3 assert:RA4 assert:RA5 assert:RA6 assert:RA7 assert:RA10 assert:RA11 assert:RA12 assert:RA13 assert:RA14 assert:RBK do nothing do nothing
if WSC is asserted from CPM-A, ...and ...and ...and ...and ...and ...and ...and ...and ...and ...and ...and ...and the the the the the the the the the the the the address address address address address address address address address address address address bus bus bus bus bus bus bus bus bus bus bus bus = = = = = = = = = = = = 00: 01: 02: 03: 010: 011: 012: 013: 014: 015: 016: 017: assert:WA0 assert:WA1 assert:WA2 assert:WA3 assert:WA10 assert:WA11 assert:WA12 assert:WA13 assert:WA14 assert:WBK do nothing do nothing
Heres a tab le I develo ped to wo rk out th e relation ship s betw een a ddres ses an d CP M-B logic signals:
CPM-B INPUTS:
I/F signal CPM -A RSC WSC WG ADR: AD_4 AD_3 AD_2 AD_1 GTR_17 GTR_27 ADDRESS > 017 ADDRESS > 027 0=CADR in register S > 017 0=CADR in register S > 027 ADDRESS AD_4=MSB, AD_1=LSB: (low -order b its of 14-b it address) fu ll n am e READ SPECIAL REG WRITE SPECIAL REG WRITE G state definition 0=Read special and central 0=W rite special and central 0=W rite G
CPM-B OUTPUTS:
I/F signal RA0 RA1 RA2 RA3 RA4 RA5 RA6 RA7 RA10 RA11 RA12 RA13 RA14 RBK WA0 WA1 WA2 WA3 WA10 WA11 WA12 WA13 WA14 WBK fu ll n am e READ ADDR 0 (A) READ ADDR 1 READ ADDR 2 READ ADDR 3 READ ADDR 4 READ ADDR 5 READ ADDR 6 READ ADDR 7 READ ADDR 10 READ ADDR 11 READ ADDR 12 READ ADDR 13 READ ADDR 14 READ BNK WRITE ADDR 0 WRITE ADDR 1 WRITE ADDR 2 WRITE ADDR 3 WRITE ADDR 10 WRITE ADDR 11 WRITE ADDR 12 WRITE ADDR 13 WRITE ADDR 14 WRITE BNK state definition 0=R ead reg at ad dress 0 0=Read reg at address 1 (Q) 0=Read reg at address 2 (Z) 0=Read reg at address 3 (LP) 0=R ead reg at ad dress 4 0=R ead reg at ad dress 5 0=R ead reg at ad dress 6 0=R ead reg at ad dress 7 0= Rea d reg a t add ress 10 (octal) 0= Rea d reg a t add ress 11 (octal) 0= Rea d reg a t add ress 12 (octal) 0= Rea d reg a t add ress 13 (octal) 0= Rea d reg a t add ress 14 (octal) 0=R ead BNK reg 0=Write reg at address 0 (A) 0=Write reg at address 1 (Q) 0=Write reg at address 2 (Z) 0=W rite reg at address 3 (LP) 0= W rite reg at ad dress 1 0 (octa l) 0= W rite reg at ad dress 1 1 (octa l) 0= W rite reg at ad dress 1 2 (octa l) 0= W rite reg at ad dress 1 3 (octa l) 0= W rite reg at ad dress 1 4 (octa l) 0=W rite BNK reg
TP1:
assert:CLISQ
TP5:
the address bus > 17 the address bus < 2000 SDV1 or SMP1 are not asserted a ss ert: SB W G the address bus = 17 assert:INH the address bus = 16 assert:CLINH
TP6:
the address bus > 1777 SDV1 or SMP1 are not asserted a ss ert: SB W G
(not eraseable mem ory) (not a loop counter subsequence) read fixed memory into G register by TP7
the address bus > 17 the address bus < 2000 SDV1 or SMP1 are not asserted a ss ert: WE
(no t a cen tral reg ister) (not fixed memory; m ust be erasable) (not a loop counter subsequence) G register written to memory beginning at TP11; Memory updates are in G by TP10 for all normal an d extracode instruction s, but th e PINC and MIN C seq uen ces w rite to G in TP10 because they need to update the parity b it. Additional interrupts are inhibited during servicing of an interrupt; Remove the inhibition when RES UME is executed (INDEX 025)
if: then:
TP12: assert:WPCTR
Check the priority counters; service any waiting inputs on the next mem ory cycle. (if SNI is set, get next instruction) (if interrupt requested (see CPM-A for similar assertion)) Read the in terrupt ve ctor. STB <- 1. Will cause the RUPT1 subsequence to execute. (not an interrupt; a normal instruction) STB < - 0 . The CPM-A will assert RB here, which, when accompanied by WSQ (below), will read the next instruction from register B onto th e bu s. WS Q w ill write it into SQ. W rite the n ext instru ction (o n the write bu s) into the SQ regis ter. Clear STA regis ter.
if: then:
the SNI register = 1 if: then: assert:RPT assert:SETSTB else: assert:CLSTB IRQ is asserted
assert:CLINH1
Clear INHINT1. Removes inhibition of interrupts (if they were) AFTER the next instruction (not a new instruction) if previous sequence was not a PINC or MINC, get next subsequence for same instruction. if the previous sequence was PINC or MINC, we already have the subsequence, but it was interrupted by the cou nter. Copy STB < - STA. Gets next sequence for same instruction. STA <- 0
This tru th tab le show s the log ic needed at TP12 to produce the RPT, SETSTB, CLSTB, CLSTA, WSQ, WSTB, CLISQ, and CLINH1 signals, given the SNI, IRQ, NRU N, and S B inpu ts.
This chart shows the logic for som e of the m ore sim ple control pulses generated by CM P-C. S om e pu lses redu ce to states from the TPG, such as CLISQ, WPCTR, and CLINH1, which reduce to TP12.
The desig n for CLSTB is a little more complex. The truth ta ble to th e left is reduced through the Karnaugh map to the Minterm equ ation below the m ap. A little bub ble pushing D eMorganizes the logic to the final solution at the bottom right.
This is the logic for WE and SBWG, two signals that control me mo ry access.
CPM-C CON TROL SIGNALS SIGNAL GENRST CLINH CLINH1 CLSTA CLSTB CLISQ CLRP INH RPT S BW G SETSTB WE WPCTR WSQ WSTB R2000 # 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 DESCRIPTION General Reset Clear INHINT Clear INHINT1 Clear state counter A (STA) Clear state counter B (STB) Clear SNI Clear RPCELL Set INHINT Read RUPT opcode W rite G from m em ory Set the ST1 bit of STB Write E-MEM from G Write PCTR (latch priority counter sequence) Write SQ Write stage counter B (STB) Read 2000
CPM INPUTS:
I/F TPG: signal TPG_Q3 TPG_Q2 TPG_Q1 TPG_Q0 fu ll n am e TPG STATE state definition wh ere Q3 is MS B, Q0 is LSB: 00 = STBY 01 = PWRON 02 = TP1 03 = TP2 04 = TP3 05 = TP4 06 = TP5 07 = TP6 08 = TP7 09 = TP8 10 = TP9 11 = TP10 12 = TP11 13 = TP12 14 = SRLSE 15 = W AIT
ADR: EQU_16 EQU_17 GTR_17 GTR_1777 ADDRESS ADDRESS ADDRESS ADDRESS = = > > 016 017 017 01777 0=CADR 0=CADR 0=CADR 0=CADR in in in in register register register register S S S S = = > > 016 017 017 01777
0=Su bsequence DV 1 is selected 0=Su bsequence MP1 is selected 0=Su bsequence RSM 3 is selected
CTR: SB_01 SB_02 SEQ: SNI INT: IRQ MON: NRUN RUN /HALT 0=run, 1= step INT RQST 0=interrupt requested. SELECT NEXT INST 1= selec t nex t instruction ( SN I register) SUB SEL 01 SUB SEL 02 SB_01 is LSB; SB_02 is MSB 00=no counter; 01=PINC; 10=MINC
CPM OUTPUTS:
I/F signal GENRST CLINH CLINH1 CLSTA CLSTB CLISQ CLRP INH RPT S BW G SETSTB WE WPCTR WSQ WSTB R2000 fu ll n am e GENERAL RESET CLEAR INHINT CLEAR INHINT1 CLEAR STA CLEAR STB CLEAR SNI CLEAR R PCELL SET INHINT READ RUPT WRITE G SET ST1 WRITE EMEM WRITE PCTR WRITE SQ WRITE STB READ 2000 state definition 0=G eneral Reset 0=Clear INHINT 0=Clear INHINT1 0=Clear state counter A (STA) 0=Clear state counter B (STB) 0=Clear SNI 0=Clear RPCE LL 0=Set INHINT 0=Read RUPT opcode 0= W rite G from m em ory 0=Set the ST1 bit of STB 0=W rite E-MEM from G 0=W rite PCTR (latch priority counter sequence) 0=Write SQ 0=Write stage counter B (STB) 0=Read 2000
Fabrication
The C TL m odu le is (3) 1 3"x5 " circuit bo ards, an d 1 co ntrol pa nel.
Module Rack
The m odu le fram ewo rk is desig ned to resem ble a rela y rack, bu t scaled to fit the circuit board dimensions. It is constructed out of 1"x2" pine and spray-painted semi-gloss gray. Circu it boards are m oun ted to the ra ck by 2 p hillips sc rew s at either end . Nylon s pacers (1/4") a re used a s stan doffs to hold the b oard edg es ab ove the ra ck. Th e bo ards are m oun ted so th e chip s are in th e back and the pin s are w iring a re visible from the front. Power is distributed by 2 heavy aluminum bus bars mounted vertically, one per side, on the back of the module. Machine screws are mounted through the bus bars at evenly-spaced intervals to provide conn ection points for the boards. Solid copper wire (24 gauge) connects the boards to the bus bars. Ring terminals are used on the bus bar side of the connection. On the circuit board size, the wires are soldered directly to the supply rails. Materials were purchased from Home Depot, ACE Hardware, and Radio Shack.
Circuit Boards
The circuit boards are 13"x5" general purpose prototyping boards, epoxy glass with doubleside plated throu gh pa ds on 0.1" cen ters (JAMEC O 21 477C L). ICs are m oun ted in le vel 3 m achin e tooled wire-w rap sock ets: 8, 14 , 16, 20 , 24, an d 28 pin (JAM ECO ). Each socket has the pin-out lab eled with a wire-wrap socket ID ma rker, which slip s on to th e socke t be fore wrap pin g (J AM EC O). Th e part n um ber is w ritte n onto the ID m arke r. Sock ets are arran ged in 4 h orizon tal row s on ea ch bo ard, w ith about 10 sockets per row. Power is distributed on the back-side of each board by bare 24gau ge solid copp er wire su pply rails solde red at eq ual in tervals to Klipwrap terminals: 3-prong terminals with a square tail for wire-wrap ping (JA MEC O 34 163C L). A +5V rail runs above each row o f sockets an d a g roun d rail run s below . Each ra il conn ects directly to th e alum inum mo dule pow er bus u sing a ring ta il con nec tor. On the pin side of the board, all connections are made with 30 AW G Kyn ar wire-wrap wire (JAM ECO ). Red wire is used for direct conn ections to the + 5V su pply rail. Black w ire is used for direct conn ections to grou nd. W hite wire is used for everything else. Power connections from the supply rails to each ICs are double-wrapped. Bypassing capa citors (.1 uf d isc ) are sold ered ac ross the su pply rails at the Klipw rap term inals; abou t 1 capacitor for every 2 IC packag es.
All connections were stripped and hand-wrapped using a Radio Shack hand-wrap tool. As each connection was made, the corresponding line on the schematic was marked with a colored h igh ligh ter. DIP resistor networks (JAMECO) plugged into 20-pin wire-wrap sockets were used as current limiting resistors for the panel ind icators.
CTL P rinted Circuit Board (PCB) A The A b oard contain s the clock (CLK ), the scaler (SCL), and th e time pu lse generator (TPG ).
CTL P rinted Circuit Board (PCB) B The B board contains the display indicators, their current-limiting resistor networks, and the open collector drivers. The display panel is a sheet of white styrene plastic. A push pin was used to make holes through the plastic, and the LEDs were inserted in rows. The panel was hand -lette red w ith a n in delible m arke r. A few chip s near the bo ttom righ t of the B bo ard are associated with subsystems on the C board.
CTL P rinted Circuit Board (PCB) C The C board contains the sequence generator (SEQ) and control pulse matrixes (CPM-A, CPM -B, and C PM-C ). The big ICs at the bottom are the EPRO Ms tha t hold the con trol pulse matrix table for CPM-A. Each EPROM holds the tables for 8 control signals. The large ICs at the top are decod ers for the CPM-B a nd CP M-C logic.
Parts (ICs)
74LS00 74LS02 74LS04 74LS06 74LS08 74LS10 74LS20 74LS27 74LS32 74LS74 74LS112 74LS138 74LS154 74LS161 74LS244 74LS273 27C128 4001 555 (14) (9) (15) (11) (2) (4) (8) (3) (3) (1) (8) (1) (7) (8) (10) (1) (7) (1) (1) U74,U26,U27,U25,U79,U78,U55,U54,U53,U48,U13,U42,U34,U28 U4,U77,U9,U73,U45,U43,U3,U38,U32 U62,U29,U76,U69,U64,U57,U71,U59,U58,U56,U49,U41,U40,U39,U33 U22,U21,U20,U23,U14,U17,U18,U19,U16,U15,U1 U65,U10 U12,U70,U52,U51 U67,U68,U66,U63,U75,U61,U60,U6 U7,U44,U2 U72,U11,U5 U24 U8,U50,U47,U46,U35,U36,U37,U31 U99 U81,U82,U83,U98,U100,U101,U106 U104,U107,U108,U109,U110,U111,U112,U113 U80,U84,U85,U93,U94,U95,U96,U97,U102,U103 U105 U86,U87,U88,U89,U90,U91,U92 U30 U114
ICs, sockets, PCBs, resistors, capacitors, wire-wrap wire were purchased from JAMECO. The 2.048 MHz crystal and the IDE wire-wrap were from DigiKey. Wire ties, wire-wrap tools, and copper wire were purchased from Radio Shack. IDE ribbon cables were purchased from an online com pu ter su pp lier.
Power Budget
qty 74LS00 74LS02 74LS04 74LS06 74LS08 74LS10 74LS20 74LS27 74LS32 74LS74 74LS112 74LS138 74LS154 74LS161 74LS244 74LS273 27C128 4001 1 555 1 LED 61 mA (ea) m A (tot) 14 2.4 33 .6 9 2.4 21 .6 15 3.6 54 .0 11 3.6 39 .6 2 4.4 8.8 4 1.8 7.2 8 1.2 9.6 3 3.4 10 .2 3 4.9 14 .7 1 4.0 4.0 8 4.0 32 .0 1 6.3 6.3 7 6.2 43 .4 8 19 .0 15 2.0 10 32 .0 32 0.0 1 17 .0 17 .0 7 25 .0 17 5.0 0.4 0.4 3.0 3.0 20 .0 12 20 .0
O p e r a tio n : Ge ne rates all of the C PM- A EPR OM files in M o t o ro l a s 2 f S -Rec o rd fo rma t suitable for EPROM program me rs. */ # i n clu d e # i n clu d e # i n clu d e # i n clu d e # i n clu d e < s tr in g . h > < s td lib . h > < c ty p e .h > < io s tr e a m . h > < s td io . h >
enum cpType { // **inferred; not defined in orignal R393 AGC 4 spec. NO_PULSE=0,
/ / O U T PU T S F RO M S U BS Y S TE M A CI =1, // C ar ry in CLG =2, // Clear G CLCTR =3, / / C l e ar lo o p c ou n t e r CTR =4, / / L o o p co u n t e r GP =5, // Gen erate Parity KRP T =6, // Kno ck dow n Ru pt priority NISQ =7, / / N e w i n st r uc t io n t o t h e S Q r e gis t e r RA =8, / / R ead A RB =9, / / R ead B RB14 =10, / / R e a d b it 1 4 RC =11, / / R ead C RG =12, / / R ead G RLP =13, // Read LP RP 2 =14, // Read parity 2 RQ =15, / / R ead Q RRP A =16, // Read RU PT add ress RSB =17, // R ea d s ign bit RSCT =18, // Read selected cou nter addre ss RU =19, // Read sum RZ =20, / / R ead Z R1 =21, / / R ead 1 R1C =22, / / R e a d 1 c om p l im e n t e d R2 =23, / / R ead 2 R22 =24, // Read 22 R24 =25, // Read 24 ST1 =26, // Stage 1 ST2 =27, // Stage 2 TMZ =28, // Test for minus zero TOV =29, / / Test for o verfl o w TP =30, // Test p arity TRSM =31, // T es t fo r r es um e TSGN =32, / / Test sign TSGN2 =33, / / T e s t s ig n 2 WA =34, / / W r i te A
=35, =36, =37, =38, =39, =40, =41, =42, =43, =44, =45, =46, =47, =48, =49, =50,
// // // // // // // // // // // // // // // //
A and LP B G (do no t reset) LP o v e rf lo w c o u n te r ov er flow RU PT inh ibit ove rfl o w P P (do no t reset) P2 Q S X Y Y (do no t reset) Z
// OUTPUTS FROM SUBSYSTEM A; USED AS INPUTS TO SUBSYSTEM B ONLY; // NOT USED OUTS IDE C PM RSC =51, / / R ead spec ia l a n d cen t ra l ( o u t p u t t o B o n ly, n o t o u t s id e C P M ) WSC =52, / / Write spe c ia l a n d cen t ra l ( o u t p u t t o B o n ly, n o t o u t s id e C P M ) WG =53, / / W r it e G (o u tp u t t o B o nly , n o t o u ts id e CP M ) // OUTPUTS FROM SUBSYSTEM A; USED AS INPUTS TO SUBSYSTEM C ONLY; // NOT USED OUTS IDE C PM SDV1 =54, // Subsequence D V1 is currently active SMP1 =55, // Subsequence M P1 is currently active S R S M3 =56, // Subsequence RS M3 is currently active / / E X TE R NA L OU T PU T S F RO M // RA0 =57, RA1 =58, RA2 =59, RA3 =60, RA4 =61, RA5 =62, RA6 =63, RA7 =64, RA10 =65, RA11 =66, RA12 =67, RA13 =68, RA14 =69, RBK =70, WA0 =71, WA1 =72, WA2 =73, WA3 =74, WA10 =75, WA11 =76, WA12 =77, WA13 =78, WA14 =79, WBK =80, WGn =81, W20 =82, W21 =83, W22 =84, W23 =85, S U BS Y S TE M B // // // // // // // // // // // // // // // // // // // // // // // // // // // // // R e a d re g is te r at a dd r es s 0 ( A ) R e ad re g is te r a t a dd re ss 1 ( Q ) R e a d re g is te r at a dd r es s 2 ( Z ) R ead reg i st er a t a d d res s 3 (L P ) Read reg ister at address 4 Read reg ister at address 5 Read reg ister at address 6 Read reg ister at address 7 R ea d r eg iste r a t a dd re ss 10 (o ct al) R ea d r eg iste r a t a dd re ss 11 (o ct al) R ea d r eg iste r a t a dd re ss 12 (o ct al) R ea d r eg iste r a t a dd re ss 13 (o ct al) R ea d r eg iste r a t a dd re ss 14 (o ct al) R e a d BN K W r it e re g is te r at a dd r es s 0 ( A ) W r it e r eg is te r a t a dd re ss 1 ( Q ) W r it e re g is te r at a dd r es s 2 ( Z ) Write regis t er a t a d d res s 3 (L P ) W rite re gis te r a t a dd re ss 10 (o ct al) W rite re gis te r a t a dd re ss 11 (o ct al) W rite re gis te r a t a dd re ss 12 (o ct al) W rite re gis te r a t a dd re ss 13 (o ct al) W rite re gis te r a t a dd re ss 14 (o ct al) W r it e B NK W r i te G ( n o rm a l g at e s )* * W r i te in t o C Y R W r it e in t o S R W r i te in t o C Y L W r it e in t o S L
/ / T H E SE A RE T H E L EF TO V E RS -- TH E Y 'R E PR O B AB L Y U S ED IN S UB S YS T EM C // GENRST =86, / / G e n e r a l R e s e t* * C L IN H =87, / / C l e ar IN H I N T * * C L IN H 1 =88, / / C l e ar IN H I N T 1 * * CLSTA =89, / / C l e ar s ta t e co u n t e r A ( S T A ) ** CLSTB =90, / / C l e ar s ta t e co u n t e r B ( S T B )* * C L IS Q =91, / / C l e ar S N I ** CLRP =92, / / C l e ar R P C E L L* * INH =93, / / S e t IN H I N T * * RP T =94, / / R e a d R U P T op c o d e ** S BW G =95, // Write G from m em ory SETSTB =96, / / S e t th e S T 1 b it o f S T B
// // // // //
W r ite W r i te W r it e W r i te Read
E-M E M fr om G P C T R ( la t ch p r io r it y co u n t e r s e q u e n ce ) * * SQ s t ag e c o u n te r B (S T B ) * * 2000 **
s ta t ic cp T y pe g lb l_ c p [M A X P U L S E S] ; / / c u rr e n t s e t o f a s se r te d c on t ro l p u ls e s ( M A X P U LS E S ) e num scTy pe { / / identifies subsequence for a given i n st ru c ti o n SUB0=0, / / S T 2 = 0, ST 1 = 0 SUB1=1, / / S T 2 = 0, ST 1 = 1 SUB2=2, / / S T 2 = 1, ST 1 = 0 S U B 3 =3 / / S T 2 = 1, ST 1 = 1 }; enum brType { BR00 BR01 BR10 BR11 NO_BR };
// // // // //
B R 1 = 0, BR 2 = 0 B R 1 = 0, BR 2 = 1 B R 1 = 1, BR 2 = 0 B R 1 = 1, BR 2 = 1 N O B R A NC H
str uct co ntr o lS ubStep { b r T y pe b r ; / / n o r m a lly n o b ra n c h (N O _ B R ) c p T y pe p u ls e [ M A X _ IP U L S E S ] ; / / c o n ta in s 0 - M A X P U L S E S c o n tr o l p u ls e s }; str uct co ntr o lS tep { c o n tr o lS u b S t e p su b s te p [ 4 ]; // in d e x e d b y b r T y pe ( B R 0 0 , B R 0 1 , B R 1 0, B R 1 1 ) }; s t ru c t su b s e q u e n ce { c o n tr o lS t e p tp [ 1 1 ]; // in d e x e d b y t p T yp e ( T P1 - T P 1 1 ) }; s t ru c t se q u e n c e { subsequence* subseq[4] ; // indexed by sc Typ e }; # d e f in e S T E P _ I N A C T IV E \ NO_BR, {N O_ PU LSE , NO_BR, {N O_ PU LSE , NO_BR, {N O_ PU LSE , NO_BR, {NO_PULSE, #de fine STE P(p1 , p2, p3 , p4, p5 ) NO_BR, { p1 , p2, p 3, NO_BR, {N O_ PU LSE , NO_BR, {N O_ PU LSE , NO_BR, {NO_PULSE,
\ p4 , p5} , \ NO _PU LSE , NO _PU LSE , NO _PU LSE , NO _PU LSE }, \ NO _PU LSE , NO _PU LSE , NO _PU LSE , NO _PU LSE }, \ N O _ P U LS E , N O _ P U L S E , N O _ P U L S E , N O _ P U LS E }
s u bs e qu e n ce S U B _T C 0 = { S TEP ( RB, S TEP _ INAC TIVE, / / TP 2 S TEP ( WG, S TEP ( RA, S TEP _ INAC TIVE, / / TP 5 S TEP _ INAC TIVE, / / TP 6 S TEP ( RG, S TEP ( RZ, S TEP ( RB, S TEP ( RU, S TEP ( N IS Q , }; s u bs e qu e n ce S U B _C C S 0 = { S TEP ( RB, S TEP ( RZ, S TEP ( WG, S TEP _ INAC TIVE, / / TP 4 S TEP _ INAC TIVE, / / TP 5 S TEP ( RG, BR00, RC, BR01, RC,
WY, NO_PULSE, W OV I,
N O _ P U L SE N O _ P U L SE N O _ P U L SE
) , // T P 1 ) , // T P 3 ) , // T P 4
N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE
), ), ), ), ),
// // // // //
TP TP TP TP TP
7 8 9 10 11
N O _ P U L SE N O _ P U L SE N O _ P U L SE
) , // T P 1 ) , // T P 2 ) , // T P 3
WP NO_PULSE, NO_PULSE,
) , // T P 6 // TP 7
BR10, BR11, BR00, BR01, BR10, BR11, S TEP ( BR00, BR01, BR10, BR11, S TEP ( };
RB, RB, GP, R1, R2, R1, RB, RC, WA, RB, WA, RU,
TMZ, TMZ, TP, WX, WX, R2, WSC, WA, R1C, WA, R1C, ST1,
NO_PULSE, NO_PULSE, NO_PULSE, GP, GP, WX, WG, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, WZ,
NO_PULSE, NO_PULSE, NO_PULSE, TP , TP , GP, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE,
// TP 8
) , // T P 9 // TP 10
) // T P 1 1
s u bs e qu e n ce S U B _C C S 1 = S TEP ( RZ, S TEP _ INAC TIVE, S TEP ( WG, S TEP ( RU, S TEP ( RA, S TEP _ INAC TIVE, S TEP ( RG, S TEP ( RU, S TEP _ INAC TIVE, S TEP ( RC, S TEP ( RG, }; s u bs e qu e n ce S U B _N D X 0 = S TEP ( RB, S TEP _ INAC TIVE, S TEP ( WG, S TEP ( RA, S TEP _ INAC TIVE, S TEP _ INAC TIVE, S TEP ( RG, S TEP ( GP, S TEP ( RB, S TEP ( T R SM , S TEP ( ST1, }; s u bs e qu e n ce S U B _N D X 1 = S TEP ( RZ, S TEP _ INAC TIVE, S TEP ( WG, S TEP ( RU, S TEP _ INAC TIVE, S TEP ( RB, S TEP ( RG, S TEP ( RB, S TEP ( RB, S T E P _ I N A C T IV E , S TEP ( RU, }; s u bs e qu e n ce S U B _R S M 3 = S TEP ( R24, S TEP _ INAC TIVE, S TEP ( WG, S TEP _ INAC TIVE, S TEP _ INAC TIVE, S TEP _ INAC TIVE, S TEP ( RG, S TEP _ INAC TIVE, S TEP _ INAC TIVE, S T E P _ I N A C T IV E , S TEP ( N IS Q , };
{ WY, / / TP 2 NO_PULSE, WZ, WY, / / TP 6 RSC, WB, / / TP 9 WA, RSC, W OV I, WB, NO_PULSE, N IS Q , N O _ P U L SE N O _ P U L SE ), // TP 10 ) // T P 1 1 WB, GP, WP , TP , N O _ P U L SE N O _ P U L SE ) , // T P 7 ) , // T P 8 NO_PULSE, NO_PULSE, CI, NO_PULSE, NO_PULSE, NO_PULSE, N O _ P U L SE N O _ P U L SE N O _ P U L SE ) , // T P 3 ) , // T P 4 ) , // T P 5 WS, CI, N O _ P U L SE ) , // T P 1
{ WS, / / TP 2 NO_PULSE, W OV I, / / TP 5 / / TP 6 RSC, TP, WSC, NO_PULSE, NO_PULSE, WB, NO_PULSE, WG, NO_PULSE, NO_PULSE, WP , NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE ), ), ), ), ), // // // // // TP TP TP TP TP 7 8 9 10 11 NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, N O _ P U L SE N O _ P U L SE ) , // T P 3 ) , // T P 4 NO_PULSE, NO_PULSE, N O _ P U L SE ) , // T P 1
{ WY, / / TP 2 NO_PULSE, WZ, / / TP 5 WY, RSC, WX, WSC, // T P 1 0 WB, W OV I, N IS Q , N O _ P U L SE ), // TP 11 NO_PULSE, WB, GP, WG, NO_PULSE, WP , TP , NO_PULSE, N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE ), ), ), ), // // // // TP TP TP TP 6 7 8 9 NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, N O _ P U L SE N O _ P U L SE ) , // T P 3 ) , // T P 4 WS, CI, N O _ P U L SE ) , // T P 1
{ WS, / / TP 2 NO_PULSE, / / TP 4 / / TP 5 / / TP 6 WZ, / / TP 8 / / TP 9 // T P 1 0 NO_PULSE, NO_PULSE, NO_PULSE, N O _ P U L SE ), // TP 11 NO_PULSE, NO_PULSE, N O _ P U L SE ) , // T P 7 NO_PULSE, NO_PULSE, N O _ P U L SE ) , // T P 3 NO_PULSE, NO_PULSE, N O _ P U L SE ) , // T P 1
s u bs e qu e n ce S U B _X C H 0 = { S TEP ( RB, S TEP ( RA, S TEP ( WG, S TEP ( WP2, S TEP _ INAC TIVE, / / TP 5
N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE
), ), ), ),
// // // //
TP TP TP TP
1 2 3 4
S TEP _ INAC TIVE, / / TP 6 S TEP ( RG, S TEP ( GP, S TEP ( RA, S TEP ( RB, S TEP ( ST2, }; s u bs e qu e n ce S U B _C S 0 = { S TEP ( RB, S TEP _ INAC TIVE, S TEP ( WG, S TEP _ INAC TIVE, S TEP _ INAC TIVE, S TEP _ INAC TIVE, S TEP ( RG, S TEP ( GP, S TEP ( RB, S TEP ( RC, S TEP ( ST2, };
N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE
), ), ), ), ),
// // // // //
TP TP TP TP TP
7 8 9 10 11
NO_PULSE, NO_PULSE,
NO_PULSE, NO_PULSE,
N O _ P U L SE N O _ P U L SE
) , // T P 1 ) , // T P 3
N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE
), ), ), ), ),
// // // // //
TP TP TP TP TP
7 8 9 10 11
s u bs e qu e n ce S U B _T S 0 = { S TEP ( RB, S TEP ( RA, ), // T P 2 S TEP ( WG, BR00, NO_PULSE, BR01, RZ, o v e r flo w BR10, RZ, unde r f lo w BR11, NO_PULSE, BR00, NO_PULSE, BR01, R1, BR10, WA, BR11, NO_PULSE, S TEP _ INAC TIVE, / / TP 6 BR00, NO_PULSE, BR01, RU, BR10, RU, BR11, NO_PULSE, S TEP ( GP, S TEP ( RB, ), // T P 9 S TEP ( RA, S TEP ( ST2, }; s u bs e qu e n ce S U B _A D 0 = { S TEP ( RB, S TEP ( RA, S TEP ( WG, S TEP _ INAC TIVE, / / S TEP _ INAC TIVE, / / S TEP _ INAC TIVE, / / S TEP ( RG, S TEP ( RB, S TEP ( RB, S T E P _ I N A C T IV E , // S TEP ( RU, };
WS, WB, NO_PULSE, NO_PULSE, WY, WY, NO_PULSE, NO_PULSE, WA, R1C, NO_PULSE, NO_PULSE, WZ, WZ, NO_PULSE, NO_PULSE, WSC, W OV I, NO_PULSE,
NO_PULSE, TOV, NO_PULSE, NO_PULSE, CI, CI, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, WG, NO_PULSE, NO_PULSE,
NO_PULSE, WP , NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE,
// TP 5
NO_PULSE, NO_PULSE, // TP 7 NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, N O _ P U L SE ) , // T P 8 NO_PULSE, N O _ P U L SE NO_PULSE, NO_PULSE, N O _ P U L SE N O _ P U L SE ), // TP 10 ), // TP 11
N O _ P U L SE N O _ P U L SE N O _ P U L SE
) , // T P 1 ) , // T P 2 ) , // T P 3
WP , TP , NO_PULSE, ST2,
N O _ P U L SE N O _ P U L SE N O _ P U L SE WOVI
) , // T P 7 ) , // T P 8 ) , // T P 9 ), // TP 11
// No te: A ND is perfo rm ed u sing D eM orga n's T he ore m : the inpu ts are inver ted , a / / lo g ic a l O R i s p e r fo r m e d , a n d t h e r e s u lt is in v e r te d . T he im p l e m e n t at io n o f t h e // OR (at TP8 ) is somewh at unortho dox: the inverted inpu ts are in registers U / / a n d C . T he O R i s a c h ie v e d b y g a t in g b o th r e g is t e rs o n to t h e re a d / w rit e b u s // simu ltaneously. (The bus on ly transfers logical 1's; register-to-register transfers / / a r e p e rf o rm e d b y c le a r in g t h e de s t in a t io n r e g is t e r a n d t h en t ra n s fe r r in g t h e // 1's from the so urce r egister to th e de stination). W hen the 1 's from b oth // re giste r s a re s imultaneously gated onto the bus, th e wo rd o n t h e b u s i s a l og i ca l // OR of both reg isters. s u bs e qu e n ce S U B _M A S K 0 = { S TEP ( RB, WS, NO_PULSE, NO_PULSE, S TEP ( RA, WB, NO_PULSE, NO_PULSE, S TEP ( WG, NO_PULSE, NO_PULSE, NO_PULSE,
N O _ P U L SE N O _ P U L SE N O _ P U L SE
) , // T P 1 ) , // T P 2 ) , // T P 3
S TEP ( RC, S TEP _ INAC TIVE, / / TP 5 S TEP _ INAC TIVE, / / TP 6 S TEP ( RG, S TEP ( RU, ( C H AN G E D ) S TEP _ INAC TIVE, / / TP 9 S TEP ( RA, ( C H AN G E D ) S TEP ( RC, }; s u bs e qu e n ce S U B _M P 0 = { S TEP ( RB, S TEP ( RA, S TEP ( RSC, BR00, RB, BR01, RB, BR10, RC, BR11, RC, S TEP ( R LP, S TEP _ INAC TIVE, / / TP 6 BR00, RG, BR01, RG, BR10, RG, BR11, RG, BR00, GP, BR01, GP, BR10, RC, BR11, RC, S TEP ( RU, BR00, RA, BR01, RA, BR10, RA, BR11, RA, BR00, ST1, BR01, R1, BR10, RU, BR11, RU, }; s u bs e qu e n ce S U B _M P 1 = { S TEP ( RA, S TEP ( R LP, BR00, NO_PULSE, BR01, NO_PULSE, BR10, RB, BR11, RB, S TEP ( RA, S TEP ( R LP, S TEP ( RU, S TEP ( RA, BR00, NO_PULSE, BR01, NO_PULSE, BR10, RB, BR11, RB, S TEP ( R LP, S TEP ( RA, S TEP ( RU, }; s u bs e qu e n ce S U B _M P 3 = { S TEP ( RZ, S TEP ( R LP, S TEP ( WG, S TEP ( RU, S TEP ( RA, BR00, NO_PULSE, BR01, NO_PULSE, BR10, RB, BR11, RB, S TEP ( RG, S TEP ( R LP, S TEP ( RB, S TEP ( RA, S TEP ( RU,
WY,
NO_PULSE,
NO_PULSE,
N O _ P U L SE
) , // T P 4
RSC, RC,
WB, WA,
WP , GP,
N O _ P U L SE TP
) , // T P 7 ), // TP 8
WB, WA,
NO_PULSE, ST2,
NO_PULSE, W OV I,
N O _ P U L SE N O _ P U L SE
), // TP 10 ), // TP 11
WS, WB, WG, WLP, WLP, WLP, WLP, WA, WY, WY, WB, WB, TP, TP, WY, WY, WB, WLP, RB14, WLP, RB14, WALP, ST1, ST1, ST1,
NO_PULSE, TSGN, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, WP , WP , WP , WP , NO_PULSE, NO_PULSE, GP, GP, TSGN2, TSGN, WL P , TSGN, WL P , NO_PULSE, WA L P , WA L P , WA L P ,
NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, TP , TP , NO_PULSE, NO_PULSE, TSGN, NO_PULSE, TSGN, NO_PULSE, R1C, NO_PULSE, NO_PULSE,
N O _ P U L SE N O _ P U L SE N O _ P U L SE NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, N O _ P U L SE NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, N O _ P U L SE NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE,
) , // T P ) , // T P ) , // T P // TP
1 2 3 4
) , // T P 5 // TP 7
// TP 8
) , // T P 9 // TP 10
// TP 11
WY, WA, NO_PULSE, NO_PULSE, WX, WX, WLP, TSGN, WALP, WY, NO_PULSE, NO_PULSE, WX, WX, WA, WLP, ST1,
NO_PULSE, TSGN, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, CTR, WA L P ,
NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE,
) , // T P 1 ) , // T P 2 // TP 3
), ), ), ),
// // // // //
TP TP TP TP TP
4 5 6 7 8
) , // T P 9 ), // TP 10 ), // TP 11
WY, TSGN, NO_PULSE, WZ, WY, NO_PULSE, NO_PULSE, WX, WX, RSC, WA, WSC, WLP, WALP,
WS, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, WB, GP, WG, NO_PULSE, N IS Q ,
CI, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, WP , TP , NO_PULSE, NO_PULSE, NO_PULSE,
), ), ), ), ),
// // // // // //
TP TP TP TP TP TP
1 2 3 4 5 6
), ), ), ), ),
// // // // //
TP TP TP TP TP
7 8 9 10 11
}; s u bs e qu e n ce S U B _D V 0 = { S TEP ( RB, S TEP ( RA, S TEP ( RSC, BR00, RC, BR01, RC, BR10, NO_PULSE, BR11, NO_PULSE, BR00, R1, BR01, R1, BR10, R2, BR11, R2, S TEP ( RA, S TEP ( RG, S TEP ( RB, BR00, R LP, BR01, R LP, BR10, NO_PULSE, BR11, NO_PULSE, BR00, RB, BR01, RB, BR10, RC, BR11, RC, S TEP ( R1, }; s u bs e qu e n ce S U B _D V 1 = { S TEP ( R22, S TEP ( RQ, S TEP ( RG, S TEP ( RA, S TEP ( R LP, S TEP _ INAC TIVE, / / TP 6 S TEP ( RU, BR00, NO_PULSE, BR01, NO_PULSE, BR10, RU, BR11, RU, BR00, RB, BR01, RB, BR10, RB, BR11, RB, S TEP ( RG, BR00, ST1, BR01, ST1, BR10, RC, BR11, RB, }; s u bs e qu e n ce S U B _S U 0 = { S TEP ( RB, S TEP ( RA, S TEP ( WG, S TEP _ INAC TIVE, / / S TEP _ INAC TIVE, / / S TEP _ INAC TIVE, / / S TEP ( RG, S TEP ( RC, S TEP ( RB, S T E P _ I N A C T IV E , // S TEP ( RU, }; s u bs e qu e n ce S U B _R U P T1 = { S TEP ( R24, S TEP _ INAC TIVE, / / S TEP ( WG, S TEP _ INAC TIVE, / / S TEP _ INAC TIVE, / / S TEP _ INAC TIVE, / / S TEP _ INAC TIVE, / / S TEP _ INAC TIVE, / / S TEP ( RZ, S TEP ( RU,
WS, WB, WG, WA, WA, NO_PULSE, NO_PULSE, WLP, WLP, WLP, WLP, WQ, WB, WA, R2, R2, NO_PULSE, NO_PULSE, WLP, WLP, WA, WA, ST1,
NO_PULSE, TSGN, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, TSGN, GP, WB, WB, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, WB,
NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, WP , TP , NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE,
N O _ P U L SE N O _ P U L SE N O _ P U L SE NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, N O _ P U L SE N O _ P U L SE N O _ P U L SE NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, N O _ P U L SE
) , // T P ) , // T P ) , // T P // TP
1 2 3 4
// TP 5
) , // T P ) , // T P ) , // T P // TP
6 7 8 9
// TP 10
), // TP 11
WS, WG, WQ, WX, TSGN2, TSGN, NO_PULSE, NO_PULSE, WQ, WQ, RSB, RSB, WG, WG, WB, NO_PULSE, NO_PULSE, WA, WA,
NO_PULSE, NO_PULSE, WY, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, WG, WG, NO_PULSE, NO_PULSE, TSGN, NO_PULSE, NO_PULSE, ST2, ST2,
NO_PULSE, NO_PULSE, RSB, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE,
N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE, N O _ P U L SE NO_PULSE, NO_PULSE, NO_PULSE, NO_PULSE,
), ), ), ), ),
// // // // //
TP TP TP TP TP
1 2 3 4 5
) , // T P 7 // TP 8
// TP 9
), // TP 10 // TP 11
N O _ P U L SE N O _ P U L SE N O _ P U L SE
) , // T P 1 ) , // T P 2 ) , // T P 3
WP , TP , NO_PULSE, ST2,
N O _ P U L SE N O _ P U L SE N O _ P U L SE WOVI
) , // T P 7 ) , // T P 8 ) , // T P 9 ), // TP 11
WS, NO_PULSE,
CI, NO_PULSE,
N O _ P U L SE N O _ P U L SE
) , // T P 1 ) , // T P 3
NO_PULSE, NO_PULSE,
NO_PULSE, NO_PULSE,
N O _ P U L SE N O _ P U L SE
) , // T P 9 ), // TP 10
S TEP ( };
ST1,
ST2,
NO_PULSE,
NO_PULSE,
N O _ P U L SE
), // TP 11
s u bs e qu e n ce S U B _R U P T3 = { S TEP ( RZ, S TEP ( RRPA, S TEP ( RZ, S TEP _ INAC TIVE, / / S TEP _ INAC TIVE, / / S TEP _ INAC TIVE, / / S TEP _ INAC TIVE, / / S TEP _ INAC TIVE, / / S TEP ( RB, S T E P _ I N A C T IV E , // S TEP ( ST2, }; s u bs e qu e n ce S U B _S T D 2 = S TEP ( RZ, S TEP _ INAC TIVE, S TEP ( WG, S TEP ( RU, S TEP _ INAC TIVE, S TEP _ INAC TIVE, S TEP ( RG, S TEP ( GP, S TEP ( RB, S T E P _ I N A C T IV E , S TEP ( N IS Q , }; {
N O _ P U L SE N O _ P U L SE N O _ P U L SE
) , // T P 1 ) , // T P 2 ) , // T P 3
WG, NO_PULSE,
NO_PULSE, NO_PULSE,
N O _ P U L SE N O _ P U L SE
) , // T P 9 ), // TP 11
N O _ P U L SE N O _ P U L SE N O _ P U L SE
) , // T P 1 ) , // T P 3 ) , // T P
N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE
) , // T P 7 ) , // T P 8 ) , // T P 9 ), // TP 11
s u bs e qu e n ce S U B _P IN C = { S TEP ( WS, S TEP _ INAC TIVE, / / TP 2 S TEP ( WG, S TEP ( R1, S TEP _ INAC TIVE, / / TP 5 S TEP ( RG, S TEP ( TP, S TEP ( WP, S TEP ( RU, S TEP ( RU, S T E P _ I N A C T IV E , // T P 1 1 }; s u bs e qu e n ce S U B _M I N C = { S TEP ( WS, S TEP _ INAC TIVE, / / TP 2 S TEP ( WG, S TEP ( WY, S TEP _ INAC TIVE, / / TP 5 S TEP ( RG, S TEP ( TP, S TEP ( WP, S TEP ( RU, S TEP ( RU, S T E P _ I N A C T IV E , // T P 1 1 }; s u bs e qu e n ce S U B _S H IN C = { S TEP ( WS, S TEP _ INAC TIVE, / / TP 2 S TEP ( WG, S TEP ( WY, S TEP _ INAC TIVE, / / TP 5 S TEP ( RG, S TEP ( TP, S TEP ( WP, S TEP ( RU, S TEP ( RU, S T E P _ I N A C T IV E , // T P 1 1 }; char* subse qString [] = { "TC0",
N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE
) , // T P 1 ) , // T P 3 ) , // T P 4 ), ), ), ), ), // // // // // TP TP TP TP TP 6 7 8 9 10
N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE
) , // T P 1 ) , // T P 3 ) , // T P 4 ), ), ), ), ), // // // // // TP TP TP TP TP 6 7 8 9 10
N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE N O _ P U L SE
) , // T P 1 ) , // T P 3 ) , // T P 4 ), ), ), ), ), // // // // // TP TP TP TP TP 6 7 8 9 10
"CCS0 ", "CCS1 ", "NDX0 ", "NDX1 ", "RSM3 ", "XCH 0", "CS0", "TS0", "AD0", "MAS K0", "MP0", "MP1", "MP3", "DV0", "DV1", "SU0", "RUPT1", "RUPT3", "STD2 ", "PINC0", "MINC0", "SHINC0 ", " NO _ S EQ " }; e num subse q { TC0 CCS0 CCS1 NDX0 NDX1 RSM3 XCH0 CS0 TS0 AD0 MASK0 MP0 MP1 MP3 DV0 DV1 SU0 RUPT1 RUPT3 STD2 P IN C 0 M I N C0 S H IN C 0 NO_SEQ };
=0, =1, =2, =3, =4, =5, =6, =7, =8, =9, =10, =11, =12, =13, =14, =15, =16, =17, =18, =19, =20, =21, =22, =23
=0, =1, =2, =3, =4, =5, =6, =7, =8, =9, =10, =11, =12, =13, =14, =15 / / T I M E P U L S E 1 : s t ar t of m e m o r y cy c le t im e ( M C T )
subseq instructionSu bsequ enceD ecoder( int S B2_field, int SB1_field, int SQ_field, in t S TB _ fiel d )
{ // Com binationa l logic deco des instru ction an d the stage coun t / / t o g et th e in s t ru c t io n s u b se q u e n c e . s ta tic su b se q de c od e [1 6 ][ 4] = { { TC0, RUPT1, STD2, { CCS0, CCS1, N O _ SE Q , { NDX0, NDX1, N O _ SE Q , { XCH0, N O _ SE Q , STD2, { { { { { { { { { { { { }; if (S B 2 _ f ie ld = = 0 & & S B 1 _ f ie ld = = 1 ) r e tu r n P IN C 0 ; e ls e if (S B 2 _ f ie ld = = 1 & & S B 1 _ f ie ld = = 0 ) r e tu r n M I N C 0 ; else return deco de[S Q_ field][STB_ field]; } void clearC ontrolPu lses() { f or (u n sig n e d i= 0 ; i< M A X P UL S E S; i+ + ) g lb l_ c p [i] = N O _ P U L S E ; } v o id a s se r t( c pT y p e * p u ls e ) { in t j= 0 ; f or (u n sig n e d i= 0 ; i< M A X P UL S E S & & j< M A X _ IP U LS E S & & p u ls e [j ] ! = NO _ P U LS E ; i+ + ) { if (g lb l_ c p [i] = = N O _ P U L S E ) { glbl_cp[i] = pu lse[j]; j + +; } } } v o id a s se r t( c pT y p e p u ls e ) { f or (u n sig n e d i= 0 ; i< M A X P UL S E S; i+ + ) { if (g lb l_ c p [i] = = N O _ P U L S E ) { g lb l_ c p [i] = p u ls e ; break; } } } void get_CP M_A (int CPM_A _addre ss) { / / E P R O M a d dr e ss // 1: // 2: // 3-6: r e g is t e r // 7,8: r e g is t e r / / 9 - 1 2 : r e g is t e r // 13: // 14: N O _ SE Q , N O _ SE Q , N O _ SE Q , N O _ SE Q , N O _ SE Q , MP0, DV0, SU0, CS0, TS0, AD0, MASK0, N O _ SE Q , N O _ SE Q , N O _ SE Q , N O _ SE Q , N O _ SE Q , MP1, DV1, N O _ SE Q , N O _ SE Q , N O _ SE Q , N O _ SE Q , N O _ SE Q , N O _ SE Q , N O _ SE Q , N O _ SE Q , N O _ SE Q , N O _ SE Q , N O _ SE Q , STD2, STD2, STD2, STD2, STD2, STD2,
RUPT3 NO_SEQ RSM3 NO_SEQ NO_SEQ NO_SEQ NO_SEQ NO_SEQ NO_SEQ MP3 NO_SEQ NO_SEQ NO_SEQ NO_SEQ NO_SEQ NO_SEQ
}, }, }, }, }, }, }, }, },
// // // // // // // // //
00 01 02 03 04 05 06 07 10
} , // 1 1 } , // 1 2 } , // 1 3 }, }, }, } // // // // 14 15 16 17
/ /* * * * * * * * * * * * * ** * * * * * * * * * * * * ** * * * * * * * * * * * * ** * * * * * * * * * * * * ** * * // EP ROM emulator in t S B 2 _ fie ld = ( C P M _ A _ a d d re s s > > 1 3 ) & 0 x 1 ; in t S B 1 _ fie ld = ( C P M _ A _ a d d re s s > > 1 2 ) & 0 x 1 ; int S Q_ field = (C PM _A _a dd res s > > 8 ) & 0 xf; in t S T B _ fie ld = ( C P M _ A _ a d d re s s > > 6 ) & 0 x 3 ; int S G_ field = (C PM _A _a dd res s > > 2 ) & 0 xf; in t B R 1 _ fie ld = ( C P M _ A _ a d d re s s > > 1 ) & 0 x 1 ; in t B R 2 _ fie ld = ( C P M _ A _ a d d re s s ) & 0x1;
// Dec ode the cu rrent instru ction sub sequ ence (glbl_subse q). subse q glbl_sub seq = instructionS ubse que nceD ecod er(SB 2_field, SB 1_field, SQ _field, STB _field); s ta tic su b se q u en c e* s ub sp [] = { &SUB_TC0, &SUB_CCS0, &SUB_XCH0, &SUB_CS0, &SUB_MP1, &SUB_MP3, &SUB_RUPT3, &SUB_STD2, }; // Clear old control pulses. clearCo ntrolPulses (); / / G e t n e w c on t ro l p u ls e s fo r th e c u r re n t in s t ru c t io n s u b se q u e n c e . if( glb l_ su b se q != N O _S E Q && // TH IS T ES T S O U T OK S G _ fie ld > = T P 1 && S G _ f ie ld < = T P 1 1 ) { subse que nce* subse qP = subsp [glbl_subse q]; if( subseqP) { // index t-2 b ecause TP1= 2, but array is indexed from zero contro lStep& csref = s ubse qP-> tp[SG _field-2]; brTyp e b = (brTyp e) ((BR 1_field << 1) | BR 2_field); contro lSubS tep& cssref = csref.sub step[b ]; if (c s sr e f. b r = = N O _ B R ) cssref = csref.sub step[0 ]; c p T y pe * p = c s sr e f. p u ls e ; asser t(p); } } // Impleme nt these h ere, becau se the instruction seque nce de coder / / function is buried in the C PM- A RO M a n d s o , id en t ific a t io n o f // th e se qu en ces is no t av ailab le ou tside CP M -A. CP M -C ne ed s info // on these 3 seque nces. switch ( glbl_subseq) { case DV1: assert(SDV1); break; case MP1: assert(SMP1); break; c a s e RS M 3 : assert(SRSM3); break; } / /* * * * * * * * * * * * * ** * * * * * * * * * * * * ** * * * * * * * * * * * * ** * * * * * * * * * * * * ** * *
} c h ar * c pT y pe S tr in g [] = { "NO_PU LSE", / / O U T PU T S F RO M S U BS Y S TE M A "CI" , "CL G" , "CL CT R", "C TR ", "G P", "K RPT ", "N ISQ ", "RA ", "RB ", "RB 14 ", "RC ", "RG ", "RL P", "R P2" , "RQ ", "RR PA ", "RS B", " RS CT ", "RU ", "RZ ", "R1 ", "R1 C", " R2 ", "R2 2", "R 24 ", "S T1 ", "S T2 ", "TM Z", "TO V", " TP" , "TR SM ", "TS GN ", "TS GN 2", "W A", " W ALP ", "W B", " W Gx ", "W LP", " W OV C", " W OV I", "W OV R", "W P", "W Px" , "W P2" , "W Q" , "W S", "WX", "W Y", "WYx", "WZ", // OUTPUTS FROM SUBSYSTEM A; USED AS INPUTS TO SUBSYSTEM B ONLY; // NOT USED OUTS IDE C PM
// "RSC", "WS C", "WG", // OUTPUTS FROM SUBSYSTEM A; USED AS INPUTS TO SUBSYSTEM C ONLY; // NOT USED OUTS IDE C PM // "SDV1 ", "SMP1", "SRSM 3", / / E X TE R NA L OU T PU T S F RO M S U BS Y S TE M B // "RA 0", "R A1 ", "RA 2", "R A3 ", "RA 4", "R A5 ", "RA 6", "R A7 ", "RA 10 ", "RA 11 ", "RA 12 ", "RA 13 ", "RA 14 ", "RB K", "W A0 ", "W A1 ", "W A2 ", "W A3 ", "W A1 0", "WA1 1", "WA12", "WA 13", "WA14 ", "WBK", "WG n", "W20", "W21 ", "W22", "W23", / / T H E SE A RE T H E L EF TO V E RS -- TH E Y 'R E PR O B AB L Y U S ED IN S UB S YS T EM C // "G EN RS T", "C LINH ", "C LINH 1", "C LST A", " CL ST B", " CL ISQ ", "C LRP ", "IN H" , " R P T " , " S B W G " , " S E T S T B ", "W E " , " W P C T R " , " W S Q " , " W S T B " , " R 2 0 0 0 " }; // f or de bu g p ur po se s o nly char* printCo ntrolPulses () { static char b uf[MA XPU LSE S*6 ]; strcpy(b uf,""); f or (u n sig n e d i= 0 ; i< M A X P UL S E S & & g lb l_ c p[ i] != N O _ PU L S E; i+ + ) { strcat(bu f, cpType String[g lbl_cp[i]]); strcat(bu f," "); } //if(strcmp(bu f,"") == 0) strcat(b uf,"NO NE" ); ret urn bu f; } / / r e tu r n th e E P R O M w o r d c or r e sp o n d in g t o th e p u ls e s // in glbl_cp. unsign ed w riteEPR OM (int lowBit) { un sig ne d E PR O M w or d = 0x 00 ; // no pu lse s; de fa ult f or (u n sig n e d i= 0 ; i< M A X P UL S E S & & g lb l_ c p[ i] != N O _ PU L S E; i+ + ) { int pulse = glbl_cp[i] - lowBit; if (p u ls e < 0 | | p u ls e > 7 ) c o n tin u e ; // p u ls e is n o t in t h is E P R O M E P R O M w o r d | = 0 x0 1 < < p u ls e ; } // printf("% 02X \n",EP RO Mw ord); //re turn EPR OMw ord; // The CPM -A con trol signals are n ega tive logic, so we n eed to // b it-f lip t he w or d. No sig na l is a 1, an d a n a ss er te d s ign al is // a 0: return ((~EP RO Mw ord) & 0xff); }
co nst unsigne d agcMem Size = 0x3fff+1; / / # of cells i n a 1 6 -b i t a d d res s ra n g e void writeE PRO M(FILE * fpO bj, int lowBit) { // Write a n EP RO M file using M otorola's S -Reco rd form at (s2f). / / S o m e p a r a m e t e rs t h at c on t ro l f ile f or m a t . Y o u c a n ch a n g e m a x B y te s / / w ithout affecting anything els e. 'a d d res s B ytes ' is d et ermin ed b y // the ch oose n S-R ecord forma t. const int m axB ytes = 20; // se t limit on record length co nst int addressBytes = 3; // 24- bit addre ss ra n g e c o n s t in t s u m C h e c kB y t e s = 1 ; const int maxd ata = m axBytes - ad dressByte s - sumC heckB ytes; int i=0; // current E PRO M ad dress in t s u m C h e c k = 0 ; w h i le ( i < a g c M e m S i ze ) {
/ / get dataByteC ount; t h e n u mb er o f b ytes o f E P RO M d a t a p er rec o rd . int dataByteC ount = maxdata; if (i + d a t a B yt e C o u n t > = a g c M e m S i ze ) { da ta B yt eC ou nt = ag cM em S ize - i; } / / w r it e re c o rd h e a d e r ( * * * 3 by t e ad d r e ss a s su m e d * * * ) int totalByteC ount = dataByte Coun t + addre ssBytes + sum Che ckBytes; fprintf(fpObj, "S 2% 02X % 06X ", totalByte Cou nt, i); su m Ch eck = t ota lByt eC ou nt & 0x ff; s u m C h e c k = ( su m C h e c k + ( (i & 0 x ff 0 0 0 0) > > 1 6 ) ) % 2 5 6 ; s u m C h e c k = ( su m C h e c k + ( (i & 0 x 0 0 ff 0 0 ) > > 8 ) ) % 2 5 6 ; s u m C h e c k = ( su m C h e c k + ( (i & 0 x 0 0 0 0 ff ) )) % 256; // write data bytes into record f or (in t j =0 ; j <d a ta B yt eC o u nt ; j ++ ) { g e t_ C P M _A ( i+ j ); // ge t C P M -A p u ls e s fo r a d dr e ss i+ j int data = w riteEPR OM ( l o wB it ) ; / / co mvert p u ls es t o E P RO M fo rma t fprintf(fpObj, "% 02X ", data); s u m C h e c k = ( su m C h e c k + d a t a) % 2 5 6 ; } / / t e rm i n a te r e c or d b y a d d in g t h e ch e c k su m a n d a n e w lin e . fprintf(fpObj, "% 02X \n", (~s um Ch eck) & 0xff); i += da taBy teCo unt; } // write an end-of-file record h ere i = 0; // use address ze ro for last record sumCheck = 0x04; // byte count s u m C h e c k = ( su m C h e c k + ( (i & 0 x ff 0 0 0 0) > > 1 6 ) ) % 2 5 6 ; s u m C h e c k = ( su m C h e c k + ( (i & 0 x 0 0 ff 0 0 ) > > 8 ) ) % 2 5 6 ; s u m C h e c k = ( su m C h e c k + ( (i & 0 x 0 0 0 0 ff ) )) % 256; fprintf(fpObj, "S 804 % 06X % 02X ", i, (~sum Ch eck) & 0xff); }
fpOb j = fope n("C PM 1_8 .hex" , "w"); if(!fpOb j) { perro r("fopen failed for object file"); exit(-1); } writeEP RO M(fpO bj, 1); // pulses 1 -8 fclose(fpOb j);
fpOb j = fope n("C PM 9_1 6.he x", "w" ); if(!fpOb j) { perro r("fopen failed for object file"); exit(-1); } w r it e E P R O M ( fp O b j , 9 ) ; / / p u ls e s 9 -1 6 fclose(fpOb j);
fpOb j = fope n("C PM 17_ 24.h ex", "w "); if(!fpOb j) { perro r("fopen failed for object file"); exit(-1); } w r it e E P R O M ( fp O b j , 1 7 ) ; / / p u ls e s 1 7- 2 4 fclose(fpOb j);
if(!fpOb j) { perro r("fopen failed for object file"); exit(-1); } w r it e E P R O M ( fp O b j , 2 5 ) ; / / p u ls e s 2 5- 3 2 fclose(fpOb j);
fpOb j = fope n("C PM 33_ 40.h ex", "w "); if(!fpOb j) { perro r("fopen failed for object file"); exit(-1); } w r it e E P R O M ( fp O b j , 3 3 ) ; / / p u ls e s 3 3- 4 0 fclose(fpOb j);
fpOb j = fope n("C PM 41_ 48.h ex", "w "); if(!fpOb j) { perro r("fopen failed for object file"); exit(-1); } w r it e E P R O M ( fp O b j , 4 1 ) ; / / p u ls e s 4 1- 4 8 fclose(fpOb j);
fpOb j = fope n("C PM 49_ 56.h ex", "w "); if(!fpOb j) { perro r("fopen failed for object file"); exit(-1); } w r it e E P R O M ( fp O b j , 4 9 ) ; / / p u ls e s 4 9- 5 6 fclose(fpOb j); }
Abstract
This report describes my successful project to build a working reproduction of the 1964 prototype for the Block I Apollo Guidance Computer. The AGC is the flight computer for the Ap ollo m oon lan din gs, and is the wo rlds first in tegra ted c ircuit com pu ter. I built it in my ba sem ent. It took me 4 yea rs. If you like, you can build one too. It will take you less time, and yours will be better than mine. I docum ented m y project in 9 separate .pdf files: Part 1 Part 2 Part 3 Part 4 Part 5 Part 6 Part 7 Part 8 O v ervie w : Introdu ces the p roject. CTL Module: Design and construction of the control module. PROC M odule: Design and construction of the processing (CPU) modu le. MEM Module: Design and construction of the mem ory module. IO Module: Design and construction of the display/keyboard (DSKY) m odule. Assem bler: A cross-a ssem bler for AG C softw are dev elopm ent. C+ + S imu lator: A low-level simulator that runs assemb led AGC code. Flight Software: My translation of portions of the COLOSSUS 249 flight software. Test & Che ckou t: A suite of test programs in AG C assembly langu age.
Part 9
Overview
The Processing Module (PROC) has 5 subsystems: PMI, ALU, CRG, INT, CTR PM I (P roce ssin g M od ule external Interface) The PMI interfaces other p ro cessin g m od ule su bsy stem s to external AG C m odules. 40-pin IDE connectors interface to th e other CT L, M EM , an d IO mo dules. Inputs from those mod ules are buffered to 1 LSTTL load. ALU (Arithm etic Log ic Unit) The A LU co ntain s the 1 6-bit AD DER to p erfo rm 1's complement arithmetic and increment the program counter (Z register). The ALU also contains the B and C registers, and logic to inclusive OR the contents of the them with the AD DE R. Th e inc lusive O R oc curs when the control modu le (CTL) issues signals to READ the conte nts of bo th registe rs onto the READ bus simultaneously. The ALU transfers data from the READ bus to the WRITE bus for regis ter-to -reg ister tra nsfers and can force the data lines of the WRITE bus to specific states to gate variou s consta nts into the AG C reg isters CRG (Cen tral Register) The A GC has fou r 16-b it central registers for general com pu tatio nal use . The se are the accumulator (A) for general computation; the program counter (Z) which contains the address of the next instruction; the Q register holding the remainder in the DV instruction, and the return address after TC instructions; and the LP register used to hold the lower produ ct after MP instructions. INT (Interrupt Priority) The original AGC had five vectored interrupts. This recreation implem ents three of them: RUPT1, also called T3RUPT which is used as general-purpose timer by the AGC WAITLIST software; RUPT3, also called T4RUPT or DSRUPT, which is used to update the DSKY display at regular intervals; and RUPT4, also called KERUPT, which is triggered by a key press from the user's keyboard. The AGC responds to each interrupt by temporarily suspending the current program, executing a short interrupt service routine, and then resuming the
interrupted program. CTR (Priority Cou nter) Tw enty m em ory lo catio ns in the o rigin al A GC function ed a s up /do wn cou nters. Th e cou nters would incremen t (PINC) or decrement (M INC) in response to external inputs. Increment or decrement was ha ndled by one 12-step subsequen ce of microinstructions inserted between any two regular instructions. This replica implemen ts 5 of the counters: OVCTR, an overflow counter increm ented or decrem ented by arithme tic overflow during certain in structions; TIME2 and TIME1, the AGC real-time clock; TIME3, a general purpose timer incremented by a 100Hz signal from the SCALER (SCL); and TIME4, a timer used to update the DSKY display.
The A LU h as a 1 6-bit parallel adder. The addend and augend are supplied by the X and Y registers. The sum, called the U register although it is not really a register at a ll, is gated to the read bus through the RU (read U) control signal. The WX and W Y con trol signa ls copy the contents of the w rite bus in to the X and Y registers.
The B register is loaded from the write bus with the W B (w rite B) sign al. The con tents of B are output to the read bus with the RB (read B) signal. The inv erted outp ut of B can be gated to the read bus with the RC (read C ) sign al.
The A GC has fou r user-acc essible ce ntral reg isters. The A register is the accum ulato r; Z is the program counter; Q stores the return address for jumps (TC instruction), and LP stores the lower product (MP instruction).
Cen tral register con tents can be output to the read bus by asserting the appropriate read control pulse (RA, RQ, RZ, or RLP ). Each register is also mapped to a m em ory locatio n, with register A ma ppe d to address 0, Q to ad dress 1, Z to 2, and LP to 3. The R0, R1, R2, and R3 control pulses output those registers to the read bus.
The w rite bus co nten ts can be loaded into a central register with a w rite co ntro l p uls e. W A and W ALP load the A register; WQ, the Q register; WZ the Z register; and WLP and W ALP the L P reg ister. The W0, W1, W2, and W3 control pulses m apped to m em ory addresses 0,1,2, and 3 also load those registers.
The in terrupt p riority subsystem m anages vectored interrupts. Five inte rrup ts (0-4) are imp lemen ted. Each interrup t is latched by its own RP cell flip-flop. Sign als from all RP cells feed into a priority encoder; a combinational logic arra y that o utpu ts the code of the hig hest priority interrupt in the RP ce lls. Wh en R PT is asserted , the priority code is la tched into RPCELL. This is decoded into an add ress wh ich is the interrupt vector; the address is written to the read b us w hen RR PA is asserted. After the interrupt code has b een loa ded into RPCELL, asserting KRPT (knock-down R PT) causes the RP cell for that interrup t to be reset. Th is causes the n ext highest priority interrupt to be decod ed by the priority enc ode r. The INHINT and INHINT1 flip-flops in hibit interrupts.
The priority counter logic design is similar to the interrupt subsystem. Up (+) and down (-) count inpu t signa ls feed into 20 PCELLs, one PCELL for each counter. The PCELLs feed into the priority encoder wh ich outputs the code of the h ighe st priority PCELL having a up or down input set. The PCELL code is written to the PCELL register wh en W PCT R is asserted. The PC ELL m em ory address, derived from PCE LL, is written to read bus when RSCT is asserted. After the code is la tched into the PCE LL reg ister, the corresponding PCELL is reset by asserting WOVR. The up or down code for the selected PCELL is written to PSEQ when WPCTR is asserted. This code feeds to the control lo gic on the CT L m odu le wh ich selec ts the PIN C (in crem ent) or M INC (d ecrem ent) instruction subsequence to bump the priority counter up or down. The PIN C and MIN C su bsequ enc es are inse rted b etw een norm al in struc tion sub sequen ces. A SHINC subsequence implements a bit-shift which is used to load telemetry bits into the AGC and assemble them into words. SHINC is not implemented in this AGC replica.
J100-PROC: PROC-to-CTL I/F J100 is a 40-pin IDE cable that connects the PROC modu le to the CTL m odule. INPU TS (to PR OC): PIN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 signal WA3 WA2 WA1 WA0 RA3 RA2 RA1 RA0 WZ WYx WY WX WQ WOVR WOVI WOVC WLP WB WA LP WA F10X R24 R22 R2 R1C R1 RZ RU RSCT RSB RRPA RQ RLP RC RB14 RB RA KRPT CI fu ll n am e WRITE ADDR 3 (74) WRITE ADDR 2 (73) WRITE ADDR 1 (72) WRITE ADDR 0 (71) READ ADDR 3 (60) READ ADDR 2 (59) READ ADDR 1 (58) READ ADDR 0 (57) WRITE Z (50) WRITE Y NO RESET (49) WRITE Y (48) WRITE X (47) WRITE Q (45) WRITE OVF (41) WRITE OVF RUPT INH (40) WRITE OVF CNTR (39) WRITE LP (38) WRITE B (36) WRITE A/LP (35) WRITE A (34) F10 SCALER ONESHOT READ 24 (25) READ 22 (24) READ 2 (23) READ 1 COMP (22) READ 1 (21) READ Z (20) READ U (19) READ CNTR ADDR (18) READ SIGN (17) READ RUPT ADDR (16) READ Q (15) READ LP (13) READ C (11) READ BIT 14 (10) READ B (9) READ A (8) KNOCK DOW N RUPT (6) SET CARRY IN (1) state definition 0=W rite reg at address 3 (LP) 0=Write reg at address 2 (Z) 0=Write reg at address 1 (Q) 0=Write reg at address 0 (A) 0=Read reg at address 3 (LP) 0=Read reg at address 2 (Z) 0=Read reg at address 1 (Q) 0=Read reg at address 0 (A) 0=W rite Z 0= W rite Y (do n ot reset) 0=W rite Y 0=W rite X 0=W rite Q 0=W rite overflow 0= W rite overflow RU PT inh ibit 0=W rite overflow counter 0=W rite LP 0=W rite B 0=W rite A and LP 0=W rite A 1=timed out (100.0 Hz) 0=Read 24 0=Read 22 0=Read 2 0=R ead 1 comp limented 0=Read 1 0=Read Z 0=Read sum 0=R ead selected cou nter address 0= Rea d sign bit 0=R ead RU PT add ress 0=Read Q 0=R ead LP 0=Read C 0=Read bit 14 0=Read B 0=Read A 0= Kn ock do wn Rup t priority 0= Carry in
J101-PROC: PROC-to-CTL I/F J101 is a 40-pin IDE cable that connects the PROC modu le to the CTL m odule. INPU TS (to PR OC): PIN 1 2 3 4 5 6 7 8 19 20 signal R2000 WPCTR RPT INH CLRP CLINH1 CLINH GENRST CLK1 CLK2 fu ll n am e READ 2000 (101) WRITE PCTR (98) READ RUPT (94) SET INHINT (93) CLEAR RPCELL (92) CLEAR INHINT1 (88) CLEAR INHINT (87) GENERAL RESET (86) CLOCK1 CLOCK2 state definition 0=Read 2000 0=Write PCTR (latch priority counter seq) 0=Read RUPT opcode 0=Set INHINT 0=Clear RPCE LL 0=Clear INHINT1 0=Clear INHINT 0=G eneral Reset 1.024 MHz AGC clock 1 (normally low) 1.024 MHz AGC clock 2 (normally low)
OUT PUTS (from PRO C): PIN 21 22 23 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 signal SB_01 SB_02 IRQ WB_01 WB_02 WB_03 WB_04 WB_05 WB_06 WB_07 WB_08 WB_09 WB_10 WB_11 WB_12 WB_13 WB_14 WB_15 WB_16 fu ll n am e SUB SEL 01 SUB SEL 02 INT RQST WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE BUS BUS BUS BUS BUS BUS BUS BUS BUS BUS BUS BUS BUS BUS BUS BUS 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 state definition SB_01 is LSB; SB_02 is MSB 00=no counter; 01=PINC; 10=MINC 0=interrupt requested. (lsb)
J104-PROC: PROC-to-IO I/F J104 is a 40-pin IDE cable that connects the PROC modu le to the IO modu le. INPU TS (to PR OC): PIN 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 22 21 20 signal RB_01 RB_02 RB_03 RB_04 RB_05 RB_06 RB_07 RB_08 RB_09 RB_10 RB_11 RB_12 RB_13 RB_14 RB_15 RB_16 BUSY2 BUSY1 KB_STR fu ll n am e READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS state definition (lsb)
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
US (overflow ) bit SG (sign ) bit 0=OUT register output to read bus 0=INP register output to read bus 1=key pressed strobe; to KEYRU PT. Key data is valid on the negative edge of KB_STR. Data is latched until the next keypress.
OUT PUTS (from PRO C): PIN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 signal WB_01 WB_02 WB_03 WB_04 WB_05 WB_06 WB_07 WB_08 WB_09 WB_10 WB_11 WB_12 WB_13 WB_14 WB_15 WB_16 fu ll n am e WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS state definition (lsb)
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
J105-PROC: PROC-to-MEM I/F J105 is a 40-pin IDE cable that connects the PROC modu le to the MEM modu le. INPU TS (to PR OC): PIN 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 22 bus 21 signal RB_01 RB_02 RB_03 RB_04 RB_05 RB_06 RB_07 RB_08 RB_09 RB_10 RB_11 RB_12 RB_13 RB_14 RB_15 RB_16 BUSY7 BUSY5 fu ll n am e READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS state definition (lsb)
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
US (overflow ) bit SG (sign ) bit 0=BNK register output enabled to read 0=G register output enabled to read bus
OUT PUTS (from PRO C): PIN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 signal WB_01 WB_02 WB_03 WB_04 WB_05 WB_06 WB_07 WB_08 WB_09 WB_10 WB_11 WB_12 WB_13 WB_14 WB_15 WB_16 fu ll n am e WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS state definition (lsb)
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
RUPT1 RUPT3
Set the RUPT1 flip-flop (FF). Simulates a TIME3 overflow. Triggers a T3RUPT. Set the RUPT3 flip-flop (FF). Simulates a TIME4 overflow. Triggers a T4RUPT (DSR UPT). Set the RUPT4 flip-flop (FF). Simulates a DSKY keypress. Triggers a KEYRUPT.
RUPT4
TIME1
Set the TIME1 flip-flop (FF). Increments the low-order word of the AGC real-time clock. Set the TIME2 flip-flop (FF). Increments the high-order word of the AGC real-time-clock. Set the T IME 3 flip -flop (FF). Increm ents the gen eral p urp ose tim er. Set the T IME 4 flip -flop (FF). Increm ents the disp lay u pd ate tim er.
TIME2
TIME3 TIME4
PROC INDICATORS
The PR OC m odu le ha s a panel of in dica tor lam ps (L ED s) to sh ow the state o f PRO C reg isters and critical logic signals. These indicator lamps show the current state of all registers and some additional, important logic signals produced by the PROC module. AGC num bers are represented in octal, so all register lamps are in groups of three. At the time the photo was taken the AGC was running the COLOSSUS 249 flight software load, executing Verb 16, Noun 36 : a m onitor verb which displays the AGC real time clock.
Th e A LU con tains th e 16-bit ADDER (co lored ora ng e in the diagram ) w hich perform s 1's com plem ent arith m etic, and increm ents th e prog ram coun ter (Z regis ter). Each orang e box is a 4-bit parallel adder; collectively, they add 16 bits. The ADDER uses the X, Y, and U registers: X: the 1 6-bit e xtens ion reg ister (2 8- bit registe rs in yellow ) that h olds on e of two in puts to the ADDER. the 16-bit extension register (also in yellow) that holds the other input to the ADDER. the AD DER output (the 1 's complem ent sum of the contents of registers X and Y). Outputs to the bus labeled B on the diagram.
Y: U:
The ALU also contains the B and C registers: B: a gen eral-pu rpose b uffer register (sh own as 2 8 -bit registe rs in yellow ), also use d to pre-fetch the next instruction. At the start of the next instruction sequence, the upper bits of B (containing the next op code) are copied to the SQ register (in CTL), and the lower bits (the address) are copied to the S register in (MEM). Output to the bus labeled A on the diagram. not a separate register, but the 1's complement of B.
C:
The ALU contains logic (using 74L S18 1 AL U ch ips, sho wn in green) to do any of the following: select the B register; select the complement of the B register (the C re giste r); sele ct the U reg ister; select the C register ORed with U, or select log ical zero. Th ose log ic functions, needed for AGC operation, are shown in the upper right corner of the diagram. The outpu ts of th e 74 LS1 81 selec tor are gated through a buffer to the read bus. The original AGC could inclusive OR the outputs of any combination of registers onto the bus, but the control m odu le only used this feature for the B/C and U registers. One of the uses involved the MASK instruction, which is a logical AND: DeM organ 's theorem wa s used to im plem ent the e qu ivalent of a logical AND by inverting operands through the C register, performing a logical OR through the bus, and then invertin g the res ult. The 74 LS1 81 logic fun ction s are gated to the read bus through the data selector logic, shown in the adjacent diagram.
The ALU also transfers data from the READ bus to the WRITE bus for register-to- register da ta m oves: D ata is output from the source register onto the READ bu s, then transferred from the READ bus to the WRITE bus through the ALU, and finally loaded from the WRITE bus into the destina tion regis ter. The logic that translates the READ bus to the W RITE bus ca n also force the da ta lines o f the W RITE b us to specific states to gate various arithm etic constants onto the bus. The accompanying diagram shows the the control sig nal on th e left (RB 14, R 1, etc) an d to the right is the bit pattern thats ORed onto the bus when the signal is asserted. The defau lt state of the rea d bu s is logical zero, so if no other read signal is ass erted , the n um ber th at ap pea rs on th e bu s is the con stant; otherwise, its the constant inclusive ORed with the contents of the READ bus. The ALU contains REA D bus control logic. Registers in the MEM modu le, the central registers in the PROC m odu le, and the A LU a ll interface to the R EAD bus th roug h tri-state buffers. Th ese bu ffers are norm ally in the high-impedance state, but the control module (CTL) issues READ control sig nals to outp ut the conten ts of specific registers to the READ bus at certain times. Only one register should be gated onto the READ bus at any given time. When no READ control signals are asserted, the ALU gates its output onto the READ bus by default. When the control module gates a register onto the READ bus, a BUSY signal is sent to the ALU mod ule, which causes the ALU to inhibit its output. Because of propagation delays, the ALU might continue to output to the READ bus for a brief time while another register is also gated to the bus. To prevent this, all output to the read bus is inhibited during CLK1. This gives the control signals, which transition on the leading edge of CLK1, enough setup time to resolve th e conflict.
ALU INPUTS:
I/F CLK: signal CLK1 CLK2 CPM: RB RC RU R1 R1C R2 R22 R24 R2000 RB14 RSB WB CI WY WX WYX READ B READ C READ G READ REA D READ READ READ READ READ RE AD OCTAL 1 OC TAL -1 OCTAL 2 OCTAL 22 OCTAL 24 OCTAL 2000 BIT14 SIG N B IT 0=output B register to write bus 0=output comp of reg B (C) to write bus 0=output U register to write bus 0=incl 0=incl 0=incl 0=incl 0=incl 0=incl 0=incl 0=incl OR OR OR OR OR OR OR OR 000001 177776 000002 000022 000024 002000 020000 100000 w/write w/write w/write w/write w/write w/write w/write w/write bus bus bus bus bus bus bus bus fu ll n am e CLOCK 1 CLOCK 2 state definition 1=read bus setup; inhibit read bus out data transfer occurs on falling edge
0= write in to B from write bus 0=set carry register to 1 0=w rite Y 0= write in to X from write bus 0= write in to Y from write bus
RBUS: RB_01 ... RB_14 RB_15 RB_16 INP: OUT: CTR: INT: MBF: CRG: ADR: BUSY1 BUSY2 BUSY3 BUSY4 BUSY5 BUSY6 BUSY7 READ BUS 01 READ BUS 14 READ BUS 15 READ BUS 16 READ BUS BUSY READ BUS BUSY READ BUS BUSY READ READ READ READ BUS BUS BUS BUS BUSY BUSY BUSY BUSY
US (overflow) bit for read bus SG (sign) bit for read bus 0=valid data read bus 0=valid data read bus 0=valid data read bus 0=valid data 0=valid data 0=valid data 0=valid data from INP on from OU T on from CTR on from from from from INT on read bus MBF on read bus CRG on read bus ADR on read bus
MBF OUTPUTS:
I/F signal fu ll n am e state definition
WBUS: WB_01 ... WB_14 WB_15 WB_16 WRITE BUS 01 WRITE BUS 14 WRITE BUS 15 WRITE BUS 16
US (overflow) bit for write bus SG (sign) bit for write bus
A:
Z:
the 16-bit p rogra m cou nter, which contains the address of the next instruction to be executed.
Q:
the 1 6-bit reg ister used to hold the remainder in the DV instruction, and to hold the return address after TC instructions.
LP:
the 1 6-bit reg ister used to hold the lower product after MP instruction s.
Similarly, the WLP control pulse bit-shifts the WRITE bus into the LP register as follows (D0 on bit 14 of the LP reg ister mean s force the bit to zero): WLP B1, B1, D0, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2
The logic design for handling bit 14 of the LP register, which takes control inputs from W ALP , WLP , and W A3 is sh own here. W A3 is identical to WLP.
Depending upon the WALP, WLP, or WA3 inputs, bit 14 of LP will either be set to B1 of the WRITE bus, or forced to zero.
CRG INPUTS:
I/F CLK: signal CLK1 CLK2 CPM: RA RA0 RQ RA1 RZ RA2 RLP RA3 WA WA0 WQ WA1 WZ WA2 WA LP WLP GENRST WBUS: WB_01 ... WB_14 WB_15 WB_16 WRITE BUS 01 WRITE BUS 14 WRITE BUS 15 WRITE BUS 16 READ A READ A READ Q READ Q READ Z READ Z READ LP READ LP WRITE A WRITE A WRITE Q WRITE Q WRITE Z WRITE Z WR ITE A,LP WR ITE LP GENERAL RESET 0=output A to read bus 0=output A to read bus 0=output Q to read bus 0=output Q to read bus 0=output Z to read bus 0=output Zto read bus 0=output LPto read bus 0=output LP to read bus 0=load A from write bus 0=load A from write bus 0=load Q from write bus 0=load Q from write bus 0=load Z from write bus 0=load Z from write bus 0= load A ,LP from write bus 0=load LP from write bus 0=G eneral Reset fu ll n am e CLOCK 1 CLOCK 2 state definition 1=read bus setup; inhibit read bus output data transfer occurs on falling edge
US (overflow) bit for write bus SG (sign) bit for write bus
MBF OUTPUTS:
I/F signal RBUS: RB_01 ... RB_14 RB_15 RB_16 BUSY fu ll n am e READ BUS 01 READ BUS 14 READ BUS 15 READ BUS 16 READ BUS BUSY state definition
US (overflow) bit for read/write bus SG (sign) bit for read/write bus 0=output enabled to read bus
RUPT3
RUPT4
The AGC software responds to each interrupt by temporarily suspending the current program, executing a short interrupt service routine, and then resuming the interrupted program.
INT INPUTS:
I/F CLK: signal CLK1 CLK2 CPM: GENRST RRPA GENERAL RESET READ RUPT ADDRESS 0= reset IN T reg isters 0=o utput R PCELL ad dress (2004,2010,2014,2020,2024) to read bus 0=load RU PT opcode into RPCELL register 0=reset RUPT latch currently selected by RPCELL register 0=clear RPCELL register 0= test overflow ; if overflow, inhibit interrupt (set INHINT1) 0=clear INHINT1 register 0=set INHINT register 0=clear INHINT register fu ll n am e CLOCK 1 CLOCK 2 state definition 1=read bus setup; inhibit read bus out data transfer occurs on falling edge
READ RUPT OPCODE KN OC K D OW N R UP T PRIO CLEAR R PCELL WRITE OVF RUPT INH
US (overflow ) bit for write bus SG (sign) bit for write bus
0=trigger interrupt 1 (2004 octal; TIME3 overflow) 0=trigger interrupt 3 (2014 octal; TIME4 overflow) 0=trigger interrupt 4 (negative edge) (2020 octal; keyboard activity)
INT OUTPUTS:
I/F SEQ: signal fu ll n am e state definition
IRQ
INT RQST
0=interrupt requested. Active if allof the following are true: a) one or more RUPT FF's are set b) interrupt is not currently being serviced
RBUS: RB_01 ... RB_14 RB_15 RB_16 BUSY READ BUS 01 READ BUS 14 READ BUS 15 READ BUS 16 READ BUS BUSY
US (overflow) bit for read/write bus SG (sign) bit for read/write bus 0=output enabled to read bus
TIME2
35
TIME1
36
TIME3
37
TIME4
40
INT/CTR interface
This chart shows how counter overflows are handled. F10 (from the scaler) increments TIME1, TIM E3, a nd TIM E4. A positive overflow of TIME1 causes an increment of TIME2. Positive overflow of TIME3 triggers a T3R UPT interrup t. Positive overflow of TIME4 triggers a DSRUPT (T4RUPT) interrup t. The addresses of TIME1 and TIM E2 are reve rsed for Block II. This chart shows the Block I order, but my replica used the Block II order for com patib ility with the COLOSSUS flight software.
CTR INPUTS:
I/F CLK: signal CLK1 CLK2 CPM: GENRST WPCTR RSCT GENERAL RESET WRITE PSEQ READ PCELL ADDRESS 0= reset C TR regis ters 0= write seq uen ce into PSEQ 0=o utput PC ELL address (034-043) to read bus 0=test overflow and inc/dec OVCTR 0=clear selected PCELL and han dle counter overflow (if any) fu ll n am e CLOCK 1 CLOCK 2 state definition 1=read bus setup; inhibit read bus out data transfer occurs on falling edge
WOVC WOVR
WBUS: WB_15 WB_16 WRITE BUS 15 WRITE BUS 16 US (overflow) bit for write bus SG (sign ) bit for write bus
P3 CELL + COUNT
0= cou nt u p P3 cou nter (036 octal; TIME1) 0=coun t up P4 counter (037 octal; TIME3) 0=coun t up P5 counter (040 octal, TIME4) Note: priority cells 6-20 not implemented.
P4P
P4 CELL + COUNT
P5P
P5 CELL + COUNT
CTR OUTPUTS:
I/F signal fu ll n am e C OU N TE R O VE RF LO W : CPO_04 P4 + OVERFLOW state definition
0=P4 cell pos ovf (during WOVR) note: TIME3 + overflow; con nect to INT subsystem to trigger T3RUPT interrup t. 0=P5 cell pos ovf (during WOVR)
CPO_05
P5 + OVERFLOW
note: TIME4 + overflow; con nect to INT subsystem to trigger T4RUPT (DS RU PT) in terrupt.
SEQ: SB_01 SB_02 SUB SEL 01 SUB SEL 02 SB_01 is LSB; SB_02 is MSB 00=no counter; 01=PINC; 10=MINC
RBUS: RB_01 ... RB_14 RB_15 RB_16 BUSY READ BUS 01 READ BUS 14 READ BUS 15 READ BUS 16 READ BUS BUSY
US (overflow) bit for read/write bus SG (sign) bit for read/write bus 0=output enabled to read bus
Fabrication
The P RO C m odu le is (4) 13"x5 " circuit bo ards, an d 1 co ntrol pa nel.
Module Rack
The m odule framework is designed to resemble a relay rack, but scaled to fit the circuit board dim ensions. It is constructed out of 1"x2" pine and spray-painted semi-gloss gray. Circuit boards are mounted to the rack by 2 phillips screws at either end. Nylon spacers (1/4") are used as sta nd offs to h old the b oard edges above the rack. The boards are mounted so the chips are in the back an d th e pin s are w iring are visible from the front. Power is distributed by 2 heavy aluminu m bu s bars mounted vertically, one per side, on the back of the m odu le. M ach ine screw s are mounted through the bus bars at evenly-spaced intervals to provide connection points for the boards. Solid copper wire (24 gauge) connects the boards to the bus bars. Ring terminals are used on the bus bar side of the connection. On the circuit board size, the wires are soldered directly to the supply rails. Materials were purchased from Home Depot, ACE Hardware, and Radio Shack.
Circuit Boards
The circuit boards are 13"x5" general purpose prototyping boards, epoxy glass with doubleside plated throu gh pa ds on 0.1" cen ters (JAMEC O 21 477C L). ICs are mounted in level 3 machine tooled wire-wrap sockets: 8, 14, 16, 20, 24, and 28 pin (JAMEC O). Each socket has the pin-out labeled wit h a w ire-w rap sock et ID m arke r, wh ich slips o nto the socke t befo re wra pping (JAM ECO). T he p art num ber is writt en o nto the ID m arke r. Sockets are arranged in 4 horizontal rows on each board, with about 10 sockets per row. Power is distributed on the back-side of each board by bare 24-gauge solid copper wire supply rails soldered at equal intervals to Klipwrap terminals: 3-prong terminals with a square tail for wire-wrapping (JAMECO 341 63CL). A +5V rail runs above each row of sockets and a ground rail runs below. Each rail connects directly to the aluminum m odu le po we r bus using a ring tail co nn ector.
On the p in sid e of th e bo ard, all con nec tion s are m ade w ith 3 0 A W G K yna r wire -w rap wire (JAMECO ). Red wire is used for direct connections to the +5V supp ly rail. Black wire is used for direct connections to ground. White wire is used for everything else. Power connections from the supply rails to each ICs are double-wrapped. Bypassing capa citors (.1 uf d isc ) are sold ered ac ross the su pply rails at the Klipw rap term inals; abou t 1 capacitor for every 2 IC packag es. All connections were stripped and hand-wrapped using a Radio Shack hand-wrap tool. As each connection was made, the corresponding line on the schematic was marked with a colored h igh ligh ter. DIP resistor networks (JAMECO) plugged into 20-pin wire-wrap sockets were used as current limiting resistors for the panel ind icators.
Parts (ICs)
ICs, sockets, PCBs, resistors, capacitors, wire-wrap wire were purchased from JAMECO. IDE wire-wrap sockets were from DigiKey. W ire ties, wire-wrap tools, and copper wire were from Ra dio Sh ack. IDE rib bon cab les w ere purch ased from an o nlin e com pu ter su pp lier. 74LS00 74LS02 74LS04 74LS06 74LS08 74LS10 74LS20 74LS21 74LS27 74LS32 74LS83 74LS86 74LS112 74LS138 74LS148 74LS151 74LS181 74LS244 (9) (4) (11) (26) (4) (2) (2) (1) (1) (5) (4) (1) (7) (4) (2) (2) (4) (33) U60,U66,U57,U53,U51,U44,U46,U47,U42 U70,U6,U49,U2 U54,U45,U37,U68,U7,U36,U69,U71,U59,U48,U72 U2 8,U 29 ,U3 0,U 31 ,U2 7,U 26 ,U2 3,U 24 ,U2 5,U 22 ,U2 1,U 20 ,U1 8,U 19 ,U1 7,U 16,U15,U12,U13,U14,U11,U10,U35,U34,U33,U32 U63,U61,U56,U52 U50,U43 U67,U73 U1 U9 U4,U41,U40,U39,U38 U134,U135,U136,U137 U5 U65,U64,U62,U58,U55,U8,U3 U84,U85,U86,U94 U93,U97 U87,U88 U130,U131,U132,U133 U74,U75,U76,U77,U78,U79,U80,U81,U82,U83,U89,U90,U95,U96,U101, U102,U104,U105,U108,U111,U112,U115,U116,U117,U118,U119,U120, U121,U122,U124,U125,U128,U129 U91,U92,U98,U99,U100,U103,U106,U107,U109,U110,U113,U114,U123 ,U126,U127,U138,U139,U140,U141
74LS273
(19)
Power Budget
74LS00 74LS02 74LS04 74LS06 74LS08 74LS10 74LS20 74LS21 74LS27 74LS32 74LS83 74LS86 74LS112 74LS138 74LS148 74LS151 74LS181 74LS244 qty 9 4 11 26 4 2 2 1 1 5 4 1 7 4 2 2 4 33 mA (ea) 2.4 2.4 3.6 3.6 4.4 1.8 1.2 2.2 3.4 4.9 22 .0 6.1 4.0 6.3 12 .0 6.0 21 .0 32 .0 m A (tot) 21 .6 9.6 39 .6 93 .6 17 .6 3.6 2.4 2.2 3.4 24 .5 88 .0 6.1 28 .0 25 .2 24 .0 12 .0 84 .0 10 56 .0
74LS273 LED
19 153
17 .0 20 .0
Abstract
This report describes my successful project to build a working reproduction of the 1964 prototype for the Block I Apollo Guidance Computer. The AGC is the flight computer for the Ap ollo m oon lan din gs, and is the wo rlds first in tegra ted c ircuit com pu ter. I built it in my ba sem ent. It took me 4 yea rs. If you like, you can build one too. It will take you less time, and yours will be better than mine. I docum ented m y project in 9 separate .pdf files: Part 1 Part 2 Part 3 Part 4 Part 5 Part 6 Part 7 Part 8 O v ervie w : Introdu ces the p roject. CTL Module: Design and construction of the control module. PROC M odule: Design and construction of the processing (CPU) modu le. MEM Module: Design and construction of the mem ory module. IO Module: Design and construction of the display/keyboard (DSKY) m odule. Assem bler: A cross-a ssem bler for AG C softw are dev elopm ent. C+ + S imu lator: A low-level simulator that runs assemb led AGC code. Flight Software: My translation of portions of the COLOSSUS 249 flight software. Test & Che ckou t: A suite of test programs in AG C assembly langu age.
Part 9
Overview
The Memory Module (MEM) has 5 subsystems: MMI, ADR, EMM/FMM, MBF, and PAR
MM I (Mem ory Module external Interface) The M MI in terfaces oth er m em ory module subsystems (ADR, EMM/FMM, MB F, and PAR ; describ ed be low) to external AGC modules. 40-pin IDE connectors interface to the PROC and CTL m odules. Inputs from those modules are buffered to 1 LSTTL load. A 1 -pin con nector int erfaces to th e IO mod ule. EMM /FMM (Eraseable/Fixed Mem ory) The EMM/FMM is the AGC m emory. AGC mem ory is 16-bit word s, organized into 1024 word banks. The lowe st ban k (ba nk 0 ) is erasab le mem ory (EMM), originally implem ented as core, but implemented here as RAM. All banks above bank 0 are fixed mem ory (originally implemented as rope core, but implemented here as EPROM). The Block I AGC initially had 12K word s of fixed m em ory. This implementation has 15K. The MSB (bit 16) in memory is an odd parity b it. The low er 15 b its hold instructions or data. MB F (M em ory Bu ffer Reg ister) The MBF has the 16-bit mem ory buffer register which holds 16-bit data words m oving to and from mem ory. This is also called the G regis ter. The AG C tra nsfers da ta to a nd from m em ory th roug h th e G re giste r during the "m em ory cycle." The memory cycle takes 12 timing pulses (11.72 microseconds). During AGC operation, data w ords cycle continuo usly from m em ory to the G register and the n back again to memory. There are four locations in eraseable memory, at addresses 20-23 (octal), dubbed "editing location s" beca use w hate ver wa s stored th ere wo uld em erge sh ifted or rotated by on e bit position. This shifting is performed in the MBF. PAR (Parity Ge nerate and T est) The PA R g ene rates and tests th e m em ory p arity bit. Th e low er 15 bits o f each m em ory w ord
hold AG C instru ctions o r data. Ea ch w ord is prote cted b y a 16 th "od d pa rity" bit. This bit is set to 1 or 0 by a parity generator circuit so a count of the 1's in each memory word always prod uce s an odd nu m ber. A parity ch ecking circuit tests the p arity bit d urin g ea ch m em ory cycle; if the bit doesn't match the expected value, the memory word is assumed to be corrupted and a PARITY ALARM panel light illum inates on the IO module. ADR (M emo ry Address) The ADR constructs the AGC m emory address. The address is formed from the S register which holds the lower 12-bits that directly address the lowest 4K of memory, and the BANK register, w hich selects hig her m em ory ba nks w hen add ressing is in the fixe d-sw itchab le mod e.
The AGC transfers data to and from memory through the G register in a process called the "m em ory cycle." Th e m em ory cycle ta kes 12 timin g pu lses (11 .72 m icrosecon ds). Th e cycle beg ins at tim ing p ulse 1 (TP1 ) wh en th e AG C load s the m em ory ad dress to b e fetched into the S register in ADR. Memory hardware retrieves the data word from memory at the address specified by the S register. Words from erasable memory are deposited into the G register by timing pulse 6 (TP6); words from fixed memory are deposited by timing pulse 7. The retrieved m em ory w ord is then available in the G register for AGC access during timing pulses 7 through 10. After timing p ulse 10, data in the G register is written back to memory. The m em ory address is formed from the 12-bit S register and the 4-bit BANK register. M em ory in the lowest 4 1K ban ks is directly addressed by the S register. The higher 1K ban ks (5 -12 ) are address through the bank register as described in the ADR subsystem section of this do cum ent. The h igh- order bit in mem ory (bit 15) is an odd parity bit. If the me mo ry word is a data word, the 14 th bit is the sig n, an d bits 13 through 1 hold the magnitude. The num ber rep resen tation is 1's com plem ent. The first half of the mem ory cycle copies data from m em ory to the G register, The sign bit in m em ory (bit 1 4) is copied to bits 1 5 an d 14 of th e G re giste r. Bits 1 3 th roug h 1 in m em ory a re
copied to bits 13 th rough 1 in G. This is performed in the MB F and EMM /FMM subsystem s. The p arity bit (b it 16 in me m ory) is read by the PAR subs ystem and tested a gain st parity gen erate d on the m em ory w ord copied in to G. If the pa rity bits fail to m atch , a pa rity alarm is generated. The 14 th bit in the G register (and the central registers in the AGC) is called the Uncorrected Sign (U S). This extra sign bit is used as an overflow in dication in m ulti-word op erations. Normally, the Sign and Un corrected sign should agree. When overflow or underflow conditions occur, both signs will disagree, and are reconciled by software in an operation at the end of a lon g string of mu lti-word com putations. At the end of the memory cycle, the G register is copied back to memory. The sign bit in G (bit 15 ) is written to the sig n bit (b it 14) in me m ory. Bits 13 throug h 1 in G are w ritten to bits 13 through 1 in memory. A new odd parity bit is computed in the PAR subsystem and written to the 16 th bit in mem ory.
T hese d ia gra m s show the timing of the m em ory cycle. The top chart is a little m ore conceptual; the bottom cha rt show s the clock cycles and control pulses directly associa ted w ith reading erasea ble m em ory (SBEW G) or fixed m em ory (SBFWG) to the G register (the WG part m ean s write to G ) . T he WE pulse w rites G back to memory.
CLK1 steps the sequencer in the CTL module that enables the control signals. The signals have tim e to settle between CLK1 and CLK 2. Da ta tran sfer occ urs on CLK2.
This is a functional diagram of the ADR, EMM/FMM, and MBF subsystems in the MEM modu le. The diagram is m ine, but th e style is borrowed from original AGC documentation: con trol sig nals are represented by diamonds. The arrows show the direction of data flow. When a control signal is asserted, data is allow ed to flow through the diamond. For example, when WE is asserted, the contents of the G register are written into era seab le me mo ry (bank 0 ).
Note the different formats for data and instruc tion w ord in mem ory, shown at the bottom of the d ia gra m .
This is a functional diagram of the PAR subs ystem in the MEM m odule. The diagram was developed during the early stages of my AGC arch itectu re analysis in 2001.
J102-CTL: CTL-to-MEM I/F J102 is a 40-pin IDE cable that connects the MEM modu le to the CTL m odule. INPU TS (to CTL ): PIN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 signal WE S BW G GENRST W23 W22 W21 W20 WGn WBK RBK WS WP2 WPx WP WGx TP RP2 RG GP CLG CLK2 CLK1 NPURST SW CLK FCLK fu ll n am e WRITE EMEM (97) WRITE G (95) GENERAL RESET (86) WRITE ADDR 23 (85) WRITE ADDR 22 (84) WRITE ADDR 21 (83) WRITE ADDR 20 (82) WRITE G NORMAL (81) WRITE BNK (80) READ BNK (70) WRITE S (46) WRITE P2 (44) WRITE P NO RESET (43) WRITE P (42) WRITE G NO RESET (37) TEST PARITY (30) READ PARITY 2 (14) READ G (12) GEN PARITY (5) CLR G (2) CLOCK2 CLOCK1 POWER U P RESET DEBOUNCE CLOCK CLOCK MODE state definition 0=W rite E-MEM from G 0= W rite G from m em ory 0=G eneral Reset 0=Write into SL 0=W rite into CYL 0=Write into SR 0=W rite into CYR 0=W rite G (norm al gates) 0=W rite BNK reg 0=R ead BNK reg 0=W rite S 0=W rite P2 0= W rite P (do n ot reset) 0=W rite P 0= W rite G (do not reset) 0= Test pa rity 0=Read parity 2 0=Read G 0= Gen erate Pa rity 0= Clear G 1.02 4 M Hz A GC clock ph ase 2 (n orm ally low) 1.02 4 M Hz A GC clock ph ase 2 (n orm ally low) 0=reset, 1=normal operation. low freq clk for switch debounce (not used) 1= free-runn ing clk mo de; 0= sing le clk mode
OUT PUTS (from CTL): PIN 31 32 33 34 35 36 37 38 39 40 signal EQU_16 EQU_17 GTR_17 EQU_25 GTR_27 GTR_1777 AD_1 AD_2 AD_3 AD_4 fu ll n am e ADDRESS ADDRESS ADDRESS ADDRESS ADDRESS ADDRESS ADDRESS ADDRESS ADDRESS ADDRESS state definition 0=CADR in register S = 016 0=CADR in register S= 017 0=CADR in register S > 017 0=CADR in register S = 025 0=CADR in register S > 027 0=CADR in register S > 01777 where AD_4 is MSB, AD_1 is LSB
= 016 (1) = 017 (2) > 017 (3) = 025 (4) > 027 (5) > 01777 (6) (1) (2) (3) (4)
J105-MEM: MEM -to-PROC I/F J102 is a 40-pin IDE cable that connects the MEM modu le to the PROC modu le. INPU TS (to M EM): PIN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 signal WB_01 WB_02 WB_03 WB_04 WB_05 WB_06 WB_07 WB_08 WB_09 WB_10 WB_11 WB_12 WB_13 WB_14 WB_15 WB_16 fu ll n am e WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS state definition (lsb)
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
OUT PUTS (from ME M): PIN 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 22 21 signal RB_01 RB_02 RB_03 RB_04 RB_05 RB_06 RB_07 RB_08 RB_09 RB_10 RB_11 RB_12 RB_13 RB_14 RB_15 RB_16 BUSY7 BUSY5 fu ll n am e READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS state definition (lsb)
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
US (overflow ) bit SG (sign ) bit 0=BNK register output to read bus 0=G register output to read bus
AGC/MANUAL
Permits memory to be examined and loaded when the switch is in the MANUAL position and the AGC is halted.
EXAM
Loads the address counter with the contents of the switch register. To work, the following switches m ust also be set: AG C/M ANU AL --> MANUAL
NEXT
Steps the address to the next location. To work, the following switches must also be set: AGC/MANUAL --> MANUAL
READ/WR ITE
Displays m em ory contents in the R EAD position; displays sw itch register contents in the WRITE position.
LOAD
Load memory with data manually entered into the switch register. To work, the following switches must also be set prior to LOAD: CLOCK CON TRO L (on CTL m odule) --> STEP; A GC/M ANU AL --> M ANU AL; READ/WR ITE --> WRITE
CLEAR PARITY
Clears a parity alarm indication by resetting the parity alarm (PALM) register. The parity alarm indicator is on the IO modu le.
PIN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
fu ll n am e DATA1 DATA2 DATA3 DATA4 DATA5 DATA6 DATA7 DATA8 DATA9 DATA10 DATA11 DATA12 DATA13 DATA14 DATA15 DATA16 GND
MEM INDICATORS
These indicator lamps show the current state of all registers and som e add itiona l, imp ortant lo gic signals produced by the MEM m odu le. AG C n um bers are represen ted in o ctal, so all register lamps are in groups of three. At the time the photo was taken the AGC was running the COLOSSUS 249 flight softw are lo ad, executin g V erb 16 , Nou n 36: a m onitor verb wh ich disp lays th e AG C real tim e clock.
14-b it address 00000 02000 04000 06000 10000 12000 14000 16000 20000 22000 24000 26000 30000 -
01777 03777 05777 07777 11777 13777 15777 17777 21777 23777 25777 27777 31777
bank 0 1 2 3 4 5 6 7 8 9 10 11 12
BANK type (E) (FF) (FF) (FS) (FS) (FS) (FS) (FS) (FS) (FS) (FS) (FS) (FS)
Reg. ignored ignored ignored 0000 - 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100
BANK B4 X X
register (B) B3 B2 X X X X
B1 X X
X 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
X 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
X 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
X 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
1 1 1 1 1 0 0 1 1 0 0 1 1 0 0 1 1
0 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1
X= don t care
This is an early conceptual diagram of ADR architecture. The WRITE bus loads the B NK register or S reg ister. Outp uts from both registers feed into the bank decoder to gen erate the bank address.
The A DR gen erates som e logic signals to test the add ress. Thes e are inte rnally u sed in ME M a nd a lso m ade a vailab le to the external modules. The GTR signals test whether the generated address is greater than 1 777, 27 , or 17 (all octal).
The EQU logic tests whether the gen erated add ress is equ al to a sp ecific value: 14, 16, 17, or 25.
The bank select logic chooses betw een the S regis ter or a combination of the S register and the ba nk reg ister to generate addre ss b its 1 4-11 . It uses S register bits 11 and 12 to make the decision. The selection signa l enab les tristate buffer A or B to produce the correct bank ad dress.
ADR INPUTS:
I/F CLK: signal CLK1 CLK2 CPM: GENRST RBK WBK from write bus WS WBUS: WB_01 ... WB_14 WRITE BUS 01 WRITE BUS 14 GENERAL RESET READ BANK WRITE BANK 0= reset A DR regis ters 0=output BNK register to read bus 0=w rite into BNK register fu ll n am e CLOCK 1 CLOCK 2 state definition 1=read bus setup; inhibit read bus output data transfer occurs on falling edge
WRITE S
ADR OUTPUTS:
I/F signal MEM: AD_11 ... AD_14 fu ll n am e ADDRESS BUS 11 ADDRESS BUS 14 state definition ban k select bits
AD_1 ... AD_10 various: EQU_16 EQU_17 GTR_17 EQU_25 GTR_27 GTR_1777 RBUS: RB_01 ... RB_16 BUSY
in in in in in in
S S S S S S
READ BUS 01 READ BUS 16 READ BUS BUSY 0=output to read bus
CPM: WE erase able m em ory S BW G WR ITE ERASEABLE WRITE G (MEM) 0= write m em ory bu s to 0=read eraseable or fixed memory onto memory bus
ADR:
ADDRESS BUS 11
bank select portion of address bus bank select portion of address bus
ADDRESS BUS 14
BIDIRECTIONAL (IN/OUT):
I/F signal EMM/FMM: MEM_01 ... MEM_15 MEM_16 fu ll n am e MEMORY_BUS 01 MEMORY_BUS 15 MEMORY_BUS 16 state definition Mem ory word form ats: inst: 15-13 :op code; 12 -1:add ress data: 15:S G; 1 4-1 d ata parity (odd) bit for memory bus
Data is written from m em ory to G b y the S BW G con trol pulse . The sig n in m em ory (SG ; bit 15) is written to bit 16 in G. The parity bit (bit 16 in memory) is written to bit 15 in G by the P AR su bsy stem . SBWG: SG, BX, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1
Data is written into G from the WRITE bus using WG (no shift), or one of the following control pulses that prod uce the followin g shifts: W20: B1, BX, SG, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2
W21: SG, BX, SG, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2 W22: B14, BX, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, SG W23: SG, BX, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, SG Data is read from G to the READ bus as follows. The parity bit (bit 15 in G) is not transferred to the read bu s; instead, the sign b it is copied onto bits 15 an d 16 of the R EAD bus. RG: SG, SG, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1
Some of the design that went into the combinational logic that sets bit 16 in the G register from the READ bus is shown here. The MB _B1 6 ou tput co ntrols the 16th bit for the W20 and W 21 control pu lses.
The MB_C16 output controls the 16 th bit for the W22 and W23 control pulses.
MBF INPUTS:
I/F CLK: signal CLK1 CLK2 CPM: RG WE GTR_17 S BW G WGN WGX W20 W21 W22 W23 GENRST WBUS: WB_01 ... WB_14 WB_15 WB_16 WRITE BUS 01 WRITE BUS 14 WRITE BUS 15 WRITE BUS 16 READ G WR ITE ERASEABLE ADDRESS > 017 WRITE G (MEM) WRITE G WRITE G WRITE WRITE WRITE WRITE G G G G (SHIFT) (SHIFT) (SHIFT) (SHIFT) 0=output G register to read/write bus 0=output G register to memory bus 0=CADR in register S > 017 0=write G from memory bus 0= write G from rea d/w rite bus (no sh ift) 0= write G from rea d/w rite bus (no sh ift) 0=w rite G 0=w rite G 0=w rite G 0=w rite G 0=G eneral Reset fu ll n am e CLOCK 1 CLOCK 2 state definition 1=read bus setup; inhibit read bus output data transfer occurs on falling edge
GENERAL RESET
US (overflow ) bit for write bus SG (sign) bit for write bus
MBF OUTPUTS:
I/F signal RBUS: RB_01 ... RB_14 RB_15 RB_16 BUSY fu ll n am e READ BUS 01 READ BUS 14 READ BUS 15 READ BUS 16 READ BUS BUSY state definition
US (overflow) bit for read/write bus SG (sign) bit for read/write bus 0=output enabled to read bus
BIDIRECTIONAL (IN/OUT):
I/F signal EMM/FMM: MEM_01 ... MEM_15 MEM_16 fu ll n am e MEMORY_BUS 01 MEMORY_BUS 15 MEMORY_BUS 16 state definition Mem ory word form ats: inst: 15-13 :op code; 12 -1:add ress data: 15:S G; 1 4-1 d ata parity (odd) bit for memory bus
The PAR subsystem checks the m em ory pa rity bit durin g each me m ory cycle and gen erates an alarm if the parity bit in m em ory does not match the expected odd parity. The PAR subsystem also generates parity from the contents of G and writes this parity back to memory.
This block diagram of the PAR subsystem emerges from the previous diagram.
This is the combinational logic u sed to g enera te the input to the G15 register. Th is is the 1- bit register that holds bit 15 (the parity bit) for the G register. The remainder of the G register (bits 114 and bit 16) is in the M BF su bsy stem . The m interms are written ou t on top . De Morg an s Theo rem and a little bubble-pushing changes the OR gate into a NAND.
PAR INPUTS:
I/F CLK: signal CLK2 fu ll n am e CLOCK 2 state definition data transfer occurs on falling edge
CPM: RG RP2 WP WPX WP2 READ G15 READ P2 WRITE P WRITE P WRITE P2 0=w rite G15 into P 0=write P2 into G15 0=write P (same as WPX) 0=write P (same as WP) 0=write P2 from 1-15 generator 0= writ e G1 5 from m em ory parity b it 0=write G15 from 1-15 generator (same as WGX) 0=write G15 from 1-15 generator (same as GP) 0=clear G15 0=test parity from P-15
S BW G
GP WGX CLG TP ADR: GTR_27 WBUS: WB_01 ... WB_14 WB_15 WB_16 MON: CLRPLM
US (overflow) bit for write bus SG (sign) bit for write bus
PAR OUTPUTS:
I/F MON signal PARALM fu ll n am e PARITY ALARM state definition 1= parity alarm
BIDIRECTIONAL (IN/OUT):
I/F signal EMM/FMM: MEM_16 fu ll n am e MEMORY_BUS 16 state definition parity (odd) bit for memory bus
Fabrication
The M EM mo dule is (3) 13 "x5" circu it board s, and 1 con trol pan el.
Module Rack
The m odule framework is designed to resemble a relay rack, but scaled to fit the c ircuit boa rd dimensions. It is constructed out of 1"x2" pine and spray-painted semi-gloss gray. Circuit boards are mounted to the rack by 2 phillips screws at either end . Nylon s pacers (1 /4") are used as standoffs to hold the board edges above the rack. The boards are mounted so the chips are in the b ack and the p ins a re wirin g are visib le from the front. Power is distributed by 2 heavy aluminu m bu s bars mounted vertically, one per side, on the back of the module. Machine screws are mounted through the bus bars at evenly-spaced intervals to provide connection points for the boards. Solid copper wire (24 gauge) connects the boards to the bus bars. Ring terminals are used on the bus bar side of the connection. On the circuit board size, the wires are soldered directly to the supply rails. Materials were purchased from Home Depot, ACE Hardware, and Radio Shack.
Circuit Boards
The circuit boards are 13 "x5" general p urpose prototypin g boards, epo xy g lass with dou ble- side plated th roug h pads on 0.1" centers (JAM ECO 2147 7CL). ICs are mounted in level 3 machine tooled wire-wrap sockets: 8, 14, 16, 20, 24, and 28 pin (JAMEC O). Each socket has the pin-out labeled wit h a w ire-w rap sock et ID m arke r, wh ich slips o nto the socke t befo re wra pping (JAM ECO). T he p art num ber is writt en o nto the ID m arke r. Sockets are arranged in 4 horizontal rows on each board, with about 10 sockets per row. Pow er is di stribu ted o n th e ba ck-side o f each boa rd by bare 24-ga ug e solid copp er w ire supply rails soldered at equal intervals to Klipwrap terminals: 3-prong terminals with a squ are tail for w ire-wra ppin g (JA ME CO 341 63C L). A + 5V ra il runs a bove each row of soc kets
and a ground rail runs below. Each rail connects directly to the aluminum module power bus usin g a rin g tail con nec tor. On the p in sid e of th e bo ard, all con nec tion s are m ade w ith 3 0 A W G K yna r wire -w rap wire (JAMECO ). Red wire is used for direct connections to the +5V supp ly rail. Black wire is used for direct connections to ground. White wire is used for everything else. Power connections from the supply rails to each ICs are double-wrapped. Bypassing capacitors (.1 uf disc ) are soldered across the supply rails at the Klipwrap terminals; about 1 capacitor for every 2 IC packag es. All connections were stripped and hand-wrapped using a Radio Shack hand-wrap tool. As each connection was made, the corresponding line on the schematic was marked with a colored h igh ligh ter. DIP resistor networks (JAMECO) plugged into 20-pin wire-wrap sockets were used as current limiting resistors for the panel ind icators.
Parts (ICs)
74LS00 74LS02 74LS04 74LS06 74LS10 74LS20 74LS27 74LS74 74LS86 74LS154 74LS193 74LS244 (11) (3) (12) (21) (3) (2) (2) (1) (1) (1) (4) (31) U50,U25,U26,U27,U40,U32,U33,U34,U43,U44,U53 U52,U31,U55 U39,U28,U51,U56,U48,U46,U45,U41,U30,U35,U36,U54 U2 0,U 19 ,U1 8,U 15 ,U1 6,U 17 ,U1 4,U 13 ,U1 2,U 10 ,U1 1,U 9,U 6,U 7,U 8,U 5,U 4,U21,U22,U23,U24 U49,U37,U42 U47,U29 U2,U38 U1 U3 U72 U63,U64,U65,U66 U57,U58,U59,U60,U61,U62,U67,U68,U69,U70,U71,U73,U83,U84,U85, U86,U87,U88,U89,U90,U91,U92,U93,U94,U95,U96,U97,U98,U103,U10 4,U105 U74,U75,U76,U79,U80,U81,U82,U106,U107,U108 U77,U78 U99,U100 U101,U102
Power Budget
74LS00 74LS02 74LS04 74LS06 74LS10 74LS20 74LS27 74LS74 74LS86 74LS154 74LS193 74LS244 74LS273 74LS280 27C128 2016 LED qty 11 3 12 21 3 2 2 1 1 1 4 31 10 2 2 2 124 mA (ea) 2.4 2.4 3.6 3.6 1.8 1.2 3.4 4.0 6.1 6.2 19 .0 32 .0 17 .0 16 .0 25 .0 25 .0 20 .0 m A (tot) 26 .4 7.2 43 .2 75 .6 5.4 2.4 6.8 4.0 6.1 6.2 76 .0 99 2.0 17 0.0 32 .0 50 .0 50 .0 24 80 .0 ------4.0 Amps total 1.6 Am ps (excludin g LEDs)
Abstract
This report describes my successful project to build a working reproduction of the 1964 prototype for the Block I Apollo Guidance Computer. The AGC is the flight computer for the Ap ollo m oon lan din gs, and is the wo rlds first in tegra ted c ircuit com pu ter. I built it in my ba sem ent. It took me 4 yea rs. If you like, you can build one too. It will take you less time, and yours will be better than mine. I docum ented m y project in 9 separate .pdf files: Part 1 Part 2 Part 3 Part 4 Part 5 Part 6 Part 7 Part 8 O v ervie w : Introdu ces the p roject. CTL Module: Design and construction of the control module. PROC M odule: Design and construction of the processing (CPU) modu le. MEM Module: Design and construction of the mem ory module. IO Module: Design and construction of the display/keyboard (DSKY) m odule. Assem bler: A cross-a ssem bler for AG C softw are dev elopm ent. C+ + S imu lator: A low-level simulator that runs assemb led AGC code. Flight Software: My translation of portions of the COLOSSUS 249 flight software. Test & Che ckou t: A suite of test programs in AG C assembly langu age.
Part 9
Overview
The I/O Module (IO) has 5 subsystems: IMI, KBD, INP, OUT, DSP IM I (I/O M od ule external Interface) The IMI interfaces the I/O module to other AG C m odu les. 40-p in IDE con nec tors interface to the PROC and CTL modules. A 1pin connector interfaces to the MEM m odule. Inputs taken those m odu les are bu ffered to 1 LSTTL load. KBD (Keyboard) An 18-button keyboard; the AGCs flight software user input interface. The keyb oard/d isplay unit is called the DSKY. INP (Input Registers) The A GC has 4 16-b it input registers that receive data from the keyb oard a nd d iscrete logic signals. IN0 reads from the keyboard and the STANDBY ALLOWED discrete signal. IN1-IN3 are no t imp lem ented in this replica. OUT (Output Registers) The A GC has 5 16-b it output registers that drive the DSKY display and oth er spa cecra ft subsystems. OUT0 writes to the DSKY display; OUT1 drives the 6 discrete indicator lamps on the AGC DSKY display; OUT2-OUT4 are not implemented in this replica.
DSP (Display) A m atrix of green 7-segment displays; the output side of the AGCs flight software user interface. There are (3) 5-digit displays with +/- signs which can display decimal or octal data, and (3) 2-digit displays to show the current program (PROG), verb, and noun. An ad ditional pan el of 6 indicator lam ps show s AGC status and a larm states.
AGC input registers and control signals that read them onto the b us a re show n in th e diag ram to the righ t. The 5 -bit keyboard code and STA NDB Y ALLO WE D sw itch are read from register 0" (IN0) when the R4 (RA4) con trol pulse is asserted . The sign al is R4 becau se the reg ister is m app ed to memory address 4. The registers are actua lly buffers, not latches. Keyboard codes are latched inte rnally in the k eyb oard su bsy stem . The IN1, IN2, and IN3 registers are not im plem ented in this replica.
AGC output registers are shown in the next figure. OUT0 drives the 7-segment DSKY displays. W10 (WA10) loads data from the write b us into the D SK Y disp lay; th e 10" is because it is mapped onto memory location 10 (octal). Each 16-bit word controls 2 digits on the dis play . The d igit pa ir is selected b y a 4-b it code at the top of the word. OUT1 drives discrete indicator lamps on a panel adjacent to the 7-segment display. W11 (WA11) writes to the register, and R11 (RA11) reads from it. The OUT2 , OUT3, and OU T4 registers are not implemented in this replica.
J103-IO: CTL-to-I/O I/F INPU TS (to IO): PIN 1 2 3 5 6 7 8 9 20 signal CLK1 CLK2 NSA GENRST WA11 WA10 RA11 RA4 STBY fu ll n am e CLOCK1 low) CLOCK2 low) STANDBY ALLOW ED GENERAL RESET (86) WRITE OUT1 (76) WRITE OUT0 (75) READ OUT1 (66) READ IN0 (61) STANDBY state definition 1.02 4 M Hz A GC clock ph ase 2 (n orm ally 1.02 4 M Hz A GC clock ph ase 2 (n orm ally 0=standb y allowed 0=clear the DSKY, OUT1, and OUT2. 0=write into OUT1 from write bus 0=write into OUT0 (DSKY) from write bus 0=output OUT1 register to read bus 0=output IN0 register to read bus 0= AG C is in th e stan dby state
OUT PUTS (from IO): PIN 40 signal OUT1_8 fu ll n am e STANDBY ENA BLED state definition 1=standby enabled; works with STANDBY ALLOW ED sw itch
J104-IO: PROC-to-IO I/F INPU TS (to IO): PIN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 signal WB_01 WB_02 WB_03 WB_04 WB_05 WB_06 WB_07 WB_08 WB_09 WB_10 WB_11 WB_12 WB_13 WB_14 WB_15 WB_16 fu ll n am e WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS WRITE BUS state definition (lsb)
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
OUT PUTS (from IO): PIN 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 22 21 20 signal RB_01 RB_02 RB_03 RB_04 RB_05 RB_06 RB_07 RB_08 RB_09 RB_10 RB_11 RB_12 RB_13 RB_14 RB_15 RB_16 BUSY2 BUSY1 KB_STR fu ll n am e READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS READ BUS state definition (lsb)
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
US (overflow ) bit SG (sign ) bit 0=OUT registers output to read bus 0=INP registers output to read bus 1=key pressed strobe; to KEYRU PT. Key data is valid on the negative edge of KB_STR. Data is latched until the next keypress.
IO DISPLAY/KEYBOARD (DSKY)
The keyboard/display portion of the IO module contains a keyboard, a bank of 7-segment displays, a pan el of discrete indicator lamps, an d a board of display drivers.
DSKY KEYBOARD
The DSKY has an 18-button keyboard:
0-9 + VERB
Decim al (or octal) digits. Plus sign for decim al entries. Minu s sign for decima l entries. Tells the AG C the next 2 digits entered will be a VERB. Tells the AG C the next 2 digits entered will be a NOUN. Tells the AG C the data entry is finished. Clears an error in entry. Resets the OPR ERR alarm lamp. Tells the AGC it can have control of the dis play . If the AGC wa nts control of the display, the KEL REL lamp will be flashing.
NOUN
ENTER
PROG
VERB
NOUN
R1
Register 1. The uppermost of the three 5-digit displays. Registers R1, R2, and R3 can display data in octal or decimal. Octal data is displayed without a sign. Decimal data is indicated by the presence of a + or - sign in front of the data. The displays I used in my replica cannot display a + sign, so I modified the logic slig htly: d ecim al da ta is represe nted by a leftm ost decim al poin t. Negative decimal numbers have a - sign and the decimal point; positive numbers just have the decimal point. Driven by OUT0. Register 2. The middle of the three 5-digit displays. Driven by OUT0. Register 3. The bottommost of the three 5-digit displays. Driven by OUT0.
R2 R3
IO DISCRETE INDICATORS
The DSKY has a panel of discrete indicator lamps (LEDs) to show status or caution and wa rning signa ls. Four of th e lam ps are d riven b y bits in outp ut registe r 1 (OU T1). Th e parity alarm is driven by a signal from the MEM module. The standby lamp is driven by the standby state of the time pulse generator (TPG) in the CTL module.
UPLINK ACTY
Uplink activity. Illum inates when data is uplinked to the AGC. Driven by bit 3 (UPTL) of OUT1. Operator Error (also called CHECK FAIL). Illuminates when the AGC detects a data entry error. Driven by bit 7 of OUT1. Key Release. Illuminated by the AGC when it needs to use the display, but th e opera tor has ta ken co ntrol of it. The AG C cau ses this la m p to flash to signal the operator to release control of the display by hitting the KEY REL button. Driven by bit 5 (KEY RELS) of OUT1. Program Alarm. Illuminates when the AGC encoun ters an error condition. Driven by bit 8 of OUT1. Standby. Illuminates when the AG C is in the STANDB Y mod e. Illum inates wh en a p arity error is dete cted d uring the m em ory cycle in the MEM m odule.
OPR ERR
KEY REL
PROG
KBD (Keyboard)
The keyboard is an 18-pushbutton unit that gen erates an d latch es a 5-b it code. Th e code is given in Keyboard and Display System Program for AGC (Program Sun rise), A. I. Green and J. J. Rocchio, E-1574, MIT Instrumentation Laboratory, Cambridge, MA, 1964.
The keyboard codes and logic for generating the 5-bit signal is reproduced to the right. The Key Name column identifies the name of the keyb oard k ey; A throug h E are the 5 lo gic signals for the 5-bit code, where A is the MSB.
The 18 switches in the keyboard feed into the combinational logic encoder wh ich ge nerate s the 5 -bit signal. The output of the enco der feeds into a 5 -bit latch. The keys are debounced by generating a keypress sign al wh enev er a key is pushed. The keypress signal feeds through a D flip-flop clocked at around 100Hz. This sam ples the keyp ress signal every 10 mSec and latches the sample. The 10 mSec interval exceeds the contact bounce time of the keyboa rd switches. To give the combinational logic time to settle before the keycode is latched, the output of the keypress D flip-flop is fed into an RC monstable. Latching occurs on the trailing edge of the one-shot pulse. The keyboard codes are fed into input register IN0, which is really just a buffer that gates the codes on to the read bu s when the proper read sign al is asserted. The original design also map s the keypress strobe which generates the keyboard interrupt (KEYRUPT) onto bit 6 of
the register, but I skipped this since there doesnt seem to be any practical reason for doing it an d th e CO LOSS US fligh t softw are d oesn t seem to loo k at th e field . The STANDBY ALLOWED switch (CTL module) maps to be 14.
KBD INPUTS:
I/F CLK: CLK2 CLOCK 2 data transfer occurs on falling edge signal fu ll n am e state definition
KBD OUTPUTS:
I/F signal fu ll n am e state definition
KBD: KB_01 ... KB_05 KEYBOARD BUS 01 KEYBOARD BUS 05 Keyboard codes
INT: KB_STR KEY STROBE 1=key pressed strobe; to KEYRU PT. Key data is valid on the negative edge of KB_STR. Data is latched until the next keypress.
KBD: KB_01 ... KB_05 NSA KEYBOARD BUS 01 KEYBOARD BUS 05 STANDBY ALLOW ED 0=standb y allowed
INP OUTPUTS:
I/F RBUS: RB_01 ... RB_14 RB_15 RB_16 BUSY READ BUS 01 READ BUS 14 READ BUS 15 READ BUS 16 READ BUS BUSY signal fu ll n am e state definition
US (overflow) bit for read/write bus SG (sign) bit for read/write bus 0=output enabled to read bus
0=load OU T1 write bus 0=load OU T2 write bus 0=load OU T3 write bus 0=load OU T4 write bus
GENRST
GENERAL RESET
WBUS: WB_01 ... WB_14 WB_15 WB_16 WRITE BUS 01 WRITE BUS 14 WRITE BUS 15 WRITE BUS 16
US (overflow) bit for write bus SG (sign ) bit for write bus
OUT OUTPUTS:
I/F DSP: OT0_01 ... OT0_16 OUT0 REG 01 OU T0 reg ister outp ut to DSKY signal fu ll n am e state definition
OUT0 REG 16
01 03 05 07 08 09
COM P panel indicator; 1=on UPTL panel indicator; 1=on KEY RELS p anel indicator; 1=on CHECK FAIL panel indicator 1=on STBY pan el indicator 1=on PROG ALM pan el indicator 1=on
RBUS: RB_01 ... RB_14 RB_15 RB_16 BUSY READ BUS 01 READ BUS 14 READ BUS 15 READ BUS 16 READ BUS BUSY
US (overflow) bit for read/write bus SG (sign) bit for read/write bus 0=output enabled to read bus
DSP (Display)
The 7 -segm ent D SK Y disp lay is driv en b y outp ut registe r 0 (OU T0). Ea ch 16 -bit w rite to OU T0 w rites d ata to a p air of 7 -seg m ent dig its.
Four fields in OUT0 are involved: The relay word (RLYWD ; bits 12-15) field selects the pair of digits; the DSPH field (bits 6-10) contains the 5-bit numerical code for the left digit in the pair, an d DP SL (b its 1-5) has th e code for the righ t digit. Th e 1-b it DPS C (bit 1 1) field controls verb/noun flash (enables 1 Hz blinking of the VERB and NOUN digits) and the plus and minus signs to the left of the three 5-digit registers on the DSKY display. Bits 15-12 R LY W D 1011 1010 1001 1000 0111 0110 0101 0100 0011 0010 0001 Bit 11 DSPC FLASH UPACT +R1S -R1S +R2S -R2S +R3S -R3S Bits 10-6 DSPH MD1 VD1 ND1 R1D2 R1D4 R2D1 R2D3 R2D5 R3D2 R3D4 Bits 5-1 DSPL MD2 VD2 ND2 R1D1 R1D3 R1D5 R2D2 R2D4 R3D1 R3D3 R3D5
Each 7-segment digit on the display has a name (VD1, VD2, etc). The digits are physically arran ged like this: MD1 ND1 R1D3 R2D3 R3D3 R1D4 R2D4 R3D4 MD2 ND2 R1D5 R2D5 R3D5 : major mode (PROG) : NOUN : regi ster 1 : regi ster 2 : regi ster 3
In m y assem bled unit, th e disp lays w ere in gro ups of 3, so som e digits were not needed and left unwired.
The 5-bit codes that illuminate each digit in the display are given below; these are the codes sent to the DPSH and DPSL fields in OUT0. In my implementation, I translate them into 4-bit binary-coded decimal representation (BCD) and feed them into a 74LS4 7 7-segm ent decoder. The mapping of the AGC digit to my
74LS47 d ecoder code is also given. The AGC digit codes are very peculiar; I suspect they were chosen for easy decoding in to the 7-segm ent displays. Dig it Blank 0 1 2 3 4 5 6 7 8 9 AGC 00000 10101 00011 11001 11011 01111 11110 11100 10011 11101 11111 74LS47 1111 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001
My initial block diagram for the DSP logic is shown here. Two combinational logic code converters changes the 5-bit AGC code (DS PH, DPSL) into 4-bit BCD. The converted codes are la tche d in to 4- bit reg isters b y w rite pu lses d ecod ed b y the rela y w ord (RLY W D) d ecod er. Single b it latches hold the flash an d sign bit code s transm itted by DS PC (bit 11 of OUT0 ). Altho ugh I show separa te deco ders for each digit, I actua lly m ultiple xed th e disp lay to minimize the hardware. In this way, I only needed a pair of 74LS47 decoders; one for DSPH and the other for DSPL.
Some back-of-the-envelope bits and pieces of the logic design are also shown here. One diagram shows the verb/n oun flash log ic. Note th e sim ple Karnaugh map (a graphical method for reducing boolean expressions), and a bit of bubble-pushing (a graphical tec hn ique for a pp lying De Morg an s Theorem to transform logic functions betwee n AN D an d OR ).
The other diagram shows the logic for the +/- signs on registers 1, 2, and 3. The displays I used in my replica cannot display a + sign, so I modified the AGC logic slightly: decimal data is represented by a leftmost decimal point. Negative decimal numbers have a - sign and decim al point; po sitive deci m al n um bers just ha ve the decim al poin t.
The d igit disp lay po rtion of the DS KY u ses green com m on-a nod e LED displa ys grou ped in threes. Like most com ponen ts, these were purcha sed from JA MEC O. Heres the pinouts:
A pan el of discrete indicator LEDs are m apped against bits in ou tput register 1 (OU T1).
DSP INPUTS:
I/F CLK: CLK2 CLOCK 2 data transfer occurs on falling edge signal fu ll n am e state definition
INP: OT0_01 ... OT0_15 OUT0 REG 01 OUT0 REG 15 OUT0 register output to DSKY
OUT1 REG 01 OUT1 REG 03 OUT1 REG 05 OUT1 REG 07 OUT1 REG 08 OUT1 REG 09
COM P panel indicator; 1=on UP TL p anel indica tor; 1=on KEY RELS p anel indicator; 1=on CHECK FAIL panel indicator 1=on STBY pan el indicator 1=on PROG ALM pan el indicator 1=on
CPM: WA10 WRITE OUT0 0=write into OUT0 (DSKY) from write bus 0=clear the DSKY.
GENRST
GENERAL RESET
DSP OUTPUTS:
I/F none. signal fu ll n am e state definition
Fabrication
The IO modu le is (2) 13"x5" circuit boards, and 1 DSKY panel containing a display driver board, a 7-segment display board, a discrete LED indicator board, and a keyboard.
Module Rack
The m odu le fram ewo rk is desig ned to resemble a relay rack, but scaled to fit the circuit board dimensions. It is constructed out of 1"x 2" pin e and spray- pain ted sem igloss gray. Circuit boards are mounted to the rack by 2 ph illips screw s at either end . Nylon s pacers (1/4") are used as standoffs to hold the boa rd ed ges abo ve th e rack . The boa rds a re mounted so the chips are in the back and the pins are wiring are visible from the front. Power is distributed by 2 heavy aluminum bus bars moun ted vertically, one per side, on the back of the module. Machine screws are mounted through the bus bars at evenly-spaced intervals to provide connection points for the boards. Solid copper wire (24 gauge) connects the boa rds to the b us b ars. R ing term ina ls are used on the bus bar side of the connection. On the circuit board size, the wires are soldered directly to the supply rails. Materials were purchased from Home Depot, ACE Hardware, and Radio Shack.
Circuit Boards
The circuit boards are 13"x5" general purpose prototyping boards, epoxy glass with doubleside plated throu gh pa ds on 0.1" cen ters (JAMEC O 21 477C L). ICs are mounted in level 3 machine tooled wire-wrap sockets: 8, 14, 16, 20, 24, and 28 pin (JAMEC O). Each socket has the pin-out labeled wit h a w ire-w rap sock et ID m arke r, wh ich slips o nto the socke t befo re wra pping (JAM ECO). T he p art num ber is writt en o nto the ID m arke r. Sockets are arranged in 4 horizontal rows on each board, with about 10 sockets per row. Power is distributed on the back-side of each board by bare 24-gauge solid copper wire supply rails soldered at equal intervals to Klipwrap terminals: 3-prong terminals with a square tail for wire-wrapping (JAMECO 341 63CL). A +5V rail runs above each row of sockets and a ground rail runs below. Each rail connects directly to the aluminum m odu le po we r bus using a ring tail co nn ector.
On the p in sid e of th e bo ard, all con nec tion s are m ade w ith 3 0 A W G K yna r wire -w rap wire (JAMECO ). Red wire is used for direct connections to the +5V supp ly rail. Black wire is used for direct connections to ground. White wire is used for everything else. Power connections from the supply rails to each ICs are double-wrapped. Bypassing capa citors (.1 uf d isc ) are sold ered ac ross the su pply rails at the Klipw rap term inals; abou t 1 capacitor for every 2 IC packag es. All connections were stripped and hand-wrapped using a Radio Shack hand-wrap tool. As each connection was made, the corresponding line on the schematic was marked with a colored h igh ligh ter. DIP resistor networks (JAMECO) plugged into 20-pin wire-wrap sockets were used as current limiting resistors for the panel ind icators.
IO Circuit Board A
The A board contains the module interface buffers, input and output registers, and the latches that hold the BCD codes for the 7-segm ent displays.
IO Circuit Board B
The B board conta ins key boa rd an d disp lay log ic. The 4 0-pin IDE con necto rs that in terface to the other modules are visible at the bottom. The 5 red LEDs show the keyboard code latched into the K BD outp ut reg ister.
An empty space at the top of the IO module rack was filled with a plexiglass panel listing verb and noun codes:
Parts (ICs)
ICs, sockets, PCBs, resistors, capacitors, wire-wrap wire were purchased from JAMECO. IDE wire-wrap sockets were from DigiKey. W ire ties, wire-wrap tools, and copper wire were from Ra dio Sh ack. IDE rib bon cab les w ere purch ased from an o nlin e com pu ter su pp lier. 74LS00 74LS02 74LS04 (13) (3) (27) U27, U27B, U27C, U15C, U15B, U15, U14C, U14B, U14, U29D, U29C, U29B, U34B U25,U25,U33C U40E, U40D, U38D, U38C, U40F, U40C, U39E, U39D, U39C, U39B, U41D, U40B, U37F, U39F, U12, U12B, U12C, U12D, U12E, U11F, U11E, U11D, U11C, U11B, U11, U39A, U37 U26F, U26E, U26D, U26C, U26B, U26, U20, U18D, U18C, U18B, U18, U20C, U17E, U17D, U20B, U16F, U16E, U9, U9B, U9C, U9D, U9E, U9F, U10, U10B, U10C, U10D, U7, U7B, U7C, U7D, U7E, U7F, U8, U20, U19F, U19E, U19D, U19C, U19B, U19 U28 U4 U2, U3, U5, U31, U32 U35C, U36 U46, U47, U48, U45 U1 U24C U6A, U23B, U22B, U21B, U30 U50, U67, U68, U69, U70, U73, U74, U75, U76 U65, U66, U71, U72 U51 U49 U101, U100, U52, U53, U77, U78, U81, U82, U83, U84 U79, U80, U44 U54, U55, U56, U57, U58, U59, U60, U61, U62, U63, U64 DISP1, DISP2, DISP3, DISP4,DISP5, DISP6, DISP7, DISP8, DISP9, DISP10, DISP11, DISP12, DISP13, DISP14, DISP15, DISP16, DISP17, DISP18, DISP19, DISP20, DISP21 U85, U42, U43 Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q15, Q16, Q17, Q18, Q19, Q20, Q21, Q32, Q33, Q34, Q35, Q36, Q37, Q38, Q39, Q40, Q41, Q42, Q43, Q44, Q45, Q8, Q9, Q10, Q11, Q12, Q13, Q14 Q22, Q23, Q24, Q25, Q26, Q27, Q28, Q29, Q30, Q31, Q46, Q47, Q48, Q49, Q50, Q51, Q52, Q53, Q54, Q55, Q56, Q57
74LS06
(41)
74LS08 74LS10 74LS20 74LS27 74LS47 74LS74 74LS86 74LS112 74LS138 74LS148 74LS154 74LS161A 74LS244 74LS273 74LS374 GREENCA
(1) (1) (5) (2) (4) (1) (1) (5) (9) (4) (1) (1) (10) (3) (11) (21)
555 NPN3
(3) (35)
PNP3
(22)
Power Budget
74LS00 74LS02 74LS04 74LS06 74LS08 74LS10 74LS20 qty 13 3 27 41 1 1 5 mA (ea) 2.4 2.4 3.6 3.6 4.4 1.8 1.2 m A (tot) 31 .2 7.2 97 .2 14 7.6 4.4 1.8 6.0
74LS27 74LS47 74LS74 74LS86 74LS112 74LS138 74LS148 74LS154 74LS161 74LS244 74LS273 74LS374 555 3 GREENCA LED 25
2 4 1 1 5 9 4 1 1 10 3 11 3.0 21 20 .0
3.4 7.0 4.0 6.1 4.0 6.3 12 .0 6.2 19 .0 32 .0 17 .0 27 .0 9.0 14 0.0 50 0.0
Abstract
This report describes my successful project to build a working reproduction of the 1964 prototype for the Block I Apollo Guidance Computer. The AGC is the flight computer for the Ap ollo m oon lan din gs, and is the wo rlds first in tegra ted c ircuit com pu ter. I built it in my ba sem ent. It took me 4 yea rs. If you like, you can build one too. It will take you less time, and yours will be better than mine. I docum ented m y project in 9 separate .pdf files: Part 1 Part 2 Part 3 Part 4 Part 5 Part 6 Part 7 Part 8 O v ervie w : Introdu ces the p roject. CTL Module: Design and construction of the control module. PROC M odule: Design and construction of the processing (CPU) modu le. MEM Module: Design and construction of the mem ory module. IO Module: Design and construction of the display/keyboard (DSKY) m odule. Assem bler: A cross-a ssem bler for AG C softw are dev elopm ent. C+ + S imu lator: A low-level simulator that runs assemb led AGC code. Flight Software: My translation of portions of the COLOSSUS 249 flight software. Test & Che ckou t: A suite of test programs in AG C assembly langu age.
Part 9
Overview
This A GC cross-asse m bler, code d in C ++ , produ ces AG C ob ject code in M otorola S -form at. The code can be burned into EPROM for use by the hardware AGC, or executed by the C++ AG C sim ula tor.
Operation
The assembler reads an AGC source code text file (having a .asm extension). It generates an assembly listing text file (.lst extension) and an two object code text files (_H.hex and _L.hex suffixes). The object code files are readable by the AGC simulator or an EPROM prog ram m er.
Syntax
Sou rce code files are text files con tainin g m ultiple lines of sou rce code . Each lin e is terminated by a newline character. Source code files can be produced by any editor, as long as it doesn't insert any hidden characters or formatting information. Each line of source code consists of one of the following: a) A blank line. b) A com me nt (com me nts m ust begin with a sem icolon (;)). c) A line of assembler code. The assembler ignores blank lines and anything that occurs after a semicolon on any given line. A line of assem bler code consists of the following comp onents: 1) A label (this is optiona l). 2) An op code or assembler directive. 3) An op erand (also op tional). 4) A com me nt (optional; com me nts m ust start with a sem icolon). The comp onents, if present, mu st appear in the order given. Each component is separated from th e nex t by on e or m ore wh ite spac es or tabs . The on ly cons traint is th at the la bel, if present, must start in the 1st colum n of the line. If no label is present, the op code or assembler directive must not start in the 1st column, but may appear in any subsequent column. The operand may consist of one of the following: a) An asterisk (the assembler substitutes in the current value of the location cou nter. b) A symbolic name (the assemble substitutes in the value during the second pass of the assembly. c) A num eric constant. Octal contants must be preceeded by a '%'; hexadecimal consta nts are p receede d by a '$'; anyth ing els e is treated as a de cim al. d) An expression consisting of one or more of the above, separated by the operators: +, -, @ (for multiplication), or / (for division). Unary plus or minus is also allowed. Exam ples: *+2 Location counter plus 2. LABEL +% 10/2 LABEL plus octal number 10 divided by decimal number 2. -5 Negative decimal 5.
Assembler Directives
The following directives are supported: ORG EQU DS CADR Set the location counter to the operand following ORG. Set the label to the operand value. Define a word of storage; set the value to the operand value. Define a word of storage; set the value to the operand value (assumed to be a 14-b it address; this is an alias for CAD R). Define a word of storage; set the value to the operand value (operand is treated as a 12-bit ad dress). Inline include a file; the operand contains the filenam e.
ADRES
INCL
Addressing
The location counter and symbol table always contain the full 14-bit address. AGC instructions require a 12-bit address as an operand. Addressing is implemented in 1K banks (bits 10 throu gh 1). B its 12 and 11 select banks 0 (era sab le m em ory), 1 (fixed -fixed ), or 2 (fixed-fixed). These banks are directly addressable in 12-bits. Banks above 2 are called 'fixed-switchable' and are addressed using the BANK register: bits 12 and 11 of the operand are set to '1' and the bank register provides the high-order 4 bits (bits 14 through 11) of the address. The lower 10 bits of the operand provide the address within the bank.
Errata
a) The assembler ignores the last line of the source (.asm) file. If the last line of your source file contains code, you must add an additional blank line to the end of your source file to ensure that your last line of code is assembled. The symbol table could be sorted before the second pass. The linear search through the sym bol table could be replaced by a mo re efficient m ethod. (Bu t, assembly is so fast, it doesnt m atter). The assembler directives and syntax don't match those of the original block I AGC. A macro definition capability might be handy. Gen erates em pty .lst an d .obj files if the so urce cod e file does n ot exist. Incorrectly a ssign s a zero va lue to la bels th at equ ate to a forw ard referen ced lab el. i.e.: LABEL1 EQU LABEL2 ; assem bler in correc tly sets LA BEL 1 to z ero LABEL2 EQU *
b)
c) d) e) f)
Assembler listing
The assembler produces a list file (.lst) that shows the assembled source code. The format of the file w as des igne d to m im ic (som ewh at) the forma t of the origin al assem bler. You will find a fragment of the original assembler listing reproduced in part 8.
Object code
The object code is output to text files in Motorola S-Record format (S2F) suitable for im m edia te us e by EPR OM prog ram m ers, an d also rea dable b y the C+ + sim ula tor. There s lots of docum enta tion on S-R ecord form ats on the inte rnet. The files are pretty big. If you open one up, youll discover they contain many short records that look like these:
This is a fragment of the source code for the lower 8 bits of the TECO1 test and checkout program (described in pa rt 9). The assembler contains C++ code for generating these files; the C++ simu lator has code for rea din g th em .
Assembler v1.6
/* **************************************************************** * * Cross Assembler for Block I Apollo Guidance Computer (AGC4) * THIS VERSION IS MODIFIED TO OUTPUT IN S-RECORD FORMAT SUITABLE FOR * LOADING IN EPROM (s2f format). * Author: John Pultorak * 6/1/2002 * ***************************************************************** Versions: 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.6 First version of the AGC assembler. Added ability to handle simple arithmetic expressions for the operand. Changed label fields to 14 char. Printed symbol table in 3 columns. Corrected wrong implementation of OVSK. Added support for bank addressing. Added capability to inline code with nested includes. Added CADR, ADRES assembler directives. Swapped addresses for TIME1 and TIME2 for compatibility with Block II PINBALL routines. Fixed the parser so it doesn't mangle comments anymore. Added FCADR and ECADR to the assembler directives. Added a check for assembled code that overwrites already used locations. EPROM Assembler outputs to low and high EPROM files.
Operation: The assembler reads an AGC source code file (having a .asm extension). It generates an assembly listing text file (.lst extension) and an object code text file (.obj extension). The object code file is readable by the AGC simulator. Syntax: Source code files are text files containing multiple lines of source code. Each line is terminated by a newline character. Source code files can be produced by any editor, as long as it doesn't insert any hidden characters or formatting information. Each line a) b) c) of assembly code consists of one of the following: a blank line; a comment (comments must begin with a semicolon (;)); or a line of assembler code.
The assembler ignores blank lines and anything that occurs after a semicolon on any given line. A line of 1) 2) 3) 4) assembler code consists of the following components: a label (this is optional); an op code or assembler directive; an operand (also optional); a comment (optional; comments must start with a semicolon)
The components, if present, must appear in the order given. Each component is separated from the next by one or more white spaces or tabs. The only constraint is that the label, if present, must start in the 1st column of the line. If no label is present, the op code or assembler directive must not start in the 1st column, but may appear in any subsequent column. The operand may consist of one of the following: a) an asterisk (the assembler substitutes in the current value of the location counter; b) a symbolic name (the assemble substitutes in the value during the second pass of the assembly; c) a numeric constant. Octal contants must be preceeded by a '%'; hexadecimal constants are preceeded by a '$'; anything else is treated as a decimal. d) an expression consisting of one or more of the above, separated by the operators: +, -, @ (for multiplication), or / (for division). Unary plus or minus is also allowed. examples: *+2 means location counter plus 2 LABEL+%10/2 -5
Assembler Directives: The following directives are supported: ORG - set the location counter to the operand following ORG. EQU - set the label to the operand value. DS - define a word of storage; set the value to the operand value. CADR - define a word of storage; set the value to the operand value (assumed to be a 14-bit address; this is an alias for CADR). ADRES - define a word of storage; set the value to the operand value (operand is treated as a 12-bit address). INCL - inline include a file; the operand contains the filename. Addressing: The location counter and symbol table always contain the full 14-bit address. AGC instructions require a 12-bit address as an operand. Addressing is implemented in 1K banks (bits 10 through 1). Bits 12 and 11 select banks 0 (erasable memory), 1 (fixed-fixed), or 2 (fixed-fixed). These banks are directly addressable in 12-bits. Banks above 2 are called 'fixed-switchable' and are addressed using the BANK register: bits 12 and 11 of the operand are set to '1' and the bank register provides the high-order 4 bits (bits 14 through 11) of the address. The lower 10 bits of the operand provide the address within the bank. Errata: The assembler ignores the last line of the source (.asm) file. If the last line of your source file contains code, you must add an additional blank line to the end of your source file to ensure that your last line of code is assembled. The symbol table should be sorted before the second pass. The linear search through the symbol table should be replaced by a more efficient method. The assembler directives and syntax don't match those of the original block I AGC. A macro definition capability would be handy. Generates empty .lst and .obj files if the source code file does not exist. Incorrectly assigns a zero value to labels that equate to a forward referenced label. i.e.: LABEL1 EQU LABEL2 ; assembler incorrectly sets LABEL1 to zero LABEL2 EQU * The assembler generates object code for eraseable memory addresses. */ #include #include #include #include #include <string.h> <stdlib.h> <ctype.h> <iostream.h> <stdio.h>
// Create a flag for each memory location in a 14-bit address space // These are initialized to false, and then set as the code is assembled. // An attempt to assemble code on top of a previously used location is // flagged as an error. const unsigned agcMemSize = 037777+1; // # of cells in a 14-bit address range bool memoryUsed [agcMemSize]; //*********************************************************************** // MODIFIED FROM THE ORIGINAL ASSEMBLER HERE. // This array represents the fixed memory PROM (14-bit address) int EPROM_H [agcMemSize]; int EPROM_L [agcMemSize]; //*********************************************************************** unsigned pass = 0; unsigned locCntr = 0; // address in 14-bit format unsigned errorCount = 0; FILE* fpList = 0; // output (assembly listing)
//*********************************************************************** // MODIFIED FROM THE ORIGINAL ASSEMBLER HERE. FILE* fpObj_H = 0; // output MSB's (object code in S-RECORD format) FILE* fpObj_L = 0; // output LSB's (object code in S-RECORD format) //*********************************************************************** struct ocode { char* name; unsigned code; bool isOpCode; // true=it is an op code bool addrOpnd; // true=convert operand to 12-bit address format unsigned len; // words }; ocode allcodes[] = { // Block I op codes. { "TC", 0000000, true, { "CCS", 0010000, true, { "INDEX", 0020000, true, { "XCH", 0030000, true, { "CS", 0040000, true, { "TS", 0050000, true, { "AD", 0060000, true, { "MASK", 0070000, true, { "MP", 0040000, true, { "DV", 0050000, true, { "SU", 0060000, true, { { { { { { { { { { { {
true, true, true, true, true, true, true, true, true, true, true,
1 1 1 1 1 1 1 1 1 1 1
// Implied address codes (R393: 3-12) "RESUME", 0020025, true, false, 1 }, // "EXTEND", 0025777, true, false, 1 }, // "INHINT", 0020017, true, false, 1 }, // "RELINT", 0020016, true, false, 1 }, // "XAQ", 0000000, true, false, 1 }, // "RETURN", 0000001, true, false, 1 }, // "NOOP", 0030000, true, false, 1 }, // "COM", 0040000, true, false, 1 }, // "TCAA", 0050002, true, false, 1 }, // "OVSK", 0050000, true, false, 1 }, // "DOUBLE", 0060000, true, false, 1 }, // "SQUARE", 0040000, true, false, 1 }, // "clarity" (R393: 3-12) 0000000, true, true, 1 }, 0030000, true, true, 1 }, 0050000, true, true, 1 }, 1 }, 1 }, 1 }, 1 }, 1 }, 0 }, 0 }, 0 }, 99 } // // // // // // // // //
// same as TC; subroutine call with return // same as XCH; address to fixed acts like // same as TS define storage; reserves 1 word of memory define 14-bit addr; reserves 1 word of memory define 14-bit addr; reserves 1 word of memory define 14-bit addr; reserves 1 word of memory define 12-bit addr; reserves 1 word of memory origin; sets location counter to operand value equate; assigns a value to a label include; inline include source code end-of-list flag
// Assembler directives "DS", 0, false, false, "CADR", 0, false, false, "FCADR", 0, false, false, "ECADR", 0, false, false, "ADRES", 0, false, true, "ORG", 0, false, false, "EQU", 0, false, false, "INCL", 0, false, false, "", 0, false, false,
void parse(char* buf, char* labl, char* opcd, char* opnd, char* cmnt) { // strip off newline char. buf[strlen(buf) - 1] = '\0'; // replace any horizontal tabs with spaces for(unsigned i=0; i<strlen(buf); i++) { if(buf[i] == ';') break; // don't edit comments if(buf[i] == '\t') buf[i] = ' '; } strcpy(labl,"");
strcpy(opcd,""); strcpy(opnd,""); strcpy(cmnt,""); char* sp = buf; char* s = 0; enum {_labl=0, _opcd, _opnd, _cmnt } mode = _labl; if(buf[0] == ' ') mode = _opcd; do { s = strtok(sp, " "); sp = 0; if(s) { if(s[0] == ';') { // Copy the remainder of the comment verbatim. strcat(cmnt, s); strcat(cmnt, " "); s += strlen(s) + 1; strcat(cmnt, s); return; } switch(mode) { case _labl: strcat(labl, s); mode = _opcd; break; case _opcd: strcat(opcd, s); mode = _opnd; break; case _opnd: strcat(opnd, s); mode = _cmnt; break; } } } while(s); } struct symbl { char name[20]; unsigned val; }; symbl symTab[5000]; unsigned nSym = 0; // Pre-defined symbols corresponding to architectural // conventions in the block I AGC4. symbl constSymTab[] = { { "A", 00 }, { "Q", 01 }, { "Z", 02 }, { "LP", 03 }, { "IN0", 04 }, { "IN1", 05 }, { "IN2", 06 }, { "IN3", 07 }, { "OUT0", 010 }, { "OUT1", 011 }, { "OUT2", 012 }, { "OUT3", 013 }, { "OUT4", 014 }, { "BANK", 015 }, { "CYR", 020 }, { "SR", 021 }, { "CYL", 022 }, { "SL", 023 }, { "ZRUPT", 024 }, { "BRUPT", 025 }, { "ARUPT", 026 }, { "QRUPT", 027 }, { "OVCTR", 034 }, { "TIME2", 035 }, { "TIME1", 036 }, { "TIME3", 037 }, { "TIME4", 040 }, { "GOPROG", 02000 },
{ { { { { { { { { { { { { { { { { { { { };
"T3RUPT", "ERRUPT", "DSRUPT", "KEYRUPT", "UPRUPT", "EXTENDER", "BANK0", "BANK1", "BANK2", "BANK3", "BANK4", "BANK5", "BANK6", "BANK7", "BANK10", "BANK11", "BANK12", "BANK13", "BANK14", "",
02004 02010 02014 02020 02024 05777 000057 002000 004000 006000 010000 012000 014000 016000 020000 022000 024000 026000 030000 0
}, }, }, }, }, }, }, }, }, }, }, }, }, }, }, }, }, }, }, }
// // // //
erasable memory, just above the counter assignments fixed-fixed fixed-fixed start of fixed-switchable
void add(char* labl, unsigned value) { // Check whether symbol is already defined. unsigned i; for(i=0; i<nSym; i++) { if(strcmp(symTab[i].name, labl)==0) { fprintf(fpList,"*** ERROR: %s redefined.\n", symTab[i].name); errorCount++; return; } } // Add new symbol to symbol table strcpy(symTab[nSym].name, labl); symTab[nSym].val = value; nSym++; } // Return the int value of the operand string. The string is // assumed to be a simple value (not an expression) int _getopnd(char* opnd) { if(strlen(opnd)==0) return 0; else if(opnd[0] == '$') // hex number return strtol(opnd+1, 0, 16); else if(opnd[0] == '%') // octal number return strtol(opnd+1, 0, 8); else if(isdigit(opnd[0])) // decimal number return strtol(opnd, 0, 10); else if(opnd[0] == '*') return locCntr; else // must be label; look up value { unsigned i; for(i=0; i<nSym; i++) { if(strcmp(symTab[i].name, opnd)==0) return symTab[i].val; } // Not there, so check whether symbol is an // assembler-defined constant. If so, copy it to // the user-defined symbols. for(i=0; strcmp(constSymTab[i].name,"") != 0; i++) { if(strcmp(constSymTab[i].name, opnd)==0) { strcpy(symTab[nSym].name, opnd); symTab[nSym].val = constSymTab[i].val; nSym++;
return constSymTab[i].val; } } if(pass == 1) { fprintf(fpList,"*** ERROR: %s undefined.\n", opnd); errorCount++; } } return 0; } // returns pointer to new position in istr char* getToken(char* istr, char* ostr) { *ostr = '\0'; // bump past any whitespace while(*istr == ' ') istr++; if(*istr == '\0') return istr; bool keepGoing = true; do { *ostr = *istr; if(*ostr == '+' || *ostr == '-' || *ostr == '@' || *ostr == '/') keepGoing = false; ostr++; istr++; } while(keepGoing && *istr != '\0' && *istr != '+' && *istr != '-' && *istr != '@' && *istr != '/'); *ostr = '\0'; return istr; } int _eval(char* sp, int tot) { if(*sp == '\0') return tot; char op[20]; sp = getToken(sp, op); char vstr[20]; int val = 0; sp = getToken(sp,vstr); if(*vstr =='-') // unary minus { sp = getToken(sp, vstr); val = -(_getopnd(vstr)); } else val = _getopnd(vstr); switch(*op) { case '+': tot case '-': tot case '@': tot case '/': tot } } int eval(char* sp) { char op[20]; getToken(sp, op); char sp1[80]; if(*op != '+' && *op != '-') strcpy(sp1,"+"); else strcpy(sp1,"");
+= -= *= /=
return _eval(sp,tot);
strcat(sp1, sp); return _eval(sp1, 0); } // Return the value of the operand string. The string may // be a simple token or an expression consisting of multiple // tokens and operators. Evaluation occurs from left to right; // no parenthesis allowed. Unary minus is allowed and correctly // evaluated. Valid operators are +, -, @, and /. The @ operator // is multiplication (the traditional * operator already is used // to refer to the location counter. unsigned getopnd(char* opnd) { //return _getopnd(opnd); // the old call did not allow for expressions unsigned retval = 0; if(strcmp(opnd,"-0") == 0 || strcmp(opnd,"-%0") == 0 || strcmp(opnd,"-$0") == 0) retval = 077777; // -0 else { // return the int value of the operand int opndVal = eval(opnd); // now, convert the number into 16-bit signed AGC format if(opndVal < 0) { // convert negative values into AGC 16-bit 1's C form. opndVal = 077777 + opndVal; if(opndVal < 0) { fprintf(fpList,"*** ERROR: %s underflowed.\n", opnd); errorCount++; opndVal = 0; } } else if(opndVal > 077777) { fprintf(fpList,"*** ERROR: %s overflowed.\n", opnd); errorCount++; opndVal = 0; } retval = (unsigned) opndVal; } return retval; } bool isDefined(char* opcd) { for(int j=0; allcodes[j].len != 99; j++) { if(strcmp(allcodes[j].name, opcd) == 0) { return true; } } return false; } unsigned getopcode(char* opcd) { for(int j=0; allcodes[j].len != 99; j++) { if(strcmp(allcodes[j].name, opcd) == 0) { return allcodes[j].code; } } fprintf(fpList,"*** ERROR: %s undefined.\n", opcd); errorCount++; return 0; } bool has12bitAddr(char* opcd) { for(int j=0; allcodes[j].len != 99; j++)
{ if(strcmp(allcodes[j].name, opcd) == 0) { return allcodes[j].addrOpnd; } } return false; } bool isOpCode(char* opcd) { for(int j=0; allcodes[j].len != 99; j++) { if(strcmp(allcodes[j].name, opcd) == 0) { return allcodes[j].isOpCode; } } return false; } unsigned getoplen(char* opcd) { for(int j=0; allcodes[j].len != 99; j++) { if(strcmp(allcodes[j].name, opcd) == 0) { return allcodes[j].len; } } return 0; } void updateLocCntr(char* opcd, char* opnd) { unsigned size = 0; for(int i=0; allcodes[i].len != 99; i++) { if(strcmp(allcodes[i].name, opcd) == 0) { size = allcodes[i].len; break; } } locCntr += size; if(strcmp(opcd,"ORG") == 0) { locCntr = getopnd(opnd); } } unsigned genOddParity(unsigned r) { //check the lower 15 bits of 'r' and return the odd parity unsigned evenParity = (1&(r>>0)) ^ (1&(r>>1)) ^ (1&(r>>2)) ^ (1&(r>>3)) ^ (1&(r>>4)) ^ (1&(r>>5)) ^ (1&(r>>6)) ^ (1&(r>>7)) ^ (1&(r>>8)) ^ (1&(r>>9)) ^ (1&(r>>10)) ^ (1&(r>>11)) ^ (1&(r>>12)) ^ (1&(r>>13)) ^ (1&(r>>14)); return ~evenParity & 1; // odd parity } // Read the source file and build the symbol table. void readSourceForPass1(char* fn) { char buf[256]; char labl[100]; // label char opcd[100]; // op code char opnd[100]; // operand char cmnt[100]; // comment // Open the source code file. FILE* fp = fopen(fn, "r"); if(!fp) {
perror("fopen failed for source file"); return; } while(fgets(buf, 256, fp)) { parse(buf, labl, opcd, opnd, cmnt); if(strcmp(opcd,"INCL")==0) readSourceForPass1(opnd); if(strlen(labl)>0) { if(strcmp(opcd,"EQU")==0) add(labl, getopnd(opnd)); else add(labl, locCntr); } updateLocCntr(opcd, opnd); } fclose(fp); } // Read the source file and symbol table and build // the object code void readSourceForPass2(char* fn) { char buf[256]; char labl[100]; // label char opcd[100]; // op code char opnd[100]; // operand char cmnt[100]; // comment // Open the source code file. FILE* fp = fopen(fn, "r"); if(!fp) { perror("fopen failed for source file"); return; } while(fgets(buf,256,fp)) { parse(buf, labl, opcd, opnd, cmnt); if(strcmp(opcd,"INCL")==0) { // Include directive (INCL). fprintf(fpList, " %-14s %-8s %-14s %s\n", labl, opcd, opnd, cmnt); readSourceForPass2(opnd); } else if(strcmp(opcd,"")==0) { // Comment. fprintf(fpList, " %s\n", cmnt); } else if(getoplen(opcd) == 0) { // Must be ORG or EQU assembler directive. fprintf(fpList, " %-14s %-8s %-14s %s\n", labl, opcd, opnd, cmnt); if(!isDefined(opcd)) { fprintf(fpList,"*** ERROR: %s undefined.\n", opcd); errorCount++; } } else { // Since we got this far, we know the assembly line contains a // valid 'opcd' that reserves some storage space. It must be an // instruction or a DS. // Location counter (locCntr) contains 14-bit address; symbol table
// // // // // //
also stores 14-bit addresses. If the operand is an address above bank 3 (05777), it is not directly addressable and needs to be converted into a 12-bit bank address. In bank addressing, bits 12,11 are set and bits 10-1 contain the address inside the bank. (The programmer must set the bank register to select the correct bank.)
// Generate a string containing the address (for the list file). // If the address is erasable, or fixed-fixed, show the 12-bit // address. // If the address is fixed-switchable, show the bank number, // followed by the 10-bit bank address. unsigned locCntrBank = (036000 & locCntr) >> 10; char locCntrString[20]; if(locCntrBank <= 3) sprintf(locCntrString, " %04o", locCntr); else sprintf(locCntrString, "%2o,%04o", locCntrBank, 01777 & locCntr); // Generate the data to be stored at that address. Convert to // 12-bit address format, if necessary. unsigned operValue = getopnd(opnd); unsigned operBank = (036000 & operValue) >> 10; if(has12bitAddr(opcd)) { // Convert operand from a 14-bit address to a 12-bit // address. // First, find bank (bits 14-11). If the bank is <= 03, no // conversion is necessary. if(operBank > 03) { // Bank is not directly addressable, so get 10 bit // bank address and set fixed-switchable flag bits // 12 and 11. operValue = (01777 & operValue) | 06000; } } unsigned data = getopcode(opcd) + operValue; data |= genOddParity(data) << 15; // Generate a string containing the data info for the list file. char dataString[20]; if(isOpCode(opcd)) sprintf(dataString, "%01o %2o,%04o %1o", (getopcode(opcd) & 070000) >> 12, operBank, operValue, genOddParity(data)); else sprintf(dataString, " %05o %1o", operValue, genOddParity(data)); if(memoryUsed[locCntr]) { fprintf(fpList,"*** ERROR: %06o address already in use.\n", locCntr); errorCount++; } memoryUsed[locCntr] = true; fprintf(fpList, "%05o %7s %11s %-14s %-8s %-14s %s\n", locCntr, locCntrString, dataString, labl, opcd, opnd, cmnt); //*********************************************************************** // MODIFIED FROM THE ORIGINAL ASSEMBLER HERE. // Insert the assembled code into an array, indexed by the address. // This has the effect of sorting the data by address, so we can walk // through the addresses and output the code to EPROM later. unsigned dataLow = 0x00ff & data; unsigned dataHigh = (0xff00 & data) >> 8; if(locCntr >=1024) // FIXED MEMORY only; not ERASEABLE { // fixed memory EPROM_H [locCntr] = dataHigh; EPROM_L [locCntr] = dataLow;
} //*********************************************************************** } updateLocCntr(opcd, opnd); } fclose(fp); } //*********************************************************************** // MODIFIED FROM THE ORIGINAL ASSEMBLER HERE. void writeEPROM(FILE* fpObj, int EPROM[]) { // Write an EPROM file using Motorola's S-Record format (s2f). // // // const int const int const int Some parameters that control file format. You can change maxBytes without affecting anything else. 'addressBytes' is determined by the choosen S-Record format. maxBytes = 20; // set limit on record length addressBytes = 3; // 16-bit address range sumCheckBytes = 1;
const int maxdata = maxBytes - addressBytes - sumCheckBytes; int i=0; // current EPROM address int sumCheck = 0; while (i < agcMemSize) { // get dataByteCount; the number of bytes of EPROM data per record. int dataByteCount = maxdata; if(i + dataByteCount >= agcMemSize) { dataByteCount = agcMemSize - i; } // write record header (*** 2 byte address assumed ***) int totalByteCount = dataByteCount + addressBytes + sumCheckBytes; fprintf(fpObj, "S2%02X%06X", totalByteCount, i); sumCheck = totalByteCount & 0xff; sumCheck = (sumCheck + ((i & 0xff0000) >> 16)) % 256; sumCheck = (sumCheck + ((i & 0x00ff00) >> 8)) % 256; sumCheck = (sumCheck + ((i & 0x0000ff) )) % 256; // write data bytes into record for(int j=0; j<dataByteCount; j++) { fprintf(fpObj, "%02X", EPROM [i+j]); sumCheck = (sumCheck + EPROM [i+j]) % 256; } // terminate record by adding the checksum and a newline. fprintf(fpObj, "%02X\n", (~sumCheck) & 0xff); i += dataByteCount; } // write an end-of-file record here i=0; // set address zero for last record sumCheck = 0x04; // byte count sumCheck = (sumCheck + ((i & 0xff0000) >> 16)) % 256; sumCheck = (sumCheck + ((i & 0x00ff00) >> 8)) % 256; sumCheck = (sumCheck + ((i & 0x0000ff) )) % 256; fprintf(fpObj, "S804%06X%02X", i, (~sumCheck) & 0xff); } //*********************************************************************** void main(int argc, char* argv[]) { cout << "AGC Block I assembler" << endl; // // // // The assembler reads an assembly source code file with a .asm extension; i.e.: myProg.asm It writes an assembly listing text file with a .lst extension (myProg.lst) and an object code
// text file with a .obj extension (myProg.obj) #ifdef NOTDEF // use this to enter the source file using command line if(argc != 2) { cout << "*** ERROR: source file name not specified." << endl; exit(-1); } fp = fopen(argv[1], "r"); #endif char sourcefile[80]; cout << "Enter source file: "; cin >> sourcefile; // Valid source files have a .asm extension; strip the // extension off so we can use the prefix for the list // and object files. char prefix[80]; strcpy(prefix, sourcefile); char* p = prefix; while(*p != '\0') { p++; if(*p == '.') break; } if(strcmp(p,".asm") != 0) { cerr << "*** ERROR: Source file not *.asm" << endl; exit(-1); } *p = '\0'; // Open a text file for the assembly listing. The filename // will have a .lst extension. char listfile[80]; sprintf(listfile, "%s.lst", prefix); fpList = fopen(listfile, "w"); if(!fpList) { perror("fopen failed for assembly list file"); exit(-1); } //*********************************************************************** // MODIFIED FROM THE ORIGINAL ASSEMBLER HERE. // Open a two text files for the object code. The filenames // will have a .hex extension char objfile[80]; sprintf(objfile, "%s_H.hex", prefix); fpObj_H = fopen(objfile, "w"); if(!fpObj_H) { perror("fopen failed for object file"); exit(-1); } sprintf(objfile, "%s_L.hex", prefix); fpObj_L = fopen(objfile, "w"); if(!fpObj_L) { perror("fopen failed for object file"); exit(-1); } fprintf(fpList,"Block I Apollo Guidance Computer (AGC4) assembler version 1.6 for EPROM\n\n"); // INITIALIZE EPROM for(int k=0; k< agcMemSize; k++) { EPROM_H [k] = 0; EPROM_L [k] = 0; } //*********************************************************************** fprintf(fpList,"First pass: generate symbol table.\n");
readSourceForPass1(sourcefile); locCntr = 0; pass++; // Clear the memory use flags; these are used to catch // any overwriting of already assembled code. memset(memoryUsed, false, sizeof(bool) * agcMemSize); fprintf(fpList,"Second pass: generate object code.\n\n"); readSourceForPass2(sourcefile); //*********************************************************************** // MODIFIED FROM THE ORIGINAL ASSEMBLER HERE. // Write the EPROM data to file writeEPROM(fpObj_H, EPROM_H); writeEPROM(fpObj_L, EPROM_L); fclose(fpObj_H); fclose(fpObj_L); //*********************************************************************** fprintf(fpList,"\nAssembly complete. Errors = %d\n", errorCount); fprintf(fpList,"\nSymbol table:\n"); unsigned j=0; for(unsigned i=0; i<nSym; i++) { fprintf(fpList,"%-14s %06o ", symTab[i].name, symTab[i].val); j = (j+1) % 3; if(j==0) fprintf(fpList,"\n"); } fclose(fpList); }
Abstract
This report describes my successful project to build a working reproduction of the 1964 prototype for the Block I Apollo Guidance Computer. The AGC is the flight computer for the Ap ollo m oon lan din gs, and is the wo rlds first in tegra ted c ircuit com pu ter. I built it in my ba sem ent. It took me 4 yea rs. If you like, you can build one too. It will take you less time, and yours will be better than mine. I docum ented m y project in 9 separate .pdf files: Part 1 Part 2 Part 3 Part 4 Part 5 Part 6 Part 7 Part 8 O v ervie w : Introdu ces the p roject. CTL Module: Design and construction of the control module. PROC M odule: Design and construction of the processing (CPU) modu le. MEM Module: Design and construction of the mem ory module. IO Module: Design and construction of the display/keyboard (DSKY) m odule. Assem bler: A cross-a ssem bler for AG C softw are dev elopm ent. C+ + S imu lator: A low-level simulator that runs assemb led AGC code. Flight Software: My translation of portions of the COLOSSUS 249 flight software. Test & Che ckou t: A suite of test programs in AG C assembly langu age.
Part 9
Overview
This documen t describes my AG C Block I C++ sim ulator. I developed it almost entirely from detaile d inform ation in this d ocum ent: A. Hopk ins, R. Alonso, and H . Blair-Smith, "Logical Description for the Apollo Guidan ce Computer (AGC4)", R-393, MIT Instrumentation Laboratory, Cambridge, MA, Mar. 1963. My simulator reproduces not only the AGC instruction set and user-accessible registers, but all of the registers, all microinstructions, time-pulse generator states, read, write and me mo ry busses, and con trol pulses (logic signals) for all AGC subsystem s. The simulator is a tool I used to capture AGC design from the R-39 3 docum ent. When I got it working well enough to run my test and checkout software suite (described in part 9) and flight software (described in part 8), I knew I understood the AGC well enough to build one. The sim ulato r head er and source co de files be cam e requ irem ents th at gu ided my AG C log ic design (d escribed in parts 2-5 ).
The ne xt lin e (C P) sh ow s curre ntly asse rted c ontrol pu lses (l ogic signals). ST1 a nd WE are being asserted. The left side of the next 4 lines shows the state of registers associated with memory (S, G, P, P2, and C ADR ), the ALU (B , X, Y, U), and the read b us (RB U) and write bus (W BU). The right side of those 4 lines shows control inputs for running, stepping, and clocking the sim ula tor. The bottom part of the display shows AGC m emory. The 2-digit num bers on the left show mem ory addresses from 00-56 . Each mem ory location has a nam e; its shown to the right of the address. Immediately to the right of that is the contents of that location. Add resses 00 -17 a re m app ed to A GC registers, an d are n ot really p art of the A GC eraseab le memory. Addresses 00-03 are the AGC central registers, followed by input and output registers. Addresses 16 and 17 are not storage locations, but a means for enabling and disabling interrupts. The eraseab le mem ory starts at address 20. Add resses 20-23 a re the editing registers. Writing to these causes the data in the registers to be shifted or rotated. Add resses 24-27 a re used for saving the cen tral registers (00-03) wh en an in terrupt occurs. Add resses 34-56 a re priority counter locations. The AG C will increm ent or decrem ent these based on + pr - logic signa ls to the priority counter cells. The lower right of the simulator is the DSKY: the display/keyboard user interface for the astron auts. Th e sim ulato r is runn ing th e CO LOS SU S 24 9 fligh t softwa re load, a nd is curren tly execu ting m ajor m ode 0 (P00 ), verb 16 , noun 36, w hich is a m onitor p rogram to continuously display the command module elapsed time clock. The clock, displayed in R1, R2, and R3, shows 0 hours, 1 minute, and 54.23 seconds. It updates about once a second but, of course, you cant see that here.
Compiler
The simulator was compiled with Microsoft Visual C++ 6.0 Standard Edition.
Commands
Heres the comp lete list of com ma nds the sim ulator know s. The keyboa rd key you h it is: {Q}, and the name of the command is: <QUIT>.
Simulator commands
{q} {l} <QUIT> <LOAD> Exits the sim ula tor. The comm and is a lower case L, not a 1". Load fixed m em ory w ith objec t cod e pro du ced by th e ass em bler. The object code files are in Motorola S-Record format (compatible with EPROM programmers). The command will ask for a filenam e. Intended to be a useful menu of simulator command, but I ne ver got a roun d to it.
{m}
<MENU>
{h}
<RESET>
Clock controls
{F1} {F2} <CLK> <MCLK> Single-step the AGC clock. Only works when MCLK <F2> has been selected. Asserts the MCLK control signal. Disables the freerunning 1MHz clock. When MCLK is selected, you can single-step the clock by by pressing <F1>. Asserts the FCLK control signal. Causes the simu lator clock to free-run at 1MHz. This is the normal operational mod e.
{F4}
<FCLK>
{s} {n}
<STEP> <INST>
Debugger commands
{e} <EXAM INE> Examines the contents of memory. The comman d asks for a sta rting add ress a nd then disp lays the m em ory data at that ad dress and follow ing locations. Halts the AGC wh en any instruction changes a watched m em ory lo catio n. Th e com m and as ks for a m em ory address (CADR) to watch. Toggles a breakpoint on/off. When the breakpoint is on, it halts the AGC when instruction execution hits that address. Displays or refreshes the standard AGC register display. Displays the currently executing AGC source code. You can single step with this display and watch the AGC move through the source code. Very useful for debugging. A > arrow shows the next instruction to be executed in the listing.
{y}
<WATCH>
{b}
<BREAK POINT>
{d} {f}
<DISPLAY> <DEBUG>
Scaler controls
{z} <F17> Manu ally generates the <F17 > scaler pulse. Useful for testing when the scaler has been toggled to off <C>, or when youre single-stepping the AGC. Manu ally generates the <F13 > scaler pulse. Useful for testing when the scaler has been toggled to off <C>, or when youre single-stepping the AGC. Toggle the scaler on/off. When the scaler is off, the F13 and F17 signals are not automatically generated.
{x}
<F13>
{c}
<TOGGLE SCALER>
Interrupt controls
{i} <INTERRUPT> Generates an AGC interrupt. The comm and will ask you for an interrupt num ber (1-5).
DSKY controls
{/} {*} {-} {+} {.} {j} {g} <VERB> <NOUN> <MINUS> <PLUS> <CLEAR> <ENTER> <KEY R EL> The The The The The The The VERB key on the DSKY display. NOUN key on the DSKY display. MINUS key on the DSKY display. PLUS key on the DSKY display. CLEAR key on the DSKY display. ENTER key on the DSKY display. KEY RELEASE key on the DSKY display.
Simulator demonstration
Heres the sim ulato r, dem onstra ting so m e CO LOS SU S 24 9 fligh t softwa re functio ns. Th is is the same scenario I ran in Part 1 using my hardware AGC.
Initialization
At startup, the simulator loads the microinstructions from the EPROM tables. These are the sam e tables I eventually use d to program the hardw are AGC EPRO Ms. Reading Reading Reading Reading Reading Reading Reading EPR OM: EPR OM: EPR OM: EPR OM: EPR OM: EPR OM: EPR OM: CP M1_8 .hex CP M9_1 6.hex CP M17_ 24.hex CP M25_ 32.hex CP M33_ 40.hex CP M41_ 48.hex CP M49_ 56.hex
<LOAD> The simulator asks, and I enter the name of object files containing the COLOSSUS flight software.
<POWER UP RESET> <RUN> <FCLK> I tell the sim ula tor to start running, and enable the freerunn ing clo ck. The AG C starts running in real-time with the 1MHz clock. The DSK Y shows m ajor mo de 00 (P0 0).
<5> <0> <ENTER> Verb/no un disp lay flash continu es: waiting for data.
<1> <2> <3> <ENTER> Octal word from R1 is loaded at address 50.
Start a monitor program to continuously display elapsed time from the CM clock
<VERB> <1> < 6> <NOUN> <3> <6> <ENTER>
<NOUN> <0> <1> <ENTER> Verb/noun display flashes: waiting for address.
The 20 -or-so subsystems in the AGC are represented by C++ classes. There are some additional classes for registers and other things. I wanted a simulator architec ture I could develop quickly that wou ld easily and directly m ap to a hard wa re logic design. I went through 16 versions of the sim ula tor; th eyre discussed at the top of the A GC Ma in.cpp file wh ich contains, unsurprisingly, the ma in(). If you want to run the simulator, you can compile it from the source code given here. To run it, youll also need the assembler (discussed in part 6), some AGC software (parts 8 and 9), and the EPROM tables in Motorola S-Record format. The C++ code to generate these tables is given at the end of part 2. Here it is, warts a nd all...
Main (AGCMain.cpp)
/**************************************************************************** * AGC4 (Apollo Guidance Computer) BLOCK I Simulator * * AUTHOR: John Pultorak * DATE: 07/29/02 * FILE: AGCmain.cpp * * VERSIONS: * 1.0 - initial version. * 1.1 - fixed minor bugs; passed automated test and checkout programs: * teco1.asm, teco2.asm, and teco3.asm to test basic instructions, * extended instructions, and editing registers. * 1.2 - decomposed architecture into subsystems; fixed minor bug in DSKY * keyboard logic (not tested in current teco*.asm suite). * Implemented scaler pulses F17, F13, F10. Tied scaler output to * involuntary counters and interrupts. Implemented counter overflow * logic and tied it to interrupts and other counters. Added simple * set/clear breakpoint. Fixed a bug in bank addressing. * 1.3 - fixed bugs in the DSKY. Added 14-bit effective address (CADR) to the * simulator display output. Inhibited interrupts when the operator * single-steps the AGC. * 1.4 - performance enhancements. Recoded the control pulse execution code * for better simulator performance. Also changed the main loop so it * polls the keyboard and system clock less often for better performance. * 1.5 - reversed the addresses of TIME1 and TIME2 so TIME2 occurs first. * This is the way its done in Block II so that a common routine (READLO) * can be used to read the double word for AGC time. * 1.6 - added indicators for 'CHECK FAIL' and 'KEY RELS'. Mapped them to OUT1, * bits 5 and 7. Added a function to display the current location in * the source code list file using the current CADR. * 1.7 - increased length of 'examine' function display. Any changes in DSKY now * force the simulator to update the display immediately. Added a 'watch' * function that looks for changes in a memory location and halts the * AGC. Added the 'UPTL', 'COMP', and "PROG ALM" lights to the DSKY. * 1.8 - started reorganizing the simulator in preparation for H/W logic design. * Eliminated slow (1Hz) clock capability. Removed BUS REQUEST feature. * Eliminated SWRST switch. * 1.9 - eliminated the inclusive 'OR' of the output for all registers onto the * R/W bus. The real AGC OR'ed all register output onto the bus; normally * only one register was enabled at a time, but for some functions several * were simultaneously enabled to take advantage of the 'OR' function (i.e.: * for the MASK instruction). The updated logic will use tristate outputs * to the bus except for the few places where the 'OR' function is actually * needed. Moved the parity bit out of the G register into a 1-bit G15 * register. This was done for convenience because the parity bit in G * is set independently from the rest of the register. * 1.10 - moved the G15 parity register from MBF to the PAR subsystem. Merged SBFWG * and SBEWG pulses into a single SBWG pulse. Deleted the CLG pulse for MBF * (not needed). Separated the ALU read pulses from all others so they can * be executed last to implement the ALU inclusive OR functions. Implemented * separate read and write busses, linked through the ALU. Implemented test * parity (TP) signal in PAR; added parity alarm (PALM) FF to latch PARITY * ALARM indicator in PAR. * 1.11 - consolidated address testing signals and moved them to ADR. Moved memory * read/write functions from MBF to MEM. Merged EMM and FMM subsystems into * MEM. Fixed a bad logic bug in writeMemory() that was causing the load of * the fixed memory to overwrite array boundaries and clobber the CPM table. * Added a memory bus (MEM_DATA_BUS, MEM_PARITY_BUS). * 1.12 - reduced the number of involuntary counters (CTR) from 20 to 8. Eliminated * the SHINC subsequence. Changed the (CTR) sequence and priority registers into * a single synchronization register clocked by WPCTR. Eliminated the fifth * interrupt (UPRUPT; INT). Eliminated (OUT) the signal to read from output * register 0 (the DSKY register), since it was not used and did not provide * any useful function, anyway. Deleted register OUT0 (OUT) which shadowed * the addressed DSKY register and did not provide any useful function. * Eliminated the unused logic that sets the parity bit in OUT2 for downlink * telemetry. * 1.13 - reorganized the CPM control pulses into CPM-A, CPM-B, and CPM-C groups. * Added the SDV1, SMP1, and SRSM3 control pulses to CPM-A to indicate when * those subsequences are active; these signals are input to CPM-C. Moved the * ISD function into CPM-A. Fixed a minor bug causing subsequence RSM3 to be * displayed as RSM0. Added GENRST to clear most registers during STBY. * 1.14 - Moved CLISQ to TP1 to fix a problem in the hardware AGC. CLISQ was clearing
* SNI on CLK2 at TP12, but the TPG was advancing on CLK1 which occurs after * CLK2, so the TPG state machine was not seeing SNI and was not moving to * the correct state. In this software simulation, everything advances on * the same pulse, so it wasn't a problem to clear SNI on TP12. Added a * switch to enable/disable the scaler. * 1.15 - Reenabled interrupts during stepping (by removing MON::RUN) signals from * CPM-A and CPM-C logic). Interrupts can be prevented by disabling the scaler. * Fixed a problem with INHINT1; it is supposed to prevent an interrupt * between instructions if there's an overflow. It was supposed to be cleared * on TP12 after SNI (after a new instruction), but was being cleared on TP12 * after every subsequence. * 1.16 - Changed CPM-A to load and use EPROM tables for the control pulse matrix. The * EPROM tables are negative logic (0=asserted), but this simulator expects * positive logic, so each word is bit-flipped when the EPROM tables load * during simulator initialization. * SOURCES: * Mostly based on information from "Logical Description for the Apollo Guidance * Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh Blair-Smith, R-393, * MIT Instrumentation Laboratory, 1963. * * PORTABILITY: * Compiled with Microsoft Visual C++ 6.0 standard edition. Should be fairly * portable, except for some Microsoft-specific I/O and timer calls in this file. * * NOTE: set tabs to 4 spaces to keep columns formatted correctly. * ***************************************************************************** */ #include <conio.h> #include #include #include #include #include #include #include #include <iostream.h> <stdio.h> <stdlib.h> <string.h> <conio.h> <stdio.h> <time.h> <ctype.h>
#include "reg.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "TPG.h" "MON.h" "SCL.h" "SEQ.h" "INP.h" "OUT.h" "BUS.h" "DSP.h" "ADR.h" "PAR.h" "MBF.h" "MEM.h" "CTR.h" "INT.h" "KBD.h" "CRG.h" "ALU.h" "CPM.h" "ISD.h" "CLK.h"
extern bool dskyChanged; //----------------------------------------------------------------------// CONTROL LOGIC void genAGCStates() { // 1) Decode the current instruction subsequence (glbl_subseq). // SEQ::glbl_subseq = CPM::instructionSubsequenceDecoder(); // 2) Build a list of control pulses for this state. CPM::controlPulseMatrix();
// // // // // // // // //
3) Execute the control pulses for this state. In the real AGC, these occur simultaneously. Since we can't achieve that here, we break it down into the following steps: Most operations involve data transfers--usually reading data from a register onto a bus and then writing that data into another register. To approximate this, we first iterate through all registers to perform the 'read' operation--this transfers data from register to bus. Then we again iterate through the registers to do 'write' operations, which move data from the bus back into the register. = 0; = 0; = 0; // // // // clear bus; necessary because words are logical OR'ed onto the bus. clear data lines: memory bits 15-1 parity line: memory bit 16
// Now start executing the pulses: // First, read register outputs onto the bus or anywhere else. int i; for(i=0; i<MAXPULSES && SEQ::glbl_cp[i] != NO_PULSE; i++) { CLK::doexecR(SEQ::glbl_cp[i]); } // Next, execute ALU read pulses. See comments in ALU .C file ALU::glbl_BUS = 0; for(i=0; i<MAXPULSES && SEQ::glbl_cp[i] != NO_PULSE; i++) { CLK::doexecR_ALU(SEQ::glbl_cp[i]); } BUS::glbl_WRITE_BUS = BUS::glbl_READ_BUS; // in case nothing is logically OR'ed below; for(i=0; i<MAXPULSES && SEQ::glbl_cp[i] != NO_PULSE; i++) { CLK::doexecR_ALU_OR(SEQ::glbl_cp[i]); } // Now, write the bus and any other signals into the register inputs. for(i=0; i<MAXPULSES && SEQ::glbl_cp[i] != NO_PULSE; i++) { CLK::doexecW(SEQ::glbl_cp[i]); } // Always execute these pulses. SCL::doexecWP_SCL(); SCL::doexecWP_F17(); SCL::doexecWP_F13(); SCL::doexecWP_F10(); TPG::doexecWP_TPG(); } //----------------------------------------------------------------------// SIMULATION LOGIC // contains prefix for source filename; i.e.: the portion // of the filename before .obj or .lst char filename[80]; char* getCommand(char* prompt) { static char s[80]; char* sp = s; cout << prompt; cout.flush(); char key; while((key = _getch()) != 13) { if(isprint(key)) { cout << key; cout.flush(); *sp = key; sp++; }
else if(key == 8 && sp != s) { cout << key << " " << key; cout.flush(); sp--; } } *sp = '\0'; return s; } bool breakpointEnab = false; unsigned breakpoint = 0; void toggleBreakpoint() { if(!breakpointEnab) { char b[80]; strcpy(b, getCommand("Set breakpoint: -- enter 14-bit CADR (octal): ")); cout << endl; breakpoint = strtol(b,0,8); breakpointEnab = true; } else { cout << "Clearing breakpoint." << endl; breakpointEnab = false; } } bool watchEnab = false; unsigned watchAddr = 0; unsigned oldWatchValue = 0; void toggleWatch() { if(!watchEnab) { char b[80]; strcpy(b, getCommand("Set watch: -- enter 14-bit CADR (octal): ")); cout << endl; watchAddr = strtol(b,0,8); watchEnab = true; oldWatchValue = MEM::readMemory(watchAddr); char buf[100]; sprintf(buf, "%06o: %06o", watchAddr, oldWatchValue); cout << buf << endl; } else { cout << "Clearing watch." << endl; watchEnab = false; } } void incrCntr() { char cntrname[80]; strcpy(cntrname, getCommand("Increment counter: -- enter pcell (0-19): ")); cout << endl; int pc = atoi(cntrname); CTR::pcUp[pc] = 1; } void decrCntr() { char cntrname[80]; strcpy(cntrname, getCommand("Decrement counter: -- enter pcell (0-19): ")); cout << endl; int pc = atoi(cntrname); CTR::pcDn[pc] = 1; }
void interrupt() { char iname[80]; strcpy(iname, getCommand("Interrupt: -- enter priority (1-5): ")); cout << endl; int i = atoi(iname) - 1; INT::rupt[i] = 1; }
#ifdef NOTDEF // Load AGC memory from the specified file object file void loadMemory() { strcpy(filename, getCommand("Load Memory -- enter filename: ")); cout << endl; // Add the .obj extension. char fname[80]; strcpy(fname, filename); strcat(fname, ".obj"); FILE* fp = fopen(fname, "r"); if(!fp) { perror("fopen failed:"); cout << "*** ERROR: Can't load memory for file: " << fname << endl; return; } unsigned addr; unsigned data; while(fscanf(fp, "%o %o", &addr, &data) != EOF) { MEM::writeMemory(addr, data); } fclose(fp); cout << "Memory loaded." << endl; } #endif static int loadBuf[0xffff+1]; // tempory buffer for assembling H,L memory data
void loadEPROM(char* fileName, bool highBytes) { cout << "Reading EPROM: " << fileName << endl; // Open the EPROM file. FILE* ifp = fopen(fileName, "r"); if(!ifp) { perror("fopen failed for source file"); exit(-1); } const int addressBytes = 3; // 24-bit address range const int sumCheckBytes = 1; char buf[4096]; // buffer holds a single S-Record while(fgets(buf,4096,ifp)) { // process a record if(buf[0] != 'S') { cout << "Error reading start of EPROM record for: " << fileName << endl; exit(-1); } char tmp[256]; strncpy(tmp, &buf[2], 2); tmp[2] = '\0'; int totalByteCount = strtol(tmp, 0, 16); int mySumCheck = totalByteCount & 0xff;
strncpy(tmp, &buf[4], 6); tmp[addressBytes*2] = '\0'; int address = strtol(tmp, 0, 16); mySumCheck = (mySumCheck + ((address & 0xff0000) >> 16)) % 256; mySumCheck = (mySumCheck + ((address & 0x00ff00) >> 8)) % 256; mySumCheck = (mySumCheck + ((address & 0x0000ff) )) % 256; //cout << hex << totalByteCount << ", " << address << dec << endl; int dataBytes = totalByteCount - addressBytes - sumCheckBytes; int i = (addressBytes+2)*2; // index to 1st databyte char. for(int j=0; j<dataBytes; j++) { // get a data byte strncpy(tmp, &buf[i], 2); tmp[2] = '\0'; int data = strtol(tmp, 0, 16); //cout << hex << data << dec << endl; mySumCheck = (mySumCheck + data) % 256; if(highBytes) { loadBuf[address] = loadBuf[address] | ((data << 8) & 0xff00); } else { loadBuf[address] = loadBuf[address] | (data & 0xff); } address++; i+=2; // bump to next databyte char } strncpy(tmp, &buf[i], 2); tmp[2] = '\0'; int sumCheck = strtol(tmp, 0, 16); if(sumCheck != ((~mySumCheck) & 0xff)) { cout << "sumCheck failed; file: " << fileName << ", address: " << hex << address << ", sumCheck: " << sumCheck << ", mySumCheck: " << mySumCheck << dec << endl; exit(-1); } } fclose(ifp); cout << "Memory loaded." << endl; } // Load AGC memory from the specified EPROM files void loadMemory() { strcpy(filename, getCommand("Load Memory -- enter filename: ")); cout << endl; char fname[80]; // Add the _H.hex extension. strcpy(fname, filename); strcat(fname, "_H.hex"); loadEPROM(fname, true); // Add the _L.hex extension. strcpy(fname, filename); strcat(fname, "_L.hex"); loadEPROM(fname, false); //******************************************************************* // EPROM is now in loadBuf; move it to AGC memory. // AGC fixed memory only uses NUMFBANK banks. for(int address=1024; address < 1024*(NUMFBANK+1); address++) { // Don't load address region 0-1023; that region is allocated
// to eraseable memory. //cout << "loading CADR=" << hex << address << endl; MEM::writeMemory(address, loadBuf[address]); } //******************************************************************* } // Write the entire contents of fixed and // eraseable memory to the specified file. // Does not write the registers void saveMemory(char* filename) { FILE* fp = fopen(filename, "w"); if(!fp) { perror("*** ERROR: fopen failed:"); exit(-1); } char buf[100]; for(unsigned addr=020; addr<=031777; addr++) { sprintf(buf, "%06o %06o\n", addr, MEM::readMemory(addr)); fputs(buf, fp); } fclose(fp); } void examineMemory() { char theAddress[20]; strcpy(theAddress, getCommand("Examine Memory -- enter address (octal): ")); cout << endl; unsigned address = strtol(theAddress, 0, 8); char buf[100]; for(unsigned i=address; i<address+23; i++) { sprintf(buf, "%06o: %06o", i, MEM::readMemory(i)); cout << buf << endl; } } // Returns true if time (s) elapsed since last time it returned true; does not block // search for "Time Management" bool checkElapsedTime(time_t s) { if(!s) return true; static clock_t start = clock(); clock_t finish = clock(); double duration = (double)(finish - start) / CLOCKS_PER_SEC; if(duration >= s) { start = finish; return true; } return false; } // Blocks until time (s) has elapsed. void delay(time_t s) { if(!s) return; clock_t start = clock(); clock_t finish = 0; double duration = 0; do { finish = clock(); } while((duration = (double)(finish - start) / CLOCKS_PER_SEC) < s);
} void updateAGCDisplay() { static bool displayTimeout = false; static int clockCounter = 0; if(checkElapsedTime(2)) displayTimeout = true; if(MON::FCLK) { if(MON::RUN) { // update every 2 seconds at the start of a new instruction if(displayTimeout || dskyChanged) { clockCounter++; if( (TPG::register_SG.read() == TP12 && SEQ::register_SNI.read() == 1) || (TPG::register_SG.read() == STBY) || clockCounter > 500 || dskyChanged) { MON::displayAGC(); displayTimeout = false; clockCounter = 0; dskyChanged = false; } } } else { static bool displayOnce = false; if(TPG::register_SG.read() == WAIT) { if(displayOnce == false) { MON::displayAGC(); displayOnce = true; clockCounter = 0; } } else { displayOnce = false; } } } else MON::displayAGC(); // When the clock is manual or slow, always update. } void showMenu() { cout << "AGC4 EMULATOR MENU:" << endl; cout << " 'r' = RUN: toggle RUN/HALT switch upward to the RUN position." << endl; } const int startCol const int colLen const int maxLines const int noffset = 0; = 5; = 23; = 10; // columns are numbered 0-n // number of chars in column // # of total lines to display // # of lines prior to, and including, selected line
const int maxLineLen = 79; void showSourceCode() { // Add the .lst extension. char fname[80]; strcpy(fname, filename); strcat(fname, ".lst"); // Open the file containing the source code listing. FILE* fp = fopen(fname, "r"); if(!fp)
{ perror("fopen failed:"); cout << "*** ERROR: Can't load source list file: " << fname << endl; return; } cout << endl; // Get the address of the source code line to display. // The address we want is the current effective address is the // S and bank registers. char CADR[colLen+1]; sprintf(CADR, "%05o", ADR::getEffectiveAddress()); int op = 0; // offset index long foffset[noffset]; for(int i=0; i<noffset; i++) foffset[i]=0; bool foundit = false; int lineCount = 0; char s[256]; char valString[20]; char out[256]; while(!feof(fp)) { if(!foundit) { foffset[op] = ftell(fp); op = (op + 1) % noffset; } // Read a line of the source code list file. if(fgets(s, 256, fp)) { // Get the address (CADR) from the line. strncpy(valString, s+startCol, colLen); valString[colLen]='\0'; // 'foundit' is true after we have found the desired line. if(foundit) { if(strcmp(valString,CADR) == 0) cout << ">"; else cout << " "; // truncate line so it fits in 80 col display strncpy(out, s, maxLineLen); out[maxLineLen] = '\0'; cout << out; lineCount++; if(lineCount >= maxLines) break; } else { if(strcmp(valString, CADR) == 0) { // Reposition the file pointer back several lines so // we can see the code that preceeds the desired // line, too. foundit = true; fseek(fp, foffset[op], 0); } } } } fclose(fp); }
CPM::readEPROM( "CPM1_8.hex", CPM::readEPROM( "CPM9_16.hex", CPM::readEPROM("CPM17_24.hex", CPM::readEPROM("CPM25_32.hex", CPM::readEPROM("CPM33_40.hex", CPM::readEPROM("CPM41_48.hex", CPM::readEPROM("CPM49_56.hex", bool singleClock = false; genAGCStates(); MON::displayAGC();
while(1) { // NOTE: assumes that the display is always pointing to the start of // a new line at the top of this loop! // Clock the AGC, but between clocks, poll the keyboard // for front-panel input by the user. This uses a Microsoft function; // substitute some other non-blocking function to access the keyboard // if you're porting this to a different platform. cout << "> "; cout.flush(); // display prompt while( !_kbhit() ) { if(MON::FCLK || singleClock) { // This is a performance enhancement. If the AGC is running, // don't check the keyboard or simulator display every // simulation cycle, because that slows the simulator // down too much. int genStateCntr = 100; do { CLK::clkAGC(); singleClock = false; genAGCStates(); genStateCntr--; // Needs more work. It doesn't always stop at the // right location and sometimes stops at the // instruction afterwards, too. if(breakpointEnab && breakpoint == ADR::getEffectiveAddress()) { MON::RUN = 0; } // Halt right after instr that changes a watched // memory location. if(watchEnab) { unsigned newWatchValue = MEM::readMemory(watchAddr); if(newWatchValue != oldWatchValue) { MON::RUN = 0; } oldWatchValue = newWatchValue; } } while (MON::FCLK && MON::RUN && genStateCntr > 0); updateAGCDisplay(); } // for convenience, clear the single step switch on TP1; in the // hardware AGC, this happens when the switch is released if(MON::STEP && TPG::register_SG.read() == TP1) MON::STEP = 0; } char key = _getch(); // Keyboard controls for front-panel: switch(key)
{ // AGC controls // simulator controls case 'q': cout << "QUIT..." << endl; exit(0); case 'm': showMenu(); break; case 'd': genAGCStates(); MON::displayAGC(); break; // update display case 'l': loadMemory(); break; case 'e': examineMemory(); break; case 'f': showSourceCode(); break; case ']': incrCntr(); //genAGCStates(); //displayAGC(EVERY_CYCLE); break; case '[': decrCntr(); //genAGCStates(); //displayAGC(EVERY_CYCLE); break; case 'i': interrupt(); //genAGCStates(); //displayAGC(EVERY_CYCLE); break; case 'z': //SCL::F17 = (SCL::F17 + 1) % 2; genAGCStates(); MON::displayAGC(); break; case 'x': //SCL::F13 = (SCL::F13 + 1) % 2; genAGCStates(); MON::displayAGC(); break; case 'c': MON::SCL_ENAB = (MON::SCL_ENAB + 1) % 2; genAGCStates(); MON::displayAGC(); break; case 'r': MON::RUN = (MON::RUN + 1) % 2; genAGCStates(); if(!MON::FCLK) MON::displayAGC(); break; case 's': MON::STEP = (MON::STEP + 1) % 2; genAGCStates(); if(!MON::FCLK) MON::displayAGC(); break; case 'a': MON::SA = (MON::SA + 1) % 2; genAGCStates(); MON::displayAGC(); break; case 'n': MON::INST = (MON::INST + 1) % 2; genAGCStates();
MON::displayAGC(); break; case 'p': MON::PURST = (MON::PURST + 1) % 2; genAGCStates(); MON::displayAGC(); break; case 'b': toggleBreakpoint(); break; case 'y': toggleWatch(); break; case ';': // Clear ALARM indicators PAR::CLR_PALM(); // Asynchronously clear PARITY FAIL MON::displayAGC(); break; // '0': '1': '2': '3': '4': '5': '6': '7': '8': '9': '+': '-': '.': '/': '*': 'g': 'h': 'j': DSKY: KBD::keypress(KEYIN_0); break; KBD::keypress(KEYIN_1); break; KBD::keypress(KEYIN_2); break; KBD::keypress(KEYIN_3); break; KBD::keypress(KEYIN_4); break; KBD::keypress(KEYIN_5); break; KBD::keypress(KEYIN_6); break; KBD::keypress(KEYIN_7); break; KBD::keypress(KEYIN_8); break; KBD::keypress(KEYIN_9); break; KBD::keypress(KEYIN_PLUS); break; KBD::keypress(KEYIN_MINUS); break; KBD::keypress(KEYIN_CLEAR); break; KBD::keypress(KEYIN_VERB); break; KBD::keypress(KEYIN_NOUN); break; KBD::keypress(KEYIN_KEY_RELEASE); break; KBD::keypress(KEYIN_ERROR_RESET); break; KBD::keypress(KEYIN_ENTER); break;
case case case case case case case case case case case case case case case case case case
case '\0': // must be a function key key = _getch(); switch(key) { case 0x3b: // F1: single clock pulse (when system clock off) singleClock = true; break; case 0x3c: // F2: manual clock (FCLK=0) MON::FCLK = 0; genAGCStates(); MON::displayAGC(); break; case 0x3e: // F4: fast clock (FCLK=1) MON::FCLK = 1; genAGCStates(); MON::displayAGC(); break; default: cout << "function key: " << key << "=" << hex << (int) key << dec << endl; } break; //default: cout << "??" << endl; default: cout << key << "=" << hex << (int) key << dec << endl; } } }
ADR (ADR.h)
/**************************************************************************** * ADR - MEMORY ADDRESS subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: ADR.h * * VERSIONS: * * DESCRIPTION: * Memory address for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef ADR_H #define ADR_H enum specialRegister { // octal addresses of special registers // Flip-Flop registers A_ADDR =00, Q_ADDR =01, Z_ADDR =02, LP_ADDR =03, IN0_ADDR =04, IN1_ADDR =05, IN2_ADDR =06, IN3_ADDR =07, OUT0_ADDR =010, OUT1_ADDR =011, OUT2_ADDR =012, OUT3_ADDR =013, OUT4_ADDR =014, BANK_ADDR =015, // No bits in these registers RELINT_ADDR =016, INHINT_ADDR =017, // In eraseable memory CYR_ADDR =020, SR_ADDR =021, CYL_ADDR =022, SL_ADDR =023, ZRUPT_ADDR =024, BRUPT_ADDR =025, ARUPT_ADDR =026, QRUPT_ADDR =027, };
class regS : public reg { public: regS() : reg(12, "%04o") { } }; class regBNK : public reg { public: regBNK() : reg(4, "%02o") { } }; class ADR
{ friend class MON; friend class MEM; friend class CLK; friend class CPM; public: static void execWP_WS(); static void execRP_RBK(); static void execWP_WBK(); static static static static static static bool bool bool bool bool bool GTR_17(); GTR_27(); EQU_16(); EQU_17(); EQU_25(); GTR_1777(); // // // // // // for for for for for for MBF, CPM PAR CPM CPM SEQ CPM
static unsigned getEffectiveAddress(); private: static regS register_S; // address register static regBNK register_BNK; // bank register static unsigned bankDecoder(); static unsigned conv_WBK[]; }; #endif
ADR (ADR.cpp)
/**************************************************************************** * ADR - MEMORY ADDRESS subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: ADR.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "reg.h" #include "ADR.h" #include "SEQ.h" #include "BUS.h" regS ADR::register_S; // address register regBNK ADR::register_BNK; // bank register // transfer bits 14-11 from the bus into the 4-bit bank register unsigned ADR::conv_WBK[] = { BX, BX, BX, BX, BX, BX, BX, BX, BX, BX, BX, BX, B14, B13, B12, B11 };
void ADR::execWP_WS() { register_S.write(BUS::glbl_WRITE_BUS); } void ADR::execRP_RBK() { BUS::glbl_READ_BUS = register_BNK.read() << 10; } void ADR::execWP_WBK() { register_BNK.writeShift(BUS::glbl_WRITE_BUS, ADR::conv_WBK); } bool ADR::GTR_27() { return (register_S.read() > 027); } bool ADR::GTR_17() { // check: address is not a central register return (register_S.read() > 017); } bool ADR::EQU_25() { return (register_S.read() == 025); } bool ADR::EQU_17() { // check: instruction is INHINT (INDEX 017) return (register_S.read() == 017); } bool ADR::EQU_16() { // check: instruction is RELINT (INDEX 016)) return (register_S.read() == 016); } bool ADR::GTR_1777() { // check: address is fixed memory
return (register_S.read() > 01777); } unsigned ADR::bankDecoder() { // Memory is organized into 13 banks of 1K words each. The banks are numbered // 0-12. Bank 0 is erasable memory; banks 1-12 are fixed (rope) memory. The 10 // lower bits in the S register address memory inside a bank. The 2 upper bits // in the S register select the bank. If the 2 upper bits are both 1, the 4-bit // bank register is used to select the bank. // 12 11 Bank // 0 0 0 erasable memory // 0 1 1 fixed-fixed 1 memory // 1 0 2 fixed-fixed 2 memory // 1 1 3-12 fixed-switchable memory (bank register selects bank) unsigned bank = ADR::register_S.readField(12,11); if(bank == 3) { // fixed-switchable if(register_BNK.read() <= 03) // defaults to 6000 - 7777 return 03; else return register_BNK.read(); // 10000 - 31777 } else return bank; // erasable or fixed-fixed } unsigned ADR::getEffectiveAddress() { // Return the 14-bit address selected by lower 10 bits of the S register (1K) // and the bank decoder (which selects the 1K bank) unsigned lowAddress = ADR::register_S.readField(10,1); if(ADR::bankDecoder() == 0) return lowAddress; unsigned highAddress = ADR::bankDecoder() << 10; return highAddress | lowAddress; }
ALU (ALU.h)
/**************************************************************************** * ALU - ARITHMETIC UNIT subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: ALU.h * * VERSIONS: * * DESCRIPTION: * Arithmetic Unit for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef ALU_H #define ALU_H #include "reg.h" class regB : public reg { public: regB() : reg(16, "%06o") { } }; class regCI : public reg { public: regCI() : reg(1, "%01o") { } }; class regX : public reg { public: regX() : reg(16, "%06o") { } }; class regY : public reg { public: regY() : reg(16, "%06o") { } }; class regU : public reg { public: regU() : reg(16, "%06o") { } virtual unsigned read(); }; class ALU { public: static unsigned glbl_BUS; // // // // // // // // // //
In the hardware AGC, all read pulses are enabled simultaneously by CLK1. This simulator has to do the pulses one-at-a-time, so they are executed in the following sequence to mimic the hardware: 1) all read pulses involving subsystems other than ALU are executed, These read pulses output to the glbl_READ_BUS. Only 0 or 1 of these pulses should be active at any time (never 2 or more), 2) next, the read pulses for the ALU are executed. The ALU is treated differently because it is the only subsystem where several read
// // // // // // // // // // // // // // // // // 3) finally,
pulses can be active simultaneously. In the original AGC, these pulses 'inclusive OR' their output to the glbl_READ_BUS, so the simulator has be implemented to execute all read pulses other than the ALU reads first, so the ALU will have the bus data it needs in order to do the inclusive OR. In the recreated AGC hardware design, the ALU is also the subsystem that links the glbl_READ_BUS to the glbl_WRITE_BUS. The recreated ALU hardware design checks whether anything is being written to the glbl_READ_BUS by the other subsystems. If not, it outputs zeroes to the glbl_READ_BUS for input to the inclusive OR operation. It then transfers data on the glbl_READ_BUS to the glbl_WRITE_BUS using an inclusive OR with data generated by other ALU read pulses. The AGC sequencer uses this operation to set certain data lines. all write pulses are executed.
static void execRP_ALU_RB(); static void execRP_ALU_RC(); static void execRP_ALU_RU(); static static static static static static static static void void void void void void void void execRP_ALU_OR_RB14(); execRP_ALU_OR_R1(); execRP_ALU_OR_R1C(); execRP_ALU_OR_R2(); execRP_ALU_OR_R22(); execRP_ALU_OR_R24(); execRP_ALU_OR_R2000(); execRP_ALU_OR_RSB();
static void execWP_GENRST(); static void execWP_WB(); static void execWP_CI(); static void execWP_WY(); static void execWP_WX(); static void execWP_WYx();
regB register_B; // next instruction regCI register_CI; // ALU carry-in flip flop regX register_X; // ALU X register regY register_Y; // ALU Y register regU register_U; // ALU sum
ALU (ALU.cpp)
/**************************************************************************** * ALU - ARITHMETIC UNIT subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: ALU.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "ALU.h" #include "SEQ.h" #include "BUS.h" regB ALU::register_B; // next instruction regCI ALU::register_CI; // ALU carry-in flip flop regX ALU::register_X; // ALU X register regY ALU::register_Y; // ALU Y register regU ALU::register_U; // ALU sum unsigned ALU::glbl_BUS = 0;
//************************************************************ void ALU::execRP_ALU_RB() { BUS::glbl_READ_BUS = register_B.read(); } // Performs an inclusive OR or register U and register C; // in the MASK instruction, the RC and RU control pulses // are activated simultaneously. This causes both to be // gated onto the AGC bus which performs the logical OR. void ALU::execRP_ALU_RC() { ALU::glbl_BUS |= register_B.outmask() & (~register_B.read()); BUS::glbl_READ_BUS = ALU::glbl_BUS; } // Performs an inclusive OR or register U and register C; // in the MASK instruction, the RC and RU control pulses // are activated simultaneously. This causes both to be // gated onto the AGC bus which performs the logical OR. void ALU::execRP_ALU_RU() { ALU::glbl_BUS |= register_U.read(); BUS::glbl_READ_BUS = ALU::glbl_BUS; } //************************************************************
//************************************************************ // This is the interface between the read and write busses void ALU::execRP_ALU_OR_RB14() { BUS::glbl_WRITE_BUS |= 0020000 | BUS::glbl_READ_BUS; } void ALU::execRP_ALU_OR_R1() {
BUS::glbl_WRITE_BUS |= 0000001 | BUS::glbl_READ_BUS; } void ALU::execRP_ALU_OR_R1C() { BUS::glbl_WRITE_BUS |= 0177776 | BUS::glbl_READ_BUS; } void ALU::execRP_ALU_OR_R2() { BUS::glbl_WRITE_BUS |= 0000002 | BUS::glbl_READ_BUS; } void ALU::execRP_ALU_OR_RSB() { BUS::glbl_WRITE_BUS |= 0100000 | BUS::glbl_READ_BUS; } void ALU::execRP_ALU_OR_R22() { BUS::glbl_WRITE_BUS |= 0000022 | BUS::glbl_READ_BUS; } void ALU::execRP_ALU_OR_R24() { BUS::glbl_WRITE_BUS |= 0000024 | BUS::glbl_READ_BUS; } void ALU::execRP_ALU_OR_R2000() { BUS::glbl_WRITE_BUS |= 0002000 | BUS::glbl_READ_BUS; // TC GOPROG instruction } //************************************************************ void ALU::execWP_GENRST() { }
unsigned regU::read() { unsigned carry = (outmask()+1) & (ALU::register_X.read() + ALU::register_Y.read()); // end-around carry if(carry || ALU::register_CI.read()) carry = 1; else carry = 0; return outmask() & (ALU::register_X.read() + ALU::register_Y.read() + carry); }
BUS (BUS.h)
/**************************************************************************** * BUS - READ/WRITE BUS subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: BUS.h * * VERSIONS: * * DESCRIPTION: * RW Bus for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef BUS_H #define BUS_H // // // // // // // // BUS LINE DESIGNATIONS Specify the assignment of bus lines to the inputs of a register (for a 'write' operation into a register). Each 'conv_' array specifies the inputs into a single register. The index into the array corresponds to the bit position in the register, where the first parameter (index=0) is bit 16 of the register (msb) and the last parameter (index=15) is register bit 1 (lsb). The value of the parameter identifies the bus line assigned to that register bit. 'BX' means 'don't care'; i.e.: leave that register bit alone.
enum { D0=17, // force bit to zero SGM=15, // sign bit in memory SG=16, // sign (S2; one's compliment) US=15, // uncorrected sign (S1; overflow), except in register G B14=14, B13=13, B12=12, B11=11, B10=10, B9=9, B8=8, B7=7, B6=6, B5=5, B4=4, B3=3, B2=2, B1=1, BX=0 // ignore }; enum ovfState { NO_OVF, POS_OVF, NEG_OVF }; class BUS { public: static unsigned glbl_READ_BUS; // read/write bus for xfer between central regs static unsigned glbl_WRITE_BUS; // read/write bus for xfer between central regs friend class INT; friend class CTR; private: static ovfState testOverflow(unsigned bus); }; #endif
BUS (BUS.cpp)
/**************************************************************************** * BUS - READ/WRITE BUS subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: BUS.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "BUS.h" unsigned BUS::glbl_READ_BUS = 0; unsigned BUS::glbl_WRITE_BUS = 0; ovfState BUS::testOverflow(unsigned bus) { if((bus & 0100000) && !(bus & 0040000)) return NEG_OVF; // negative overflow else if(!(bus & 0100000) && (bus & 0040000)) return POS_OVF; // positive overflow else return NO_OVF; }
CLK (CLK.h)
/**************************************************************************** * CLK - CLOCK subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: CLK.h * * VERSIONS: * * DESCRIPTION: * Clock for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef CLK_H #define CLK_H #include "reg.h" // define pointer-to-function type typedef void (*EXECTYPE)();
CLK (CLK.cpp)
/**************************************************************************** * CLK - CLOCK subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: CLK.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "CLK.h" #include "INP.h" #include "OUT.h" #include "MBF.h" #include "ADR.h" #include "SEQ.h" #include "ALU.h" #include "CRG.h" #include "CTR.h" #include "INT.h" #include "PAR.h" #include "TPG.h" #include "SCL.h" #include "MEM.h" // A container for all registers. This is kept so we can iterate through // all registers to execute the control pulses. For simulation purposes // only; this has no counterpart in the hardware AGC. reg* CLK::registerList[] = // registers are in no particular sequence { &INP::register_IN0, &INP::register_IN1, &INP::register_IN2, &INP::register_IN3, &OUT::register_OUT1, &OUT::register_OUT2, &OUT::register_OUT3, &OUT::register_OUT4, &MBF::register_G, &PAR::register_G15, &ADR::register_S, &ADR::register_BNK, &SEQ::register_SQ, &ALU::register_B, &CRG::register_Q, &CRG::register_Z, &CRG::register_LP, &CRG::register_A, &ALU::register_X, &ALU::register_Y, &ALU::register_U, &SEQ::register_STA, &SEQ::register_STB, &SEQ::register_SNI, &SEQ::register_LOOPCTR, &ALU::register_CI, &SEQ::register_BR1, &SEQ::register_BR2, &CTR::register_UpCELL, &CTR::register_DnCELL, &INT::register_RPCELL, &INT::register_INHINT1, &INT::register_INHINT, &PAR::register_P, &PAR::register_P2, &PAR::register_PALM, &TPG::register_SG, &SCL::register_SCL, &SCL::register_F17, &SCL::register_F13, &SCL::register_F10, 0 // zero is end-of-list flag };
void CLK::clkAGC() { // Now that all the inputs are set up, clock the registers so the outputs // can change state in accordance with the inputs. for(int i=0; registerList[i]; i++) { registerList[i]->clk(); } }
{ { { { { { { {
} } } } } } }
void void void void void void void void void void void void void void void
execR_RA7() execR_RA11() execR_RA12() execR_RA13() execR_RA14() execR_RA() execR_RBK() execR_RG() execR_RLP() execR_RQ() execR_RRPA() execR_RSCT() execR_RZ() execR_SBWG() execR_WE()
{ { { { { { { { { { { { { { {
INP::execRP_RA7(); OUT::execRP_RA11(); OUT::execRP_RA12(); OUT::execRP_RA13(); OUT::execRP_RA14(); CRG::execRP_RA(); ADR::execRP_RBK(); MBF::execRP_RG(); CRG::execRP_RLP(); CRG::execRP_RQ(); INT::execRP_RRPA(); CTR::execRP_RSCT(); CRG::execRP_RZ(); MEM::execRP_SBWG(); MBF::execRP_WE();
} } } } } } } } } } } } } } PAR::execRP_WE(); } } } } } } } } } } } }
void execR_ALU_RB() void execR_ALU_RC() void execR_ALU_RU() void void void void void void void void execR_ALU_OR_RSB() execR_ALU_OR_R1() execR_ALU_OR_R1C() execR_ALU_OR_R2() execR_ALU_OR_R22() execR_ALU_OR_R24() execR_ALU_OR_R2000() execR_ALU_OR_RB14()
{ ALU::execRP_ALU_RB(); { ALU::execRP_ALU_RC(); { ALU::execRP_ALU_RU(); { { { { { { { { ALU::execRP_ALU_OR_RSB(); ALU::execRP_ALU_OR_R1(); ALU::execRP_ALU_OR_R1C(); ALU::execRP_ALU_OR_R2(); ALU::execRP_ALU_OR_R22(); ALU::execRP_ALU_OR_R24(); ALU::execRP_ALU_OR_R2000(); ALU::execRP_ALU_OR_RB14();
EXECTYPE execR[] = { execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_RA, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_RG, execR_RLP, execR_NOPULSE, execR_RQ, execR_RRPA, execR_NOPULSE, execR_RSCT, execR_NOPULSE, execR_RZ, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE,
// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
NO_PULSE, CI, // CLG, // CLCTR, // CTR, // GP, // KRPT, // NISQ, // RA, // RB, // RB14, // RC, // RG, // RLP, // RP2, // RQ, // RRPA, // RSB, // RSCT, // RU, // RZ, // R1, // R1C, // R2, // R22, // R24, // ST1, // ST2, // TMZ, // TOV, // TP, // TRSM, // TSGN, // TSGN2, // WA, // WALP, // WB, // WGx, // WLP, // WOVC, // WOVI, // WOVR, // WP, //
Carry in Clear G Clear loop counter** Loop counter Generate Parity Knock down Rupt priority New instruction to the SQ register Read A Read B Read bit 14 Read C Read G Read LP Read parity 2 Read Q Read RUPT address Read sign bit Read selected counter address Read sum Read Z Read 1 Read 1 complimented Read 2 Read 22 Read 24 Stage 1 Stage 2 Test for minus zero Test for overflow Test parity Test for resume Test sign Test sign 2 Write A Write A and LP Write B Write G (do not reset) Write LP Write overflow counter Write overflow RUPT inhibit Write overflow Write P
// // // // // // // //
WPx, WP2, WQ, WS, WX, WY, WYx, WZ, RSC, WSC, WG,
// // // // // // // //
execR_NOPULSE, // execR_NOPULSE, // execR_NOPULSE, // execR_NOPULSE, // execR_NOPULSE, // execR_NOPULSE, // execR_RA0, execR_RA1, execR_RA2, execR_RA3, execR_RA4, execR_RA5, execR_RA6, execR_RA7, execR_NOPULSE, execR_RA11, execR_RA12, execR_RA13, execR_RA14, execR_RBK, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_SBWG, execR_NOPULSE, execR_WE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, }; // 99 // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
SDV1, // Subsequence DV1 is active SMP1, // Subsequence MP1 is active SRSM3, // Subsequence RSM3 is active RA0, RA1, RA2, RA3, RA4, RA5, RA6, RA7, RA10, RA11, RA12, RA13, RA14, RBK, WA0, WA1, WA2, WA3, WA10, WA11, WA12, WA13, WA14, WBK, WGn, W20, W21, W22, W23 // // // // // // // // // // // // // // // // // // // // // // // // // // // // // Read register at address 0 (A) Read register at address 1 (Q) Read register at address 2 (Z) Read register at address 3 (LP) Read register at address 4 Read register at address 5 Read register at address 6 Read register at address 7 Read register at address 10 (octal) Read register at address 11 (octal) Read register at address 12 (octal) Read register at address 13 (octal) Read register at address 14 (octal) Read BNK Write register at address 0 (A) Write register at address 1 (Q) Write register at address 2 (Z) Write register at address 3 (LP) Write register at address 10 (octal) Write register at address 11 (octal) Write register at address 12 (octal) Write register at address 13 (octal) Write register at address 14 (octal) Write BNK Write G (normal gates)** Write into CYR Write into SR Write into CYL Write into SL General Reset** Clear INHINT** Clear INHINT1** Clear state counter A (STA)** Clear state counter B (STB)** Clear SNI** Clear RPCELL** Set INHINT** Read RUPT opcode ** Write G from memory Set the ST1 bit of STB Write E-MEM from G Write PCTR (latch priority counter sequence)** Write SQ Write stage counter B (STB)** Read 2000 **
GENRST,// CLINH, // CLINH1,// CLSTA, // CLSTB, // CLISQ, // CLRP, // INH, // RPT, // SBWG, // SETSTB,// WE, // WPCTR, // WSQ, // WSTB, // R2000, //
execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_ALU_RB, execR_NOPULSE, execR_ALU_RC, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_ALU_RU, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE,
// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
CLCTR, CTR, GP, KRPT, NISQ, RA, RB, RB14, RC, RG, RLP, RP2, RQ, RRPA, RSB, RSCT, RU, RZ, R1, R1C, R2, R22, R24, ST1, ST2, TMZ, TOV, TP, TRSM, TSGN, TSGN2, WA, WALP, WB, WGx, WLP, WOVC, WOVI, WOVR, WP, WPx, WP2, WQ, WS, WX, WY, WYx, WZ, RSC, WSC, WG,
// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
Clear loop counter** Loop counter Generate Parity Knock down Rupt priority New instruction to the SQ register Read A Read B Read bit 14 Read C Read G Read LP Read parity 2 Read Q Read RUPT address Read sign bit Read selected counter address Read sum Read Z Read 1 Read 1 complimented Read 2 Read 22 Read 24 Stage 1 Stage 2 Test for minus zero Test for overflow Test parity Test for resume Test sign Test sign 2 Write A Write A and LP Write B Write G (do not reset) Write LP Write overflow counter Write overflow RUPT inhibit Write overflow Write P Write P (do not reset) Write P2 Write Q Write S Write X Write Y Write Y (do not reset) Write Z
execR_NOPULSE, // execR_NOPULSE, // execR_NOPULSE, // execR_NOPULSE, // execR_NOPULSE, // execR_NOPULSE, // execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, // // // // // // // // // // // // // // // // // // //
SDV1, // Subsequence DV1 is active SMP1, // Subsequence MP1 is active SRSM3, // Subsequence RSM3 is active RA0, RA1, RA2, RA3, RA4, RA5, RA6, RA7, RA10, RA11, RA12, RA13, RA14, RBK, WA0, WA1, WA2, WA3, WA10, // // // // // // // // // // // // // // // // // // // Read register at address 0 (A) Read register at address 1 (Q) Read register at address 2 (Z) Read register at address 3 (LP) Read register at address 4 Read register at address 5 Read register at address 6 Read register at address 7 Read register at address 10 (octal) Read register at address 11 (octal) Read register at address 12 (octal) Read register at address 13 (octal) Read register at address 14 (octal) Read BNK Write register at address 0 (A) Write register at address 1 (Q) Write register at address 2 (Z) Write register at address 3 (LP) Write register at address 10 (octal)
execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, };
// // // // // // // // // // // // // // // // // // // // // // // // // //
WA11, WA12, WA13, WA14, WBK, WGn, W20, W21, W22, W23
// // // // // // // // // //
Write Write Write Write Write Write Write Write Write Write
register at address register at address register at address register at address BNK G (normal gates)** into CYR into SR into CYL into SL
11 12 13 14
GENRST,// CLINH, // CLINH1,// CLSTA, // CLSTB, // CLISQ, // CLRP, // INH, // RPT, // SBWG, // SETSTB,// WE, // WPCTR, // WSQ, // WSTB, // R2000, //
General Reset** Clear INHINT** Clear INHINT1** Clear state counter A (STA)** Clear state counter B (STB)** Clear SNI** Clear RPCELL** Set INHINT** Read RUPT opcode ** Write G from memory Set the ST1 bit of STB Write E-MEM from G Write PCTR (latch priority counter sequence)** Write SQ Write stage counter B (STB)** Read 2000 **
EXECTYPE execR_ALU_OR[] = { execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_ALU_OR_RB14, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_ALU_OR_RSB, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_ALU_OR_R1, execR_ALU_OR_R1C, execR_ALU_OR_R2, execR_ALU_OR_R22, execR_ALU_OR_R24, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE,
// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
NO_PULSE, CI, // CLG, // CLCTR, // CTR, // GP, // KRPT, // NISQ, // RA, // RB, // RB14, // RC, // RG, // RLP, // RP2, // RQ, // RRPA, // RSB, // RSCT, // RU, // RZ, // R1, // R1C, // R2, // R22, // R24, // ST1, // ST2, // TMZ, // TOV, // TP, // TRSM, // TSGN, // TSGN2, // WA, // WALP, // WB, // WGx, // WLP, //
Carry in Clear G Clear loop counter** Loop counter Generate Parity Knock down Rupt priority New instruction to the SQ register Read A Read B Read bit 14 Read C Read G Read LP Read parity 2 Read Q Read RUPT address Read sign bit Read selected counter address Read sum Read Z Read 1 Read 1 complimented Read 2 Read 22 Read 24 Stage 1 Stage 2 Test for minus zero Test for overflow Test parity Test for resume Test sign Test sign 2 Write A Write A and LP Write B Write G (do not reset) Write LP
execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_NOPULSE, execR_ALU_OR_R2000, };
// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
WOVC, WOVI, WOVR, WP, WPx, WP2, WQ, WS, WX, WY, WYx, WZ, RSC, WSC, WG,
// // // // // // // // // // // //
Write Write Write Write Write Write Write Write Write Write Write Write
overflow counter overflow RUPT inhibit overflow P P (do not reset) P2 Q S X Y Y (do not reset) Z
SDV1, // Subsequence DV1 is active SMP1, // Subsequence MP1 is active SRSM3, // Subsequence RSM3 is active RA0, RA1, RA2, RA3, RA4, RA5, RA6, RA7, RA10, RA11, RA12, RA13, RA14, RBK, WA0, WA1, WA2, WA3, WA10, WA11, WA12, WA13, WA14, WBK, WGn, W20, W21, W22, W23 // // // // // // // // // // // // // // // // // // // // // // // // // // // // // Read register at address 0 (A) Read register at address 1 (Q) Read register at address 2 (Z) Read register at address 3 (LP) Read register at address 4 Read register at address 5 Read register at address 6 Read register at address 7 Read register at address 10 (octal) Read register at address 11 (octal) Read register at address 12 (octal) Read register at address 13 (octal) Read register at address 14 (octal) Read BNK Write register at address 0 (A) Write register at address 1 (Q) Write register at address 2 (Z) Write register at address 3 (LP) Write register at address 10 (octal) Write register at address 11 (octal) Write register at address 12 (octal) Write register at address 13 (octal) Write register at address 14 (octal) Write BNK Write G (normal gates)** Write into CYR Write into SR Write into CYL Write into SL General Reset** Clear INHINT** Clear INHINT1** Clear state counter A (STA)** Clear state counter B (STB)** Clear SNI** Clear RPCELL** Set INHINT** Read RUPT opcode ** Write G from memory Set the ST1 bit of STB Write E-MEM from G Write PCTR (latch priority counter sequence)** Write SQ Write stage counter B (STB)** Read 2000 **
GENRST,// CLINH, // CLINH1,// CLSTA, // CLSTB, // CLISQ, // CLRP, // INH, // RPT, // SBWG, // SETSTB,// WE, // WPCTR, // WSQ, // WSTB, // R2000, //
void void void void void void void void void void void
execW_NOPULSE() execW_CI() execW_CLG() execW_CLINH() execW_CLINH1() execW_CLISQ() execW_CLCTR() execW_CLRP() execW_CLSTA() execW_CLSTB() execW_CTR()
{ { { { { { { { { { { {
} ALU::execWP_CI(); PAR::execWP_CLG(); INT::execWP_CLINH(); INT::execWP_CLINH1(); SEQ::execWP_CLISQ(); SEQ::execWP_CLCTR(); INT::execWP_CLRP(); SEQ::execWP_CLSTA(); SEQ::execWP_CLSTB(); SEQ::execWP_CTR();
} } } } } } } } } }
void execW_GENRST()
SEQ::execWP_GENRST(); MBF::execWP_GENRST(); CRG::execWP_GENRST(); PAR::execWP_GENRST(); ALU::execWP_GENRST(); CTR::execWP_GENRST(); INT::execWP_GENRST(); OUT::execWP_GENRST(); } PAR::execWP_GP(); } INT::execWP_INH(); } INT::execWP_KRPT(); } SEQ::execWP_NISQ(); } INT::execWP_RPT(); } PAR::execWP_RP2(); } MBF::execWP_SBWG(); PAR::execWP_SBWG(); } SEQ::execWP_SETSTB(); } SEQ::execWP_ST1(); } SEQ::execWP_ST2(); } SEQ::execWP_TMZ(); } SEQ::execWP_TOV(); } PAR::execWP_TP(); } SEQ::execWP_TRSM(); } SEQ::execWP_TSGN(); } SEQ::execWP_TSGN2(); } CRG::execWP_WA0(); } CRG::execWP_WA1(); } CRG::execWP_WA2(); } CRG::execWP_WA3(); } OUT::execWP_WA10(); } OUT::execWP_WA11(); } OUT::execWP_WA12(); } OUT::execWP_WA13(); } OUT::execWP_WA14(); } CRG::execWP_WA(); } CRG::execWP_WALP(); } ALU::execWP_WB(); } ADR::execWP_WBK(); } MEM::execWP_WE(); } MBF::execWP_WGn(); } MBF::execWP_WGx(); PAR::execWP_WGx(); } CRG::execWP_WLP(); } CTR::execWP_WOVC(); } INT::execWP_WOVI(); } CTR::execWP_WOVR(); } PAR::execWP_WP(); } PAR::execWP_WPx(); } PAR::execWP_WP2(); } CTR::execWP_WPCTR(); } CRG::execWP_WQ(); } ADR::execWP_WS(); } SEQ::execWP_WSQ(); } SEQ::execWP_WSTB(); } ALU::execWP_WX(); } ALU::execWP_WY(); } ALU::execWP_WYx(); } CRG::execWP_WZ(); } MBF::execWP_W20(); } MBF::execWP_W21(); } MBF::execWP_W22(); } MBF::execWP_W23(); }
void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void void
execW_GP() execW_INH() execW_KRPT() execW_NISQ() execW_RPT() execW_RP2() execW_SBWG() execW_SETSTB() execW_ST1() execW_ST2() execW_TMZ() execW_TOV() execW_TP() execW_TRSM() execW_TSGN() execW_TSGN2() execW_WA0() execW_WA1() execW_WA2() execW_WA3() execW_WA10() execW_WA11() execW_WA12() execW_WA13() execW_WA14() execW_WA() execW_WALP() execW_WB() execW_WBK() execW_WE() execW_WGn() execW_WGx() execW_WLP() execW_WOVC() execW_WOVI() execW_WOVR() execW_WP() execW_WPx() execW_WP2() execW_WPCTR() execW_WQ() execW_WS() execW_WSQ() execW_WSTB() execW_WX() execW_WY() execW_WYx() execW_WZ() execW_W20() execW_W21() execW_W22() execW_W23()
{ { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { {
EXECTYPE execW[] = { execW_NOPULSE, execW_CI, execW_CLG, execW_CLCTR, execW_CTR, execW_GP, execW_KRPT, execW_NISQ, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_RP2, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_ST1, execW_ST2, execW_TMZ, execW_TOV, execW_TP, execW_TRSM, execW_TSGN, execW_TSGN2, execW_WA, execW_WALP, execW_WB, execW_WGx, execW_WLP, execW_WOVC, execW_WOVI, execW_WOVR, execW_WP, execW_WPx, execW_WP2, execW_WQ, execW_WS, execW_WX, execW_WY, execW_WYx, execW_WZ,
// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
NO_PULSE, CI, // CLG, // CLCTR, // CTR, // GP, // KRPT, // NISQ, // RA, // RB, // RB14, // RC, // RG, // RLP, // RP2, // RQ, // RRPA, // RSB, // RSCT, // RU, // RZ, // R1, // R1C, // R2, // R22, // R24, // ST1, // ST2, // TMZ, // TOV, // TP, // TRSM, // TSGN, // TSGN2, // WA, // WALP, // WB, // WGx, // WLP, // WOVC, // WOVI, // WOVR, // WP, // WPx, // WP2, // WQ, // WS, // WX, // WY, // WYx, // WZ, // RSC, WSC, WG,
Carry in Clear G Clear loop counter** Loop counter Generate Parity Knock down Rupt priority New instruction to the SQ register Read A Read B Read bit 14 Read C Read G Read LP Read parity 2 Read Q Read RUPT address Read sign bit Read selected counter address Read sum Read Z Read 1 Read 1 complimented Read 2 Read 22 Read 24 Stage 1 Stage 2 Test for minus zero Test for overflow Test parity Test for resume Test sign Test sign 2 Write A Write A and LP Write B Write G (do not reset) Write LP Write overflow counter Write overflow RUPT inhibit Write overflow Write P Write P (do not reset) Write P2 Write Q Write S Write X Write Y Write Y (do not reset) Write Z
execW_NOPULSE, // execW_NOPULSE, // execW_NOPULSE, // execR_NOPULSE, // execR_NOPULSE, // execR_NOPULSE, // execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, execW_NOPULSE, // // // // // // // // // // // // // //
SDV1, // Subsequence DV1 is active SMP1, // Subsequence MP1 is active SRSM3, // Subsequence RSM3 is active RA0, RA1, RA2, RA3, RA4, RA5, RA6, RA7, RA10, RA11, RA12, RA13, RA14, RBK, // // // // // // // // // // // // // // Read Read Read Read Read Read Read Read Read Read Read Read Read Read register register register register register register register register register register register register register BNK at at at at at at at at at at at at at address address address address address address address address address address address address address 0 (A) 1 (Q) 2 (Z) 3 (LP) 4 5 6 7 10 (octal) 11 (octal) 12 (octal) 13 (octal) 14 (octal)
execW_WA0, execW_WA1, execW_WA2, execW_WA3, execW_WA10, execW_WA11, execW_WA12, execW_WA13, execW_WA14, execW_WBK, execW_WGn, execW_W20, execW_W21, execW_W22, execW_W23, execW_GENRST, execW_CLINH, execW_CLINH1, execW_CLSTA, execW_CLSTB, execW_CLISQ, execW_CLRP, execW_INH, execW_RPT, execW_SBWG, execW_SETSTB, execW_WE, execW_WPCTR, execW_WSQ, execW_WSTB, execW_NOPULSE, }; // 99
// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
WA0, WA1, WA2, WA3, WA10, WA11, WA12, WA13, WA14, WBK, WGn, W20, W21, W22, W23
// // // // // // // // // // // // // // //
Write Write Write Write Write Write Write Write Write Write Write Write Write Write Write
register at address register at address register at address register at address register at address register at address register at address register at address register at address BNK G (normal gates)** into CYR into SR into CYL into SL
GENRST,// CLINH, // CLINH1,// CLSTA, // CLSTB, // CLISQ, // CLRP, // INH, // RPT, // SBWG, // SETSTB,// WE, // WPCTR, // WSQ, // WSTB, // R2000, //
General Reset** Clear INHINT** Clear INHINT1** Clear state counter A (STA)** Clear state counter B (STB)** Clear SNI** Clear RPCELL** Set INHINT** Read RUPT opcode ** Write G from memory Set the ST1 bit of STB Write E-MEM from G Write PCTR (latch priority counter sequence)** Write SQ Write stage counter B (STB)** Read 2000 **
CPM (CPM.h)
/**************************************************************************** * CPM - CONTROL PULSE MATRIX subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: CPM.h * * VERSIONS: * * DESCRIPTION: * Control Pulse Matrix for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef CPM_H #define CPM_H #include "TPG.h" #include "SEQ.h"
class CPM { public: static subseq instructionSubsequenceDecoder( int counter_subseq, int SQ_field, int STB_field); static char* subseqString[]; static void controlPulseMatrix(); static void readEPROM(char* fileName, int* eprom); static static static static static static static private: // Clear the list of currently asserted control pulses. static void clearControlPulses(); // Assert the set of control pulses by adding them to the list of currently // active control signals. static void assert(cpType* pulse); // Assert a control pulse by adding it to the list of currently asserted // control pulses. static void assert(cpType pulse); static void get_CPM_A(int CPM_A_address); static void getControlPulses_EPROM(int address); static void checkEPROM(int inval, int lowbit); }; #endif int int int int int int int EPROM1_8 [0x3fff+1]; EPROM9_16 [0x3fff+1]; EPROM17_24[0x3fff+1]; EPROM25_32[0x3fff+1]; EPROM33_40[0x3fff+1]; EPROM41_48[0x3fff+1]; EPROM49_56[0x3fff+1];
CPM (CPM.cpp)
/**************************************************************************** * CPM - CONTROL PULSE MATRIX subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: CPM.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "CPM.h" #include "SEQ.h" #include "MON.h" #include "CTR.h" #include "INT.h" #include "ADR.h" #include <stdlib.h> char* CPM::subseqString[] = { "TC0", "CCS0", "CCS1", "NDX0", "NDX1", "RSM3", "XCH0", "CS0", "TS0", "AD0", "MASK0", "MP0", "MP1", "MP3", "DV0", "DV1", "SU0", "RUPT1", "RUPT3", "STD2", "PINC0", "MINC0", "SHINC0", "NO_SEQ" }; subseq CPM::instructionSubsequenceDecoder( int counter_subseq, int SQ_field, int STB_field) { // Combinational logic decodes instruction and the stage count // to get the instruction subsequence. static subseq decode[16][4] = { { TC0, RUPT1, STD2, RUPT3 }, // 00 { CCS0, CCS1, NO_SEQ, NO_SEQ }, // 01 { NDX0, NDX1, NO_SEQ, RSM3 }, // 02 { XCH0, NO_SEQ, STD2, NO_SEQ }, // 03 { { { { { { { { { { { NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, MP0, DV0, SU0, CS0, TS0, AD0, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, MP1, DV1, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, STD2, STD2, STD2, STD2, STD2, NO_SEQ NO_SEQ NO_SEQ NO_SEQ NO_SEQ }, }, }, }, }, // // // // // 04 05 06 07 10
{ };
MASK0,
NO_SEQ,
STD2,
NO_SEQ }
// 17
if(counter_subseq == PINCSEL) return PINC0; else if(counter_subseq == MINCSEL) return MINC0; else return decode[SQ_field][STB_field]; } void CPM::clearControlPulses() { for(unsigned i=0; i<MAXPULSES; i++) SEQ::glbl_cp[i] = NO_PULSE; } void CPM::assert(cpType* pulse) { int j=0; for(unsigned i=0; i<MAXPULSES && j<MAX_IPULSES && pulse[j] != NO_PULSE; i++) { if(SEQ::glbl_cp[i] == NO_PULSE) { SEQ::glbl_cp[i] = pulse[j]; j++; } } } void CPM::assert(cpType pulse) { for(unsigned i=0; i<MAXPULSES; i++) { if(SEQ::glbl_cp[i] == NO_PULSE) { SEQ::glbl_cp[i] = pulse; break; } } } int int int int int int int CPM::EPROM1_8 []; CPM::EPROM9_16 []; CPM::EPROM17_24[]; CPM::EPROM25_32[]; CPM::EPROM33_40[]; CPM::EPROM41_48[]; CPM::EPROM49_56[];
void CPM::readEPROM(char* fileName, int* eprom) { cout << "Reading EPROM: " << fileName << endl; // Open the EPROM file. FILE* ifp = fopen(fileName, "r"); if(!ifp) { perror("fopen failed for source file"); exit(-1); } const int addressBytes = 3; // 24-bit address range const int sumCheckBytes = 1; char buf[4096]; while(fgets(buf,4096,ifp)) { // process a record if(buf[0] != 'S') { cout << "Error reading start of EPROM record for: " << fileName << endl; exit(-1);
} char tmp[256]; strncpy(tmp, &buf[2], 2); tmp[2] = '\0'; int totalByteCount = strtol(tmp, 0, 16); int mySumCheck = totalByteCount & 0xff; strncpy(tmp, &buf[4], 6); tmp[addressBytes*2] = '\0'; int address = strtol(tmp, 0, 16); mySumCheck = (mySumCheck + ((address & 0xff0000) >> 16)) % 256; mySumCheck = (mySumCheck + ((address & 0x00ff00) >> 8)) % 256; mySumCheck = (mySumCheck + ((address & 0x0000ff) )) % 256; //cout << hex << totalByteCount << ", " << address << dec << endl; int dataBytes = totalByteCount - addressBytes - sumCheckBytes; int i = (addressBytes+2)*2; // index to 1st databyte char. for(int j=0; j<dataBytes; j++) { // get a data byte strncpy(tmp, &buf[i], 2); tmp[2] = '\0'; int data = strtol(tmp, 0, 16); //cout << hex << data << dec << endl; mySumCheck = (mySumCheck + data) % 256; // The H/W AGC needs negative logic in the EPROMS (0=asserted) // but this simulator needs positive logic, so we bit flip the word. //eprom[address] = data; eprom[address] = ((~data) & 0xff); address++; i+=2; // bump to next databyte char } strncpy(tmp, &buf[i], 2); tmp[2] = '\0'; int sumCheck = strtol(tmp, 0, 16); if(sumCheck != ((~mySumCheck) & 0xff)) { cout << "sumCheck failed; file: " << fileName << ", address: " << hex << address << ", sumCheck: " << sumCheck << ", mySumCheck: " << mySumCheck << dec << endl; exit(-1); } } fclose(ifp); } void CPM::checkEPROM(int inval, int lowbit) { for(int mask=0x1; inval && mask !=0x100; mask=mask<<1) { if(inval & mask) assert((cpType) lowbit); lowbit++; } } // perform the CPM-A EPROM function using the EPROM files void CPM::getControlPulses_EPROM(int address) { checkEPROM(EPROM1_8 [address], 1); checkEPROM(EPROM9_16 [address], 9); checkEPROM(EPROM17_24[address], 17); checkEPROM(EPROM25_32[address], 25); checkEPROM(EPROM33_40[address], 33); checkEPROM(EPROM41_48[address], 41); checkEPROM(EPROM49_56[address], 49); } void CPM::get_CPM_A(int address)
{ // Use the EPROM tables to get the CPM-A control pulses documented // in R-393. getControlPulses_EPROM(address); // Now add some additional control pulses implied, but not documented // in R-393. if(SEQ::register_LOOPCTR.read() == 6) { assert(ST2); // STA <- 2 assert(CLCTR); // CTR <- 0 } //***************************************************************** // Now that the EPROM tables are used for CPM-A, this function is only // used to display the instruction subsequence in MON. SEQ::glbl_subseq = CPM::instructionSubsequenceDecoder( CTR::getSubseq(), SEQ::register_SQ.read(), SEQ::register_STB.read()); //***************************************************************** // These were in CPM-C, where the rest of the control signal assertions // related to their use still are, but were moved here because WB and RB // are part of the R-393 sequence tables. Check CPM-C to see how these // assertions fit in (the former use is commented out there). switch(TPG::register_SG.read()) { case PWRON: assert(WB); // break; TC GOPROG copied to B (see CPM-C for related assertions)
case TP12: if(SEQ::register_SNI.read() == 1) { if(!INT::IRQ()) { // Normal instruction assert(RB); // SQ <- B (see CPM-C for related assertions) } } break; default: ; } }
void CPM::controlPulseMatrix() { // Combination logic decodes time pulse, subsequence, branch register, and // "select next instruction" latch to get control pulses associated with // those states. // Get rid of any old control pulses. clearControlPulses(); //******************************************************************************* // SUBSYSTEM A int SB2_field = 0; int SB1_field = 0; switch(CTR::getSubseq()) { case PINCSEL: SB2_field = 0; SB1_field = 1; break; case MINCSEL: SB2_field = 1; SB1_field = 0; break; default:
SB2_field = 0; SB1_field = 0; }; int CPM_A_address = 0; CPM_A_address = (SB2_field << 13) | (SB1_field << 12) | (SEQ::register_SQ.read() (SEQ::register_STB.read() (TPG::register_SG.read() (SEQ::register_BR1.read() SEQ::register_BR2.read();
8) 6) 2) 1)
| | | |
// Construct address into CPM-A control pulse ROM: // Address bits (bit 1 is LSB) // 1: register BR2 // 2: register BR1 // 3-6: register SG (4) // 7,8: register STB (2) // 9-12: register SQ (4) // 13: STB_01 (from CTR: selects PINC, MINC, or none) // 14: STB_02 (from CTR: selects PINC, MINC, or none) get_CPM_A(CPM_A_address); //*******************************************************************************
//******************************************************************************* // SUBSYSTEM B // NOTE: WG, RSC, WSC are generated by SUBSYSTEM A. Those 3 signals are only used // by SUBSYSTEM B; not anywhere else. // CONSIDER MOVING TO ADR **********************8 if(SEQ::isAsserted(WG)) { switch(ADR::register_S.read()) { case 020: assert(W20); break; case 021: assert(W21); break; case 022: assert(W22); break; case 023: assert(W23); break; default: if(ADR::GTR_17()) assert(WGn); // not a central register } } if(SEQ::isAsserted(RSC)) { switch(ADR::register_S.read()) { case 00: assert(RA0); break; case 01: assert(RA1); break; case 02: assert(RA2); break; case 03: assert(RA3); break; case 04: assert(RA4); break; case 05: assert(RA5); break; case 06: assert(RA6); break; case 07: assert(RA7); break; case 010: assert(RA10); break; case 011: assert(RA11); break; case 012: assert(RA12); break; case 013: assert(RA13); break; case 014: assert(RA14); break; case 015: assert(RBK); break; default: break; // 016, 017 } } if(SEQ::isAsserted(WSC)) switch(ADR::register_S.read()) { case 00: assert(WA0); break;
case 01: assert(WA1); break; case 02: assert(WA2); break; case 03: assert(WA3); break; case 010: assert(WA10); break; case 011: assert(WA11); break; case 012: assert(WA12); break; case 013: assert(WA13); break; case 014: assert(WA14); break; case 015: assert(WBK); break; default: break; // 016, 017 } //*******************************************************************************
//******************************************************************************* // SUBSYSTEM C switch(TPG::register_SG.read()) { case STBY: assert(GENRST); // inhibit all alarms // init "SQ" complex // clear branch registers // stage registers are not cleared; should they be? // zeroes are already gated onto bus when no read pulses are asserted. // to zero synchronous-clocked registers, assert write pulses here. // Level-triggered registers are zeroed by GENRST anded with CLK2. break; case PWRON: assert(R2000); //assert(WB); // break; case TP1: // Moved this from TP12 to TP1 because CLISQ was getting cleared in the // hardware AGC before TPG was clocked; therefore TPG was not seeing the // SNI indication. assert(CLISQ); // SNI <- 0 case TP5: // EMEM must be available in G register by TP6 if( ADR::GTR_17() && // not a central register !ADR::GTR_1777() && // not fixed memory !SEQ::isAsserted(SDV1) && // not a loop counter subseq !SEQ::isAsserted(SMP1)) { assert(SBWG); } if( ADR::EQU_17() ) assert (INH); // INHINT (INDEX 017) if( ADR::EQU_16() ) assert (CLINH); // RELINT (INDEX 016) break; case TP6: // FMEM must be available in G register by TP7 if( ADR::GTR_1777() memory !SEQ::isAsserted(SDV1) !SEQ::isAsserted(SMP1)) { assert(SBWG); } break; case TP11: // G register written to memory beginning at TP11; Memory updates are in // G by TP10 for all normal and extracode instructions, but the PINC, MINC, && // not a loop counter subseq
&&
// not eraseable
// and SHINC sequences write to G in TP10 because they need to update the // parity bit. if( ADR::GTR_17() && // not a central register !ADR::GTR_1777() && // not fixed memory !SEQ::isAsserted(SDV1) && // not a loop counter subseq !SEQ::isAsserted(SMP1)) { assert(WE); } // Additional interrupts are inhibited during servicing of an interrupt; // Remove the inhibition when RESUME is executed (INDEX 025) if(SEQ::isAsserted(SRSM3)) assert(CLRP); break; case TP12: // DISABLE INPUT CHANGE TO PRIORITY COUNTER (reenable after TP1) // Check the priority counters; service any waiting inputs on the next // memory cycle. assert(WPCTR); if(SEQ::register_SNI.read() == 1) // if SNI is set, get next instruction { if(INT::IRQ()) // if interrupt requested (see CPM-A for similar assertion) { // Interrupt: SQ <- 0 (the default RW bus state) assert(RPT); // latch interrupt vector assert(SETSTB); // STB <- 1 } else { // Normal instruction //assert(RB); // SQ <- B (implemented in CPM-A) assert(CLSTB); // STB <- 0 } assert(WSQ); assert(CLSTA); // STA <- 0 // Remove inhibition of interrupts (if they were) AFTER the next instruction assert(CLINH1); // INHINT1 <- 0 } else if(CTR::getSubseq() == NOPSEL) // if previous sequence was not a counter { // get next sequence for same instruction. assert(WSTB); // STB <- STA assert(CLSTA); // STA <- 0 } //assert(CLISQ); break; default: ; } //******************************************************************************* } // SNI <- 0 (moved to TP1)
CRG (CRG.h)
/**************************************************************************** * CRG - ADDRESSABLE CENTRAL REGISTER subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: CRG.h * * VERSIONS: * * DESCRIPTION: * Addressable Central Registers for the Block 1 Apollo Guidance Computer * prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef CRG_H #define CRG_H #include "reg.h" class regQ : public reg { public: regQ() : reg(16, "%06o") { } }; class regZ : public reg { public: regZ() : reg(16, "%06o") { } }; class regLP : public reg { public: regLP() : reg(16, "%06o") { } }; class regA : public reg { public: regA() : reg(16, "%06o") { } }; class CRG { public: static void execWP_GENRST(); static static static static static static static static static static static static static static static void void void void void void void void void void void void void void void execRP_RQ(); execRP_RA1(); execWP_WQ(); execWP_WA1(); execRP_RZ(); execRP_RA2(); execWP_WZ(); execWP_WA2(); execRP_RLP(); execRP_RA3(); execRP_RA(); execRP_RA0(); execWP_WA(); execWP_WA0(); execWP_WALP();
static void execWP_WLP(); static void execWP_WA3(); static static static static regQ register_Q; // return address regZ register_Z; // program counter regLP register_LP; // lower accumulator regA register_A; // accumulator
static unsigned conv_WALP_LP[]; static unsigned conv_WALP_A[]; static unsigned conv_WLP[]; }; #endif
CRG (CRG.cpp)
/**************************************************************************** * CRG - ADDRESSABLE CENTRAL REGISTER subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: CRG.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "CRG.h" #include "SEQ.h" #include "BUS.h" regQ CRG::register_Q; // return address regZ CRG::register_Z; // program counter regLP CRG::register_LP; // lower accumulator regA CRG::register_A; // accumulator // // // // // // // // BUS LINE ASSIGNMENTS Specify the assignment of bus lines to the inputs of a register (for a 'write' operation into a register). Each 'conv_' array specifies the inputs into a single register. The index into the array corresponds to the bit position in the register, where the first parameter (index=0) is bit 16 of the register (msb) and the last parameter (index=15) is register bit 1 (lsb). The value of the parameter identifies the bus line assigned to that register bit. 'BX' means 'don't care'; i.e.: leave that register bit alone.
unsigned CRG::conv_WALP_LP[] = { BX, BX, B1, BX, BX, BX, BX, BX, BX, BX, BX, BX, BX, BX, BX, BX }; unsigned CRG::conv_WALP_A[] = { SG, SG, US, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2 }; unsigned CRG::conv_WLP[] = { B1, B1, D0, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2 };
void CRG::execWP_WZ() { register_Z.write(BUS::glbl_WRITE_BUS); } void CRG::execWP_WA2() { register_Z.write(BUS::glbl_WRITE_BUS); } void CRG::execRP_RLP() { BUS::glbl_READ_BUS = register_LP.read(); } void CRG::execRP_RA3() { BUS::glbl_READ_BUS = register_LP.read(); } void CRG::execWP_WALP() { register_LP.writeShift(BUS::glbl_WRITE_BUS, CRG::conv_WALP_LP); register_A.writeShift(BUS::glbl_WRITE_BUS, CRG::conv_WALP_A); } void CRG::execWP_WLP() { register_LP.writeShift(BUS::glbl_WRITE_BUS, CRG::conv_WLP); } void CRG::execWP_WA3() { register_LP.writeShift(BUS::glbl_WRITE_BUS, CRG::conv_WLP); }
CTR (CTR.h)
/**************************************************************************** * CTR - INVOLUNTARY PRIORITY COUNTER subsystem * * AUTHOR: John Pultorak * DATE: 10/25/02 * FILE: CTR.h * * VERSIONS: * * DESCRIPTION: * Involuntary Counters for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef CTR_H #define CTR_H #include "reg.h" enum ctrNumber { // indexes for priority cells OVCTR =0, TIME2 TIME1 TIME3 TIME4 }; enum ctrAddr { // octal addresses of counters // Note: In Block 1, TIME1 preceeds TIME2. In Block II, // this is reversed: TIME2 preceeds TIME1. This reversal // was done so that the most significant time word occurs // at the lower address in the 2 word AGC clock. Therefore, // a common AGC software routine can be used to read the // time. OVCTR_ADDR =0034, TIME2_ADDR TIME1_ADDR TIME3_ADDR TIME4_ADDR SPARE1_ADDR SPARE2_ADDR SPARE3_ADDR }; enum pCntrType { NOPSEL PINCSEL MINCSEL }; =0, =1, =2 // NO COUNTER // PINC // MINC =0035, // Block II puts TIME2 first =0036, =0037, =0040, =0041, =0042, =0043 =1, =2, =3, =4, // Block II puts TIME2 first
class regUpCELL : public reg { public: // Bit synchronize the counter inputs. regUpCELL() : reg(8, "%03o") { } }; class regDnCELL : public reg { public:
// Bit synchronize the counter inputs. regDnCELL() : reg(8, "%03o") { } }; class CTR { public: static static static static static
static unsigned getSubseq(); static unsigned pcUp[]; static unsigned pcDn[]; static regUpCELL register_UpCELL; // latches the selected priority counter cell (0-7) static regDnCELL register_DnCELL; // latches the selected priority counter cell (0-7) private: static void resetAllpc(); }; #endif
CTR (CTR.cpp)
/**************************************************************************** * CTR - INVOLUNTARY PRIORITY COUNTER subsystem * * AUTHOR: John Pultorak * DATE: 10/25/02 * FILE: CTR.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "CTR.h" #include "INT.h" #include "BUS.h" #include "SEQ.h" regUpCELL CTR::register_UpCELL; // latches the selected priority counter cell (0-7 (decimal)) regDnCELL CTR::register_DnCELL; // latches the selected priority counter cell (0-7 (decimal)) unsigned CTR::pcUp[8]; unsigned CTR::pcDn[8];
// PRIORITY COUNTERS // // // // // **************************************************** The interrupt priorities are stored in RPCELL as 1-5, but the priority counter priorities are stored as 0-7; this inconsistency should be fixed, probably. Also, the method of address determination for the priority counters needs work
void CTR::resetAllpc() { for(int i=0; i<8; i++) { pcUp[i]=0; pcDn[i]=0; } } // priority encoder; outputs 0-7; 0=highest priority (OVCTR), 1=TIME2, 2=TIME1, etc static bool newPriority = true; // a simulator performance optimization; not in the hardware AGC unsigned getPriority() { // simulator optimization; don't recompute priority if the priority inputs haven't changed static unsigned priority = 7; // default (lowest priority) if(!newPriority) return priority; priority = 7; // default (lowest priority) for(int i=0; i<8; i++) { if(CTR::register_UpCELL.readField(i+1,i+1) | CTR::register_DnCELL.readField(i+1,i+1)) { priority = i; break; } } newPriority = false; return priority; }
unsigned CTR::getSubseq() { unsigned pc = getPriority(); unsigned upCell = CTR::register_UpCELL.readField(pc+1,pc+1); unsigned dnCell = CTR::register_DnCELL.readField(pc+1,pc+1);
void CTR::execWP_WPCTR() { // transfer cell data into up and down synch registers for(int i=0; i<8; i++) { register_UpCELL.writeField(i+1,i+1,pcUp[i]); register_DnCELL.writeField(i+1,i+1,pcDn[i]); } newPriority=true; // a simulator performance optimization; not in hardware AGC } // Selected counter address is requested at TP1. // Counter address is latched at TP12 void CTR::execRP_RSCT() { BUS::glbl_READ_BUS = 034 + getPriority(); } void CTR::execWP_WOVR() { unsigned pc = getPriority(); if(register_UpCELL.readField(pc+1,pc+1)) { pcUp[pc]=0; } if(register_DnCELL.readField(pc+1,pc+1)) { pcDn[pc]=0; } // generate various actions in response to counter overflows: switch(BUS::testOverflow(BUS::glbl_WRITE_BUS)) { case POS_OVF: // positive overflow switch(getPriority()) // get the counter { case TIME1: CTR::pcUp[TIME2]=1; break; // overflow from TIME1 increments TIME2 case TIME3: INT::rupt[T3RUPT]=1; break; // overflow from TIME3 triggers T3RUPT case TIME4: INT::rupt[DSRUPT]=1; break; // overflow from TIME4 triggers DSRUPT } break; case NEG_OVF: break; // no actions for negative counter overflow } } void CTR::execWP_WOVC() {
switch(BUS::testOverflow(BUS::glbl_WRITE_BUS)) { case POS_OVF: CTR::pcUp[OVCTR]=1; break; // incr OVCTR (034) case NEG_OVF: CTR::pcDn[OVCTR]=1; break; // decr OVCTR (034) } } // // // // register_PCELL: Overflow from the selected counter appears on the bus when WOVR or WOVC is asserted; it could be used to trigger an interrupt or routed to increment another counter
DSP (DSP.h)
/**************************************************************************** * DSP - DSKY DISPLAY subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: DSP.h * * VERSIONS: * * DESCRIPTION: * DSKY Display for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef DSP_H #define DSP_H class DSP { public: // DSKY display // major mode display static char MD1; static char MD2; // verb display static char VD1; static char VD2; // noun display static char ND1; static char ND2; static static static static static static static static static static static static static static static static static static // R1 char R1S; char R1D1; char R1D2; char R1D3; char R1D4; char R1D5; // R2 char R2S; char R2D1; char R2D2; char R2D3; char R2D4; char R2D5; // R3 char R3S; char R3D1; char R3D2; char R3D3; char R3D4; char R3D5; // These flags control the sign; if both bits are 0 or 1, there is no sign. // Otherwise, the sign is set by the selected bit. unsigned R1SP; unsigned R1SM; unsigned R2SP; unsigned R2SM; unsigned R3SP; unsigned R3SM;
// verb/noun flash static unsigned flash; static void clearOut0(); static char signConv(unsigned p, unsigned m); static char outConv(unsigned in); static void decodeRelayWord(unsigned in); }; #endif
DSP (DSP.cpp)
/**************************************************************************** * DSP - DSKY DISPLAY subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: DSP.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "DSP.h" #include <string.h> #include <iostream.h> #include <stdio.h> bool dskyChanged = false; // true when DSKY display changes // major mode display char DSP::MD1=0; char DSP::MD2=0; // verb display char DSP::VD1=0; char DSP::VD2=0; // noun display char DSP::ND1=0; char DSP::ND2=0; char char char char char char char char char char char char char char char char char char // R1 DSP::R1S=0; DSP::R1D1=0; DSP::R1D2=0; DSP::R1D3=0; DSP::R1D4=0; DSP::R1D5=0; // R2 DSP::R2S=0; DSP::R2D1=0; DSP::R2D2=0; DSP::R2D3=0; DSP::R2D4=0; DSP::R2D5=0; // R3 DSP::R3S=0; DSP::R3D1=0; DSP::R3D2=0; DSP::R3D3=0; DSP::R3D4=0; DSP::R3D5=0;
// These flags control the sign; if both bits are 0 or 1, there is no sign. // Otherwise, the sign is set by the selected bit. unsigned DSP::R1SP=0; unsigned DSP::R1SM=0; unsigned DSP::R2SP=0; unsigned DSP::R2SM=0; unsigned DSP::R3SP=0; unsigned DSP::R3SM=0; // flag controls 1 Hz flash of verb and noun display unsigned DSP::flash = 0; // 0=flash off, 1=flash on void DSP::clearOut0() { MD1 = MD2 = ' '; VD1 = VD2 = ' ';
= = = =
ND2 = ' '; // noun display R1D1 = R1D2 = R1D3 = R1D4 = R1D5 = ' '; R2D1 = R2D2 = R2D3 = R2D4 = R2D5 = ' '; R3D1 = R3D2 = R3D3 = R3D4 = R3D5 = ' ';
// R1 // R2 // R3
R1SP = R1SM = 0; R2SP = R2SM = 0; R3SP = R3SM = 0; } char DSP::signConv(unsigned p, unsigned m) { if(p && !m) return '+'; else if(m && !p) return '-'; else return ' '; } char DSP::outConv(unsigned in) { switch(in) { case 000: return ' '; case 025: return '0'; case 003: return '1'; case 031: return '2'; case 033: return '3'; case 017: return '4'; case 036: return '5'; case 034: return '6'; case 023: return '7'; case 035: return '8'; case 037: return '9'; } return ' '; // error } void DSP::decodeRelayWord(unsigned in) { unsigned charSelect = (in & 074000) >> 11; // get bits 15-12 unsigned b11 = (in & 02000) >> 10; // get bit 11 unsigned bHigh = (in & 01740) >> 5; // get bits 10-6 unsigned bLow = in & 037; //****************************** #ifdef NOTDEF char buf[80]; sprintf(buf, "bits15-12: %02o, Bit11: %01o, bits10-6: %02o, bits5-1: %02o", charSelect, b11, bHigh, bLow); cout << buf << endl; #endif dskyChanged = true; //****************************** switch(charSelect) { case 013: MD1 = outConv(bHigh); MD2 = outConv(bLow); break; case 012: VD1 = outConv(bHigh); VD2 = outConv(bLow); flash = b11; break; case 011: ND1 = outConv(bHigh); ND2 = outConv(bLow); break; case 010: R1D1 = outConv(bLow); break; // UPACT not implemented case 007: R1SP = b11; R1S = signConv(R1SP, R1SM); R1D2 = outConv(bHigh); R1D3 = outConv(bLow); break; R1SM = b11; R1S = signConv(R1SP, R1SM); R1D4 = outConv(bHigh); R1D5 = outConv(bLow); break; R2SP = b11; R2S = signConv(R2SP, R2SM); R2D1 = outConv(bHigh); R2D2 = outConv(bLow); break;
case 006:
case 005:
case 004:
R2SM = b11; R2S = signConv(R2SP, R2SM); R2D3 = outConv(bHigh); R2D4 = outConv(bLow); break; R2D5 = outConv(bHigh); R3D1 = outConv(bLow); break; R3SP = b11; R3S = signConv(R3SP, R3SM); R3D2 = outConv(bHigh); R3D3 = outConv(bLow); break; R3SM = b11; R3S = signConv(R3SP, R3SM); R3D4 = outConv(bHigh); R3D5 = outConv(bLow); break;
case 001: } }
INP (INP.h)
/**************************************************************************** * INP - INPUT REGISTER subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: INP.h * * VERSIONS: * * DESCRIPTION: * Input Registers for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef INP_H #define INP_H #include "reg.h" class regIn0 : public reg { public: regIn0() : reg(16, "%06o") { } }; class regIn1 : public reg { public: regIn1() : reg(16, "%06o") { } }; class regIn2 : public reg { public: regIn2() : reg(16, "%06o") { } }; class regIn3 : public reg { public: regIn3() : reg(16, "%06o") { } }; class INP { public: static static static static static static static static }; #endif
void execRP_RA4(); void execRP_RA5(); void execRP_RA6(); void execRP_RA7(); regIn0 register_IN0; regIn1 register_IN1; regIn2 register_IN2; regIn3 register_IN3;
// // // //
0 1 2 3
INP (INP.cpp)
/**************************************************************************** * INP - INPUT REGISTER subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: INP.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "INP.h" #include "SEQ.h" #include "KBD.h" #include "MON.h" #include "BUS.h" regIn0 regIn1 regIn2 regIn3 INP::register_IN0; INP::register_IN1; INP::register_IN2; INP::register_IN3; // // // // input input input input register register register register 0 1 2 3
void INP::execRP_RA4() { // Sample the state of the inputs at the moment the // read pulse is asserted. In the H/W implementation, // register 0 is a buffer, not a latch. register_IN0.writeField(5,1,KBD::kbd); register_IN0.writeField(6,6,0); // actually should be keypressed strobe register_IN0.writeField(14,14,MON::SA); register_IN0.clk(); BUS::glbl_READ_BUS = register_IN0.read(); }
void INP::execRP_RA5() { BUS::glbl_READ_BUS = register_IN1.read(); } void INP::execRP_RA6() { BUS::glbl_READ_BUS = register_IN2.read(); } void INP::execRP_RA7() { BUS::glbl_READ_BUS = register_IN3.read(); }
INT (INT.h)
/**************************************************************************** * INT - PRIORITY INTERRUPT subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: INT.h * * VERSIONS: * * DESCRIPTION: * Priority Interrupts for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef INT_H #define INT_H #include "reg.h" enum ruptAddress { // Addresses for service routines of vectored interrupts T3RUPT_ADDR =02004, // option 1: overflow of TIME 3 ERRUPT_ADDR =02010, // option 2: error signal DSRUPT_ADDR =02014, // option 3: telemetry end pulse or TIME 4 overflow KEYRUPT_ADDR =02020, // option 4: activity from MARK, keyboard, or tape reader }; enum ruptNumber { // Option number (selects rupt priority cell) // NOTE: the priority cells (rupt[]) are indexed 0-4, but stored in the // RPCELL register as 1-5; (0 in RPCELL means no interrupt) T3RUPT =0, // option 1: overflow of TIME 3 ERRUPT =1, // option 2: error signal DSRUPT =2, // option 3: telemetry end pulse or TIME 4 overflow KEYRUPT =3, // option 4: activity from MARK, keyboard, or tape reader }; class regRPCELL : public reg { public: regRPCELL() : reg(5, "%02o") { } }; // also inhibits additional interrupts while an interrupt is being processed class regINHINT1 : public reg { public: regINHINT1() : reg(1, "%01o") { } }; class regINHINT : public reg { public: regINHINT() : reg(1, "%01o") { } }; class INT { public: friend class CLK; friend class MON; static void execRP_RRPA();
static bool IRQ(); // returns true if an interrupt is requested static unsigned rupt[]; private: static void resetAllRupt(); static unsigned getPriorityRupt(); static regRPCELL register_RPCELL; // latches the selected priority interrupt vector (1-5) static regINHINT1 register_INHINT1; // inhibits interrupts for 1 instruction (on WOVI) static regINHINT register_INHINT; // inhibits interrupts on INHINT, reenables on RELINT }; #endif
INT (INT.cpp)
/**************************************************************************** * INT - PRIORITY INTERRUPT subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: INT.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "INT.h" #include "SEQ.h" #include "BUS.h" regRPCELL INT::register_RPCELL; // latches the selected priority interrupt vector (1-5) regINHINT1 INT::register_INHINT1; // inhibits interrupts for 1 instruction (on WOVI) regINHINT INT::register_INHINT; // inhibits interrupts on INHINT, reenables on RELINT // NOTE: the priority cells (rupt[]) are indexed 0-4, but stored in the // RPCELL register as 1-5; (0 in RPCELL means no interrupt) unsigned INT::rupt[5];
bool INT::IRQ() { if( INT::getPriorityRupt() // if interrupt requested && INT::register_RPCELL.read() == 0 // and interrupt not currently being serviced && INT::register_INHINT1.read() == 0 // and interrupt not inhibited for 1 instruction && INT::register_INHINT.read() == 0) // and interrupts enabled (RELINT) { return true; } return false; } void INT::resetAllRupt() { for(int i=0; i<5; i++) { rupt[i]=0; } } // interrupt vector; outputs 1-5 (decimal) == vector; 0 == no interrupt unsigned INT::getPriorityRupt() { for(int i=0; i<5; i++) { if(rupt[i]) return i+1; } return 0; } void INT::execRP_RRPA() { BUS::glbl_READ_BUS = 02000 + (register_RPCELL.read() << 2); }
// latches the selected priority interrupt vector (1-5) // also inhibits additional interrupts while an interrupt is being processed void INT::execWP_GENRST() { register_RPCELL.write(0); register_INHINT.write(1); resetAllRupt(); } void INT::execWP_RPT() {
register_RPCELL.write(INT::getPriorityRupt()); } void INT::execWP_KRPT() { INT::rupt[register_RPCELL.read()-1] = 0; } void INT::execWP_CLRP() { register_RPCELL.write(0); } // INHINT1: inhibits interrupts for 1 instruction (on WOVI) void INT::execWP_WOVI() { if(BUS::testOverflow(BUS::glbl_WRITE_BUS) != NO_OVF) register_INHINT1.write(1); } void INT::execWP_CLINH1() { register_INHINT1.write(0); } // INHINT: inhibits interrupts on INHINT, reenables on RELINT void INT::execWP_INH() { register_INHINT.write(1); } void INT::execWP_CLINH() { register_INHINT.write(0); }
ISD (ISD.h)
/**************************************************************************** * ISD - INSTRUCTION SUBSEQUENCE DECODER subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: ISD.h * * VERSIONS: * * DESCRIPTION: * Instruction Subsequence Decoder for the Block 1 Apollo Guidance Computer * prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef ISD_H #define ISD_H #include "SEQ.h" #include "CTR.h" // INSTRUCTION SUBSEQUENCE DECODER
#ifdef NOTDEF class ISD { public: static subseq instructionSubsequenceDecoder(); static char* ISD::subseqString[]; }; #endif #endif
ISD (ISD.cpp)
/**************************************************************************** * ISD - INSTRUCTION SUBSEQUENCE DECODER subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: ISD.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "ISD.h" #ifdef NOTDEF char* ISD::subseqString[] = { "TC0", "CCS0", "CCS1", "NDX0", "NDX1", "RSM3", "XCH0", "CS0", "TS0", "AD0", "MASK0", "MP0", "MP1", "MP3", "DV0", "DV1", "SU0", "RUPT1", "RUPT3", "STD2", "PINC0", "MINC0", "SHINC0", "NO_SEQ" }; subseq ISD::instructionSubsequenceDecoder() { // Combinational logic decodes instruction and the stage count // to get the instruction subsequence. static subseq decode[16][4] = { { TC0, RUPT1, STD2, RUPT3 }, // 00 { CCS0, CCS1, NO_SEQ, NO_SEQ }, // 01 { NDX0, NDX1, NO_SEQ, RSM3 }, // 02 { XCH0, NO_SEQ, STD2, NO_SEQ }, // 03 { { { { { { { { { { { { }; switch(CTR::getSubseq()) { case PINCSEL: return PINC0; NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, MP0, DV0, SU0, CS0, TS0, AD0, MASK0, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, MP1, DV1, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, NO_SEQ, STD2, STD2, STD2, STD2, STD2, STD2, NO_SEQ NO_SEQ NO_SEQ NO_SEQ NO_SEQ }, }, }, }, }, // // // // // 04 05 06 07 10
KBD (KBD.h)
/**************************************************************************** * KBD - DSKY KEYBOARD subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: KBD.h * * VERSIONS: * * DESCRIPTION: * DSKY Keyboard for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef KBD_H #define KBD_H
enum keyInType { // DSKY keyboard input codes: Taken from E-1574, Appendix 1 // These codes enter the computer through bits 1-5 of IN0. // The MSB is in bit 5; LSB in bit 1. Key entry generates KEYRUPT. KEYIN_NONE =0, // no key depressed** KEYIN_0 =020, KEYIN_1 =001, KEYIN_2 =002, KEYIN_3 =003, KEYIN_4 =004, KEYIN_5 =005, KEYIN_6 =006, KEYIN_7 =007, KEYIN_8 =010, KEYIN_9 =011, KEYIN_VERB =021, KEYIN_ERROR_RESET =022, KEYIN_KEY_RELEASE =031, KEYIN_PLUS =032, KEYIN_MINUS =033, KEYIN_ENTER =034, KEYIN_CLEAR =036, KEYIN_NOUN =037, }; class KBD { public: static keyInType kbd; // latches the last key entry from the DSKY static void keypress(keyInType c); }; #endif
KBD (KBD.cpp)
/**************************************************************************** * KBD - DSKY KEYBOARD subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: KBD.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "KBD.h" #include "INT.h" // DSKY keyboard keyInType KBD::kbd=KEYIN_NONE;
void KBD::keypress(keyInType c) { // latch the keycode kbd = c; // generate KEYRUPT interrupt INT::rupt[KEYRUPT] = 1; }
MBF (MBF.h)
/**************************************************************************** * MBF - MEMORY BUFFER REGISTER subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: MBF.h * * VERSIONS: * * DESCRIPTION: * Memory Buffer Register for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef MBF_H #define MBF_H #include "reg.h" class regG : public reg { public: // all memory bits except bit 15 (parity) // bit 15 is not used, so ignore it. regG() : reg(16, "%06o") { } };
class MBF { public: static void execWP_GENRST(); static void execRP_RG(); static void execRP_WE(); static static static static static static static void void void void void void void execWP_WGn(); execWP_WGx(); execWP_W20(); execWP_W21(); execWP_W22(); execWP_W23(); execWP_SBWG();
// Bit 15 (parity) is kept in a separate register in PAR // because it is independently loaded. static regG register_G; // memory buffer register (except for bit 15) static static static static static static static static }; #endif unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned conv_RG[]; conv_WGn[]; conv_W20[]; conv_W21[]; conv_W22[]; conv_W23[]; conv_SBWG[]; conv_WE[];
MBF (MBF.cpp)
/**************************************************************************** * MBF - MEMORY BUFFER REGISTER subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: MBF.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "MBF.h" #include "SEQ.h" #include "ADR.h" #include "BUS.h" #include "PAR.h" #include "MEM.h" // The actual bit 15 of register_G is not used. regG MBF::register_G; // memory buffer register (except bit 15: parity) unsigned MBF::conv_RG[] = { SG, SG, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1 }; unsigned MBF::conv_SBWG[] = { SGM, BX, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1 }; unsigned MBF::conv_WE[] = { BX, SG, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1 }; unsigned MBF::conv_W20[] = { B1, BX, SG, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2 }; unsigned MBF::conv_W21[] = { SG, BX, SG, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2 }; unsigned MBF::conv_W22[] = { B14, BX, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, SG }; unsigned MBF::conv_W23[] = { SG, BX, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, SG };
void MBF::execRP_RG() { if(ADR::GTR_17()) { BUS::glbl_READ_BUS = register_G.shiftData(0, register_G.read(), MBF::conv_RG); } } void MBF::execRP_WE() { // Write G into memory; shift the sign to bit 15; parity is written from the // PAR subsystem MEM::MEM_DATA_BUS = (register_G.shiftData(0, MBF::register_G.read(), MBF::conv_WE)); }
void MBF::execWP_WGn() { register_G.write(BUS::glbl_WRITE_BUS); } void MBF::execWP_WGx() { // This is only used in PINC, MINC, and SHINC. Does not clear G // register; writes (ORs) into G from RWBus and writes into parity // from 1-15 generator. The sequence calls CLG in a previous TP to // reset G to zero, so the OR operation can be safely eliminated // from my implementation of the design. register_G.write(BUS::glbl_WRITE_BUS); } void MBF::execWP_W20() { register_G.writeShift(BUS::glbl_WRITE_BUS, MBF::conv_W20); } void MBF::execWP_W21() { register_G.writeShift(BUS::glbl_WRITE_BUS, MBF::conv_W21); } void MBF::execWP_W22() { register_G.writeShift(BUS::glbl_WRITE_BUS, MBF::conv_W22); } void MBF::execWP_W23() { register_G.writeShift(BUS::glbl_WRITE_BUS, MBF::conv_W23); } void MBF::execWP_SBWG() { register_G.writeShift(MEM::MEM_DATA_BUS, MBF::conv_SBWG); }
MEM (MEM.h)
/**************************************************************************** * MEM - ERASEABLE/FIXED MEMORY subsystem * * AUTHOR: John Pultorak * DATE: 9/26/02 * FILE: MEM.h * * VERSIONS: * * DESCRIPTION: * Eraseable & Fixed Memory for the Block 1 Apollo Guidance Computer * prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef MEM_H #define MEM_H #include "reg.h" #define NUMFBANK 12 // number of 1024 word fixed memory banks
class regEMEM : public reg { public: regEMEM() : reg(16, "%06o") { } regEMEM& operator= (const unsigned& r) { write(r); return *this; } }; class regFMEM : public reg { public: regFMEM() : reg(16, "%06o") { } regFMEM& operator= (const unsigned& r) { write(r); return *this; } }; class MEM { public: static void execWP_WE(); static void execRP_SBWG(); static regEMEM register_EMEM[]; // erasable memory static regFMEM register_FMEM[]; // fixed memory static unsigned MEM_DATA_BUS; // data lines: memory bits 15-1 static unsigned MEM_PARITY_BUS; // parity line: memory bit 16 static unsigned readMemory(); static void writeMemory(unsigned data); // The following functions are used in the simulator, // but are implemented in the AGC design. static unsigned readMemory(unsigned address); static void writeMemory(unsigned address, unsigned data); }; #endif
MEM (MEM.cpp)
/**************************************************************************** * MEM - ERASEABLE/FIXED MEMORY subsystem * * AUTHOR: John Pultorak * DATE: 9/26/02 * FILE: MEM.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "MEM.h" #include "ADR.h" #include "stdlib.h" regEMEM MEM::register_EMEM[1024]; // erasable memory regFMEM MEM::register_FMEM[1024*(NUMFBANK+1)]; // fixed memory (lowest 1024 words ignored) unsigned MEM::MEM_DATA_BUS = 0; unsigned MEM::MEM_PARITY_BUS = 0; // data lines: memory bits 15-1 // parity line: memory bit 16
void MEM::execWP_WE() { // Write into memory; parity bit in bit 16 writeMemory( (MEM_PARITY_BUS << 15) | MEM_DATA_BUS ); } void MEM::execRP_SBWG() { MEM_DATA_BUS = readMemory() & 0077777; // everything except parity MEM_PARITY_BUS = (readMemory() & 0100000) >> 15; // parity bit only } unsigned MEM::readMemory() { // Return memory value addressed by lower 10 bits of the S register (1K) and the // bank decoder (which selects the 1K bank) unsigned lowAddress = ADR::register_S.readField(10,1); if(ADR::bankDecoder() == 0) return MEM::register_EMEM[lowAddress].read(); unsigned highAddress = ADR::bankDecoder() << 10; return MEM::register_FMEM[highAddress | lowAddress].read(); } void MEM::writeMemory(unsigned data) { // Write into erasable memory addressed by lower 10 bits of the S register (1K) // and the bank decoder (which selects the 1K bank) unsigned lowAddress = ADR::register_S.readField(10,1); if(ADR::bankDecoder() == 0) { MEM::register_EMEM[lowAddress].write(data); MEM::register_EMEM[lowAddress].clk(); // not a synchronous FF, so execute immediately ************* } } unsigned MEM::readMemory(unsigned address) { // Address is 14 bits. This function is used by the simulator for examining // memory; it is not part of the AGC design. unsigned lowAddress = address & 01777; unsigned bank = (address & 036000) >> 10; if(bank == 0) return MEM::register_EMEM[lowAddress].read();
unsigned highAddress = bank << 10; return MEM::register_FMEM[highAddress | lowAddress].read(); } void MEM::writeMemory(unsigned address, unsigned data) { // Address is 14 bits. This function is used by the simulator for depositing into // memory; it is not part of the AGC design. This function is also used to // initialize fixed memory. //************************************************************ // This function could also write the parity into memory //************************************************************ unsigned lowAddress = address & 01777; unsigned bank = (address & 036000) >> 10; if(bank == 0) { if(lowAddress > 1024) { cout << "Error: Eraseable address=" << lowAddress << endl; exit(0); } MEM::register_EMEM[lowAddress].write(data); MEM::register_EMEM[lowAddress].clk(); // execute immediately } else { unsigned highAddress = bank << 10; if((highAddress | lowAddress) >= 1024*(NUMFBANK+1)) { cout << "Error: Fixed address=" << (highAddress | lowAddress) << endl; exit(0); } MEM::register_FMEM[highAddress | lowAddress].write(data); MEM::register_FMEM[highAddress | lowAddress].clk(); // execute immediately } }
MON (MON.h)
/**************************************************************************** * MON - AGC MONITOR subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: MON.h * * VERSIONS: * * DESCRIPTION: * AGC Monitor for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef MON_H #define MON_H class MON { public: static void displayAGC(); static char* MON::clkTypestring[]; static static static static static unsigned unsigned unsigned unsigned unsigned PURST; RUN; STEP; INST; FCLK; SA; // // // // // power up reset run/halt switch single step switch instruction/sequence step select switch clock mode (0=single (manual) clock, 1=continuous clock)
// "standby allowed" SW; // 0=NO (full power), 1=YES (low power) // "scaler enabled" SW; 0=NO (scaler halted), 1=YES (scaler running)
SCL_ENAB;
MON (MON.cpp)
/**************************************************************************** * MON - AGC MONITOR subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: MON.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "MON.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include unsigned unsigned unsigned unsigned unsigned "TPG.h" "MON.h" "SCL.h" "SEQ.h" "INP.h" "OUT.h" "BUS.h" "DSP.h" "ADR.h" "PAR.h" "MBF.h" "MEM.h" "CTR.h" "INT.h" "KBD.h" "CRG.h" "ALU.h" "CPM.h" "ISD.h" "CLK.h" MON::PURST=1; MON::RUN=0; MON::STEP=0; MON::INST=1; MON::FCLK=0; // // // // // power up reset; initially high at startup run/halt switch single step switch instruction/sequence step select switch clock mode
// "standby allowed" SW; 0=NO (full power), 1=YES (low power) // "scaler enabled" SW; 0=NO (scaler halted), 1=YES (scaler
void MON::displayAGC() { char buf[100]; cout << "AGC4 SIMULATOR 1.16 -------------------------------" << endl; sprintf(buf," TP: %-5s F17:%1d F13:%1d F10:%1d SCL:%06o", TPG::tpTypestring[TPG::register_SG.read()], SCL::register_F17.read(), SCL::register_F13.read(), SCL::register_F10.read(), SCL::register_SCL.read()); cout << buf << endl; sprintf(buf, " STA:%01o STB:%01o BR1:%01o BR2:%01o SNI:%01o CI:%01o LOOPCTR:%01o", SEQ::register_STA.read(), SEQ::register_STB.read(), SEQ::register_BR1.read(), SEQ::register_BR2.read(), SEQ::register_SNI.read(), ALU::register_CI.read(), SEQ::register_LOOPCTR.read()); cout << buf << endl; sprintf(buf, " RPCELL:%05o %-6s", INT::register_RPCELL.read(), INT::register_INHINT1.read(), INT::register_INHINT.read(), CTR::register_UpCELL.read(), CTR::register_DnCELL.read(), SEQ::register_SQ.read(), SEQ::instructionString[SEQ::register_SQ.read()], CPM::subseqString[SEQ::glbl_subseq]); cout << buf << endl; sprintf(buf, " CP:%s", SEQ::getControlPulses()); cout << buf << endl; INH1:%01o INH:%01o UpCELL:%03o DnCELL:%03o SQ:%02o %-6s
// For the G register, bit 15 comes from register G15; the other bits (16, 14-1) come // from register G. sprintf(buf, " S: %04o G:%06o P:%06o (r)RUN :%1d (p)PURST:%1d (F2,F4)FCLK:%1d", ADR::register_S.read(), (MBF::register_G.read() & 0137777) | (PAR::register_G15.read() << 14), PAR::register_P.read(), MON::RUN, MON::PURST, MON::FCLK); cout << buf << endl; sprintf(buf, " RBU:%06o WBU:%06o P2:%01o (s)STEP:%1d", BUS::glbl_READ_BUS & 0177777, BUS::glbl_WRITE_BUS & 0177777, PAR::register_P2.read(), MON::STEP); cout << buf << endl; char parityAlm = ' '; if(PAR::register_PALM.read()) parityAlm = '*'; sprintf(buf, " B:%06o CADR:%06o (n)INST:%1d PALM:[%c]", ALU::register_B.read(), ADR::getEffectiveAddress(), MON::INST, parityAlm); cout << buf << endl; sprintf(buf, " X:%06o Y:%06o U:%06o (a)SA :%1d", ALU::register_X.read(), ALU::register_Y.read(), ALU::register_U.read(), MON::SA); cout << buf << endl; cout << endl; sprintf(buf, "00 A:%06o 15 BANK:%02o 36 TIME1:%06o 53 OPT Y:%06o", CRG::register_A.read(), ADR::register_BNK.read(), MEM::readMemory(036), MEM::readMemory(053)); cout << buf << endl; sprintf(buf, "01 Q:%06o 16 RELINT:%6s 37 TIME3:%06o 54 TRKR X:%06o", CRG::register_Q.read(),"", MEM::readMemory(037), MEM::readMemory(054)); cout << buf << endl; sprintf(buf, "02 Z:%06o 17 INHINT:%6s 40 TIME4:%06o 55 TRKR Y:%06o", CRG::register_Z.read(),"", MEM::readMemory(040), MEM::readMemory(055)); cout << buf << endl; sprintf(buf, "03 LP:%06o 20 CYR:%06o 41 UPLINK:%06o 56 TRKR Z:%06o", CRG::register_LP.read(), MEM::readMemory(020), MEM::readMemory(041), MEM::readMemory(056)); cout << buf << endl; sprintf(buf, "04 IN0:%06o 21 SR:%06o 42 OUTCR1:%06o", INP::register_IN0.read(), MEM::readMemory(021), MEM::readMemory(042)); cout << buf << endl; char progAlm = ' '; if(OUT::register_OUT1.read() & 0400) progAlm = '*'; char compFail = ' '; // also called 'check fail' and 'oper err' if(OUT::register_OUT1.read() & 0100) compFail = '*'; char keyRels = ' '; if(OUT::register_OUT1.read() & 020) keyRels = '*'; char upTl = ' '; if(OUT::register_OUT1.read() & 004) upTl = '*'; char comp = ' '; // also called comp acty if(OUT::register_OUT1.read() & 001) comp = '*'; sprintf(buf, "05 IN1:%06o 22 CYL:%06o 43 OUTCR2:%06o CF:[%c%c]:KR [%c]:PA", INP::register_IN1.read(), MEM::readMemory(022), MEM::readMemory(043), compFail, keyRels, progAlm); cout << buf << endl; sprintf(buf, "06 IN2:%06o 23 SL:%06o 44 PIPA X:%06o", INP::register_IN2.read(), MEM::readMemory(023), MEM::readMemory(044)); cout << buf << endl; sprintf(buf, "07 IN3:%06o 24 ZRUPT:%06o 45 PIPA Y:%06o A:[%c%c] M:[%c%c]", INP::register_IN3.read(), MEM::readMemory(024), MEM::readMemory(045),
upTl, comp, DSP::MD1, DSP::MD2); cout << buf << endl; char fc = ' '; if(DSP::flash) fc = '*'; sprintf(buf, "10 OUT0: 25 BRUPT:%06o 46 PIPA Z:%06o V:[%c%c] N:[%c%c] %c", MEM::readMemory(025), MEM::readMemory(046), DSP::VD1, DSP::VD2, DSP::ND1, DSP::ND2, fc); cout << buf << endl; sprintf(buf, "11 OUT1:%06o 26 ARUPT:%06o 47 CDU X:%06o R1:[ %c%c%c%c%c%c ]", OUT::register_OUT1.read(), MEM::readMemory(026), MEM::readMemory(047), DSP::R1S, DSP::R1D1, DSP::R1D2, DSP::R1D3, DSP::R1D4, DSP::R1D5); cout << buf << endl; sprintf(buf, "12 OUT2:%06o 27 QRUPT:%06o 50 CDU Y:%06o R2:[ %c%c%c%c%c%c ]", OUT::register_OUT2.read(), MEM::readMemory(027), MEM::readMemory(050), DSP::R2S, DSP::R2D1, DSP::R2D2, DSP::R2D3, DSP::R2D4, DSP::R2D5); cout << buf << endl; sprintf(buf, "13 OUT3:%06o 34 OVCTR:%06o 51 CDU Z:%06o R3:[ %c%c%c%c%c%c ]", OUT::register_OUT3.read(), MEM::readMemory(034), MEM::readMemory(051), DSP::R3S, DSP::R3D1, DSP::R3D2, DSP::R3D3, DSP::R3D4, DSP::R3D5); cout << buf << endl; sprintf(buf, "14 OUT4:%06o 35 TIME2:%06o 52 OPT X:%06o", OUT::register_OUT4.read(), MEM::readMemory(035), MEM::readMemory(052)); cout << buf << endl; }
OUT (OUT.h)
/**************************************************************************** * OUT - OUTPUT REGISTER subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: OUT.h * * VERSIONS: * * DESCRIPTION: * Output Registers for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef OUT_H #define OUT_H #include "reg.h" class regOut1 : public reg { public: regOut1() : reg(16, "%06o") { } }; class regOut2 : public reg { public: regOut2() : reg(16, "%06o") { } }; class regOut3 : public reg { public: regOut3() : reg(16, "%06o") { } }; class regOut4 : public reg { public: regOut4() : reg(16, "%06o") { } }; class OUT { public: static static static static static static static static static static static static static static }; #endif
void void void void void void void void void void
execWP_GENRST(); execWP_WA10(); execRP_RA11(); execWP_WA11(); execRP_RA12(); execWP_WA12(); execRP_RA13(); execWP_WA13(); execRP_RA14(); execWP_WA14(); register_OUT1; register_OUT2; register_OUT3; register_OUT4; // // // // output output output output register register register register 1 2 3 4
OUT (OUT.cpp)
/**************************************************************************** * OUT - OUTPUT REGISTER subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: OUT.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "OUT.h" #include "SEQ.h" #include "BUS.h" #include "DSP.h" #include "ADR.h" #include "PAR.h" #include <stdlib.h> regOut1 regOut2 regOut3 regOut4 OUT::register_OUT1; OUT::register_OUT2; OUT::register_OUT3; OUT::register_OUT4; // // // // output output output output register register register register 1 2 3 4
PAR (PAR.h)
/**************************************************************************** * PAR - PARITY GENERATION AND TEST subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: PAR.h * * VERSIONS: * * DESCRIPTION: * Parity Generation and Test for the Block 1 Apollo Guidance Computer * prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef PAR_H #define PAR_H #include "reg.h" class regG15 : public reg { public: // memory buffer register bit 15 (parity) only regG15() : reg(1, "%01o") { } }; class regP : public reg { public: regP() : reg(16, "%06o") { } }; class regP2 : public reg { public: regP2() : reg(1, "%01o") { } }; class regPALM : public reg { public: // parity alarm FF (set on TP) regPALM() : reg(1, "%01o") { } }; class PAR { public: static void execRP_WE(); static static static static static static static static void void void void void void void void execWP_WP(); execWP_WPx(); execWP_WP2(); execWP_RP2(); execWP_GP(); execWP_SBWG(); execWP_WGx(); execWP_CLG();
static void execWP_TP(); static void CLR_PALM(); // asynchronous clear for PARITY ALARM
// memory buffer register bit 15; the rest of the // memory buffer register is defined in MBF static regG15 register_G15; static regP2 register_P2; static regP register_P; static regPALM register_PALM; static unsigned gen1_15Parity(unsigned r); static unsigned genP_15Parity(unsigned r); static unsigned conv_WP[]; }; #endif
PAR (PAR.cpp)
/**************************************************************************** * PAR - PARITY GENERATION AND TEST subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: PAR.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "PAR.h" #include "SEQ.h" #include "BUS.h" #include "MBF.h" #include "ADR.h" #include "MEM.h" regP PAR::register_P; regP2 PAR::register_P2; regG15 PAR::register_G15; // memory buffer register bit 15 regPALM PAR::register_PALM; // PARITY ALARM FF unsigned PAR::conv_WP[] = { BX, SG, B14, B13, B12, B11, B10, B9, B8, B7, B6, B5, B4, B3, B2, B1 };
// IMPLEMENTATION NOTE: It has been empirically determined that the following // control signals are mutually exclusive (there is never more than one of these // generated at any time): // GP, WGX, RP2, SBWG, CLG // // // // NOTE: WP clears register_P before writing into it. Strictly speaking, WPx isn't supposed to clear the register (should OR into the register), but in the counter sequences where WPx is used, register_P is always cleared in the previous TP by asserting WP with default zeroes on the write bus.
void PAR::execWP_WP() { // set all bits except parity bit register_P.writeShift(BUS::glbl_WRITE_BUS, PAR::conv_WP); // now set parity bit; in the actual AGC, this is // a single operation. if(SEQ::isAsserted(RG)) register_P.writeField(16, 16, register_G15.read()); else register_P.writeField(16, 16, 0); // clear parity bit } void PAR::execWP_WPx() { // set all bits except parity bit register_P.writeShift(BUS::glbl_WRITE_BUS, PAR::conv_WP); // now set parity bit; in the actual AGC, this is // a single operation. if(SEQ::isAsserted(RG)) register_P.writeField(16, 16, register_G15.read()); else
register_P.writeField(16, 16, 0); // clear parity bit } void PAR::execWP_WP2() { register_P2.write(gen1_15Parity(register_P.read())); } void PAR::execWP_RP2() { register_G15.write(register_P2.read()); } void PAR::execWP_GP() { register_G15.write(gen1_15Parity(register_P.read())); } void PAR::execWP_SBWG() { register_G15.write(MEM::MEM_PARITY_BUS); // load memory bit 16 (parity) into G15 } void PAR::execWP_WGx() { // This is only used in PINC, MINC, and SHINC. Does not clear G // register; writes (ORs) into G from RWBus and writes into parity // from 1-15 generator. All done in one operation, although I show // it in two steps here. The sequence calls CLG in a previous TP. register_G15.write(PAR::gen1_15Parity(register_P.read())); } void PAR::execWP_CLG() { register_G15.write(0); } void PAR::execWP_GENRST() { register_PALM.write(0); } void PAR::execWP_TP() { if(ADR::GTR_27() && genP_15Parity(register_P.read())) register_PALM.write(genP_15Parity(register_P.read())); } void PAR::CLR_PALM() { // asynchronous clear for PARITY ALARM (from MON) register_PALM.clear(); } unsigned PAR::gen1_15Parity(unsigned r) { //check the lower 15 bits of 'r' and return the odd parity; //bit 16 is ignored. unsigned evenParity = (1&(r>>0)) ^ (1&(r>>1)) ^ (1&(r>>2)) ^ (1&(r>>3)) ^ (1&(r>>4)) ^ (1&(r>>5)) ^ (1&(r>>6)) ^ (1&(r>>7)) ^ (1&(r>>8)) ^ (1&(r>>9)) ^ (1&(r>>10)) ^ (1&(r>>11)) ^ (1&(r>>12)) ^ (1&(r>>13)) ^ (1&(r>>14)); return ~evenParity & 1; // odd parity } unsigned PAR::genP_15Parity(unsigned r) { //check all 16 bits of 'r' and return the odd parity unsigned evenParity = (1&(r>>0)) ^ (1&(r>>1)) ^ (1&(r>>2)) ^ (1&(r>>3)) ^ (1&(r>>4)) ^ (1&(r>>5)) ^ (1&(r>>6)) ^ (1&(r>>7)) ^ (1&(r>>8)) ^ (1&(r>>9)) ^ (1&(r>>10)) ^ (1&(r>>11)) ^
Registers (reg.h)
#ifndef reg_H #define reg_H #include <iostream.h> #include <string.h> #include <stdio.h> class reg { public: virtual unsigned read() { return mask & slaveVal; } virtual void write(unsigned v) { load = true; masterVal = mask & v; } // asynchronous clear void clear() { slaveVal = 0; } // load is set when a register is written into. void clk() { if(load) slaveVal = masterVal; load = false; } unsigned readField(unsigned msb, unsigned lsb); // bitfield numbered n - 1 void writeField(unsigned msb, unsigned lsb, unsigned v); // bitfield numbered n - 1 // Write a 16-bit word (in) into the register. Transpose the bits according to // the specification (ib). void writeShift(unsigned in, unsigned* ib); // Return a shifted 16-bit word. Transpose the 'in' bits according to // the specification 'ib'. 'Or' the result to out and return the value. unsigned shiftData(unsigned out, unsigned in, unsigned* ib); unsigned outmask() { return mask; } protected: reg(unsigned s, char* fs) : size(s), mask(0), masterVal(0), slaveVal(0), fmtString(fs), load(false) { mask = buildMask(size);} static unsigned buildMask(unsigned s); friend ostream& operator << (ostream& os, const reg& r) { char buf[32]; sprintf(buf, r.fmtString, r.slaveVal); os << buf; return os; } private: unsigned unsigned unsigned unsigned char* bool }; #endif
Registers (reg.cpp)
#include "reg.h" #include <math.h> #include "BUS.h" unsigned reg::buildMask(unsigned s) { unsigned msk = 0; for(unsigned i=0; i<s; i++) { msk = (msk << 1) | 1; } return msk; } unsigned reg::readField(unsigned msb, unsigned lsb) { return (slaveVal >> (lsb-1)) & buildMask((msb-lsb)+1); } void reg::writeField(unsigned msb, unsigned lsb, unsigned v) { load = true; unsigned fmask = buildMask((msb-lsb)+1) << (lsb-1); v = (v << (lsb-1)) & fmask; masterVal = (masterVal &(~fmask)) | v; } void reg::writeShift(unsigned in, unsigned* ib) { load = true; unsigned out = masterVal; // iterate through each bit of the output word, copying in bits from the input // word and transposing bit position according to the specification (ib) for(unsigned i=0; i<16; i++) { if(ib[i] == BX) continue; // BX is 'don't care', so leave it alone // zero the output bit at 'ob', where ob specifies a bit // position (numbered 16-1, where 1 is lsb) unsigned ob = 16-i; unsigned obmask = 1 << (ob - 1); // create mask for output bit out &= ~obmask; if(ib[i] == D0) continue; // D0 is 'force the bit to zero' // copy input bit ib[i] to output bit 'ob', where ib and ob // specify bit positions (numbered 16-1, where 1 is lsb) unsigned ibmask = 1 << (ib[i] - 1); // create mask for input bit unsigned inbit = in & ibmask; int shift = ib[i]-ob; if(shift<0) inbit = inbit << abs(shift); else if(shift > 0) inbit = inbit >> shift; out |= inbit; } masterVal = out; } unsigned reg::shiftData(unsigned out, unsigned in, unsigned* ib) { // iterate through each bit of the output word, copying in bits from the input // word and transposing bit position according to the specification (ib) for(unsigned i=0; i<16; i++) { if(ib[i] == BX) continue; // BX is 'don't care', so leave it alone // zero the output bit at 'ob', where ob specifies a bit // position (numbered 16-1, where 1 is lsb) unsigned ob = 16-i;
unsigned obmask = 1 << (ob - 1); // create mask for output bit out &= ~obmask; if(ib[i] == D0) continue; // D0 is 'force the bit to zero' // copy input bit ib[i] to output bit 'ob', where ib and ob // specify bit positions (numbered 16-1, where 1 is lsb) unsigned ibmask = 1 << (ib[i] - 1); // create mask for input bit unsigned inbit = in & ibmask; int shift = ib[i]-ob; if(shift<0) inbit = inbit << abs(shift); else if(shift > 0) inbit = inbit >> shift; out |= inbit; } return out; }
SCL (SCL.h)
/**************************************************************************** * SCL - SCALER subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: SCL.h * * VERSIONS: * * DESCRIPTION: * Scaler for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef SCL_H #define SCL_H #include "reg.h" class regF17 : public reg { public: regF17() : reg(2, "%01o") { } }; class regF13 : public reg { public: regF13() : reg(2, "%01o") { } }; class regF10 : public reg { public: regF10() : reg(2, "%01o") { } }; class regSCL : public reg { public: regSCL() : reg(17, "%06o") { } }; class SCL { public: static static static static
static regSCL register_SCL; // Normally outputs '0'; outputs '1' for one // clock pulse at the indicated frequency. static unsigned F17x(); // 0.78125 Hz scaler output static unsigned F13x(); // 12.5 Hz scaler output static unsigned F10x(); // 100 Hz scaler output static regF17 register_F17; static regF13 register_F13; static regF10 register_F10; };
#endif
SCL (SCL.cpp)
/**************************************************************************** * SCL - SCALER subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: SCL.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "SCL.h" #include "CTR.h" #include "MON.h" regSCL regF17 regF13 regF10 SCL::register_SCL; SCL::register_F17; SCL::register_F13; SCL::register_F10;
enum oneShotType { // **inferred; not defined in orignal R393 AGC4 spec. WAIT_FOR_TRIGGER=0, OUTPUT_PULSE=1, // LSB (bit 1) is the output bit for the one-shot WAIT_FOR_RESET=2 };
void SCL::doexecWP_F17() { int bit = SCL::register_SCL.readField(17,17); switch(register_F17.read()) { case WAIT_FOR_TRIGGER: if(bit==1) register_F17.write(OUTPUT_PULSE); break; case OUTPUT_PULSE: register_F17.write(WAIT_FOR_RESET); break; case WAIT_FOR_RESET: if(bit==0) register_F17.write(WAIT_FOR_TRIGGER); break; default: ; } } void SCL::doexecWP_F13() { int bit = SCL::register_SCL.readField(13,13); switch(register_F13.read()) { case WAIT_FOR_TRIGGER: if(bit==1) register_F13.write(OUTPUT_PULSE); break; case OUTPUT_PULSE: register_F13.write(WAIT_FOR_RESET); break; case WAIT_FOR_RESET: if(bit==0) register_F13.write(WAIT_FOR_TRIGGER); break; default: ; } } void SCL::doexecWP_F10() { int bit = SCL::register_SCL.readField(10,10); switch(register_F10.read()) { case WAIT_FOR_TRIGGER: if(bit==1) register_F10.write(OUTPUT_PULSE); break; case OUTPUT_PULSE: register_F10.write(WAIT_FOR_RESET); CTR::pcUp[TIME1] = 1; CTR::pcUp[TIME3] = 1; CTR::pcUp[TIME4] = 1; break; case WAIT_FOR_RESET: if(bit==0) register_F10.write(WAIT_FOR_TRIGGER); break; default: ; } } unsigned SCL::F17x() { return register_F17.readField(1,1);
} unsigned SCL::F13x() { return register_F13.readField(1,1); } unsigned SCL::F10x() { return register_F10.readField(1,1); } void SCL::doexecWP_SCL() { if(MON::SCL_ENAB) // if the scaler is enabled { //write((read() + 1) % outmask()); register_SCL.write((register_SCL.read() + 1)); } }
SEQ (SEQ.h)
/**************************************************************************** * SEQ - SEQUENCE GENERATOR subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: SEQ.h * * VERSIONS: * * DESCRIPTION: * Sequence Generator for the Block 1 Apollo Guidance Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef SEQ_H #define SEQ_H #include "reg.h" #define MAXPULSES 15 #define MAX_IPULSES 5 // no more than 5 instruction-generated pulses active at any time enum cpType { // **inferred; not defined in orignal R393 AGC4 spec. NO_PULSE=0, // OUTPUTS FROM SUBSYSTEM A CI =1, // Carry in CLG =2, // Clear G CLCTR =3, // Clear loop counter CTR =4, // Loop counter GP =5, // Generate Parity KRPT =6, // Knock down Rupt priority NISQ =7, // New instruction to the SQ register RA =8, // Read A RB =9, // Read B RB14 =10, // Read bit 14 RC =11, // Read C RG =12, // Read G RLP =13, // Read LP RP2 =14, // Read parity 2 RQ =15, // Read Q RRPA =16, // Read RUPT address RSB =17, // Read sign bit RSCT =18, // Read selected counter address RU =19, // Read sum RZ =20, // Read Z R1 =21, // Read 1 R1C =22, // Read 1 complimented R2 =23, // Read 2 R22 =24, // Read 22 R24 =25, // Read 24 ST1 =26, // Stage 1 ST2 =27, // Stage 2 TMZ =28, // Test for minus zero TOV =29, // Test for overflow TP =30, // Test parity TRSM =31, // Test for resume TSGN =32, // Test sign TSGN2 =33, // Test sign 2 WA =34, // Write A WALP =35, // Write A and LP WB =36, // Write B WGx =37, // Write G (do not reset)
=38, =39, =40, =41, =42, =43, =44, =45, =46, =47, =48, =49, =50,
// // // // // // // // // // // // //
Write Write Write Write Write Write Write Write Write Write Write Write Write
LP overflow counter overflow RUPT inhibit overflow P P (do not reset) P2 Q S X Y Y (do not reset) Z
// OUTPUTS FROM SUBSYSTEM A; USED AS INPUTS TO SUBSYSTEM B ONLY; // NOT USED OUTSIDE CPM RSC =51, // Read special and central (output to B only, not outside CPM) WSC =52, // Write special and central (output to B only, not outside CPM) WG =53, // Write G (output to B only, not outside CPM) // OUTPUTS FROM SUBSYSTEM A; USED AS INPUTS TO SUBSYSTEM C ONLY; // NOT USED OUTSIDE CPM SDV1 =54, // Subsequence DV1 is currently active SMP1 =55, // Subsequence MP1 is currently active SRSM3 =56, // Subsequence RSM3 is currently active // EXTERNAL OUTPUTS FROM SUBSYSTEM B // RA0 =57, // Read register at address 0 (A) RA1 =58, // Read register at address 1 (Q) RA2 =59, // Read register at address 2 (Z) RA3 =60, // Read register at address 3 (LP) RA4 =61, // Read register at address 4 RA5 =62, // Read register at address 5 RA6 =63, // Read register at address 6 RA7 =64, // Read register at address 7 RA10 =65, // Read register at address 10 (octal) RA11 =66, // Read register at address 11 (octal) RA12 =67, // Read register at address 12 (octal) RA13 =68, // Read register at address 13 (octal) RA14 =69, // Read register at address 14 (octal) RBK =70, // Read BNK WA0 =71, // Write register at address 0 (A) WA1 =72, // Write register at address 1 (Q) WA2 =73, // Write register at address 2 (Z) WA3 =74, // Write register at address 3 (LP) WA10 =75, // Write register at address 10 (octal) WA11 =76, // Write register at address 11 (octal) WA12 =77, // Write register at address 12 (octal) WA13 =78, // Write register at address 13 (octal) WA14 =79, // Write register at address 14 (octal) WBK =80, // Write BNK WGn =81, // Write G (normal gates)** W20 =82, // Write into CYR W21 =83, // Write into SR W22 =84, // Write into CYL W23 =85, // Write into SL // THESE ARE THE LEFTOVERS -- THEY'RE PROBABLY USED IN SUBSYSTEM C // GENRST =86, // General Reset** CLINH =87, // Clear INHINT** CLINH1 =88, // Clear INHINT1** CLSTA =89, // Clear state counter A (STA)** CLSTB =90, // Clear state counter B (STB)** CLISQ =91, // Clear SNI** CLRP =92, // Clear RPCELL** INH =93, // Set INHINT** RPT =94, // Read RUPT opcode ** SBWG =95, // Write G from memory SETSTB =96, // Set the ST1 bit of STB WE =97, // Write E-MEM from G WPCTR =98, // Write PCTR (latch priority counter sequence)** WSQ =99, // Write SQ
WSTB R2000 };
=100, =101,
// INSTRUCTIONS // Op Codes, as they appear in the SQ register. enum instruction { // The code in the SQ register is the same as the op code for these // four instructions. TC =00, // 00 TC K Transfer Control 1 MCT CCS =01, // 01 CCS K Count, Compare, and Skip 2 MCT INDEX =02, // 02 INDEX K 2 MCT XCH =03, // 03 XCH K Exchange 2 MCT // The SQ register code is the op code + 010 (octal). This happens because all // of these instructions have bit 15 set (the sign (SG) bit) while in memory. When the // instruction is copied from memory to the memory buffer register (G) to register // B, the SG bit moves from bit 15 to bit 16 and the sign is copied back into bit // 15 (US). Therefore, the CS op code (04) becomes (14), and so on. CS =014, // 04 CS K Clear and Subtract 2 MCT TS =015, // 05 TS K Transfer to Storage 2 MCT AD =016, // 06 AD K Add 2 or 3 MCT MASK =017, // 07 MASK K Bitwise AND 2 MCT // // // // // // MP DV SU }; enum subseq { TC0 CCS0 CCS1 NDX0 NDX1 RSM3 XCH0 CS0 TS0 AD0 MASK0 MP0 MP1 MP3 DV0 DV1 SU0 RUPT1 RUPT3 STD2 PINC0 MINC0 SHINC0 NO_SEQ }; =0, =1, =2, =3, =4, =5, =6, =7, =8, =9, =10, =11, =12, =13, =14, =15, =16, =17, =18, =19, =20, =21, =22, =23 These are extended instructions. They are accessed by executing an INDEX 5777 before each instruction. By convention, address 5777 contains 47777. The INDEX instruction adds 47777 to the extended instruction to form the SQ op code. For example, the INDEX adds 4 to the 4 op code for MP to produce the 11 (octal; the addition generates an end-around-carry). SQ register code (the 7777 part is a negative zero). =011, // 04 MP K Multiply 10 MCT =012, // 05 DV K Divide 18 MCT =013, // 06 SU K Subtract 4 or 5 MCT
enum scType { // identifies subsequence for a given instruction SUB0=0, // ST2=0, ST1=0 SUB1=1, // ST2=0, ST1=1 SUB2=2, // ST2=1, ST1=0 SUB3=3 // ST2=1, ST1=1 }; enum brType { BR00 BR01 =0, =1, // BR1=0, BR2=0 // BR1=0, BR2=1
=2, =3, =4
// BR1=1, BR2=0 // BR1=1, BR2=1 // NO BRANCH =02000; // bottom address of fixed memory
class regSQ : public reg { public: regSQ() : reg(4, "%02o") { } }; class regSTA : public reg { public: regSTA() : reg(2, "%01o") { } }; class regSTB : public reg { public: regSTB() : reg(2, "%01o") { } }; class regBR1 : public reg { public: regBR1() : reg(1, "%01o") { } }; class regBR2 : public reg { public: regBR2() : reg(1, "%01o") { } }; class regCTR : public reg { public: regCTR() : reg(3, "%01o") { } }; class regSNI : public reg { public: regSNI() : reg(1, "%01o") { } }; class SEQ { public: static static static static static static static static static static static static static static static static static
void void void void void void void void void void void void void void void void void
execWP_GENRST(); execWP_WSQ(); execWP_NISQ(); execWP_CLISQ(); execWP_ST1(); execWP_ST2(); execWP_TRSM(); execWP_CLSTA(); execWP_WSTB(); execWP_CLSTB(); execWP_SETSTB(); execWP_TSGN(); execWP_TOV(); execWP_TMZ(); execWP_TSGN2(); execWP_CTR(); execWP_CLCTR(); // select next intruction flag // current set of asserted control pulses (MAXPULSES)
// Test the currently asserted control pulses; return true if the specified // control pulse is active. static bool isAsserted(cpType pulse); // Return a string containing the names of all asserted control pulses. static char* getControlPulses(); static subseq glbl_subseq; static static static static static static }; #endif // currently decoded instruction subsequence instruction register stage counter A stage counter B branch register1 branch register2 // loop counter
regSQ register_SQ; // regSTA register_STA; // regSTB register_STB; // regBR1 register_BR1; // regBR2 register_BR2; // regCTR register_LOOPCTR;
SEQ (SEQ.cpp)
/**************************************************************************** * SEQ - SEQUENCE GENERATOR subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: SEQ.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "SEQ.h" #include "ADR.h" #include "BUS.h" regSNI SEQ::register_SNI; cpType SEQ::glbl_cp[]; regSQ SEQ::register_SQ; regSTA SEQ::register_STA; regSTB SEQ::register_STB; regBR1 SEQ::register_BR1; regBR2 SEQ::register_BR2; regCTR SEQ::register_LOOPCTR; subseq SEQ::glbl_subseq; // select next intruction flag // current set of asserted control pulses (MAXPULSES) // // // // // // // instruction register stage counter A stage counter B branch register1 branch register2 loop counter currently decoded instruction subsequence
char* SEQ::instructionString[] = { "TC", "CCS", "INDEX", "XCH", "***", "***", "***", "***", "***", "MP", "DV", "SU", "CS", "TS", "AD", "MASK" };
char* SEQ::cpTypeString[] = { "NO_PULSE", // OUTPUTS FROM SUBSYSTEM A "CI", "CLG", "CLCTR", "CTR", "GP", "KRPT", "NISQ", "RA", "RB", "RB14", "RC", "RG", "RLP", "RP2", "RQ", "RRPA", "RSB", "RSCT", "RU", "RZ", "R1", "R1C", "R2", "R22", "R24", "ST1", "ST2", "TMZ", "TOV", "TP", "TRSM", "TSGN", "TSGN2", "WA", "WALP", "WB", "WGx", "WLP", "WOVC", "WOVI", "WOVR", "WP", "WPx", "WP2", "WQ", "WS", "WX", "WY", "WYx", "WZ", // OUTPUTS FROM SUBSYSTEM A; USED AS INPUTS TO SUBSYSTEM B ONLY; // NOT USED OUTSIDE CPM // "RSC", "WSC", "WG", // OUTPUTS FROM SUBSYSTEM A; USED AS INPUTS TO SUBSYSTEM C ONLY; // NOT USED OUTSIDE CPM // "SDV1", "SMP1", "SRSM3", // EXTERNAL OUTPUTS FROM SUBSYSTEM B
// "RA0", "RA1", "RA2", "RA3", "RA4", "RA5", "RA6", "RA7", "RA10", "RA11", "RA12", "RA13", "RA14", "RBK", "WA0", "WA1", "WA2", "WA3", "WA10", "WA11", "WA12", "WA13", "WA14", "WBK", "WGn", "W20", "W21", "W22", "W23", // THESE ARE THE LEFTOVERS -- THEY'RE PROBABLY USED IN SUBSYSTEM C // "GENRST", "CLINH", "CLINH1", "CLSTA", "CLSTB", "CLISQ", "CLRP", "INH", "RPT", "SBWG", "SETSTB", "WE", "WPCTR", "WSQ", "WSTB", "R2000" };
void SEQ::execWP_GENRST() { register_SQ.write(0); register_BR1.write(0); register_BR2.write(0); register_SNI.write(0); register_LOOPCTR.write(0); register_STA.write(0); register_STB.write(0); } void SEQ::execWP_WSQ() { register_SQ.write(BUS::glbl_WRITE_BUS >> 12); }
// change to write(0)??
bool SEQ::isAsserted(cpType pulse) { for(unsigned i=0; i<MAXPULSES; i++) if(glbl_cp[i] == pulse) return true; return false; }
char* SEQ::getControlPulses() { static char buf[MAXPULSES*6]; strcpy(buf,""); for(unsigned i=0; i<MAXPULSES && glbl_cp[i] != NO_PULSE; i++) { strcat(buf, cpTypeString[glbl_cp[i]]); strcat(buf," "); } //if(strcmp(buf,"") == 0) strcat(buf,"NONE"); return buf; } void SEQ::execWP_ST1() { register_STA.writeField(1,1,1); }
void SEQ::execWP_ST2() { register_STA.writeField(2,2,1); } void SEQ::execWP_TRSM() { if(ADR::EQU_25()) register_STA.writeField(2,2,1); } void SEQ::execWP_CLSTA() { register_STA.writeField(2,1,0); }
void SEQ::execWP_TSGN() { // Set Branch 1 FF // if sign bit is '1' (negative sign) if(BUS::glbl_WRITE_BUS & 0100000) register_BR1.write(1); else register_BR1.write(0); } void SEQ::execWP_TOV() { // Set Branch 1 FF // if negative overflow (sign==1; overflow==0) if((BUS::glbl_WRITE_BUS & 0140000) == 0100000) register_BR1.write(1); else register_BR1.write(0); // Set Branch 2 FF // if positive overflow (sign==0; oveflow==1) if((BUS::glbl_WRITE_BUS & 0140000) == 0040000) register_BR2.write(1); else register_BR2.write(0); }
if(BUS::glbl_WRITE_BUS & 0100000) register_BR2.write(1); else register_BR2.write(0); } void SEQ::execWP_TMZ() { // Set Branch 2 FF // if minus zero if(BUS::glbl_WRITE_BUS == 0177777) register_BR2.write(1); else register_BR2.write(0); }
TPG (TPG.h)
/**************************************************************************** * TPG - TIME PULSE GENERATOR subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: TPG.h * * VERSIONS: * * DESCRIPTION: * Time Pulse Generator and Start/Stop Logic for the Block 1 Apollo Guidance * Computer prototype (AGC4). * * SOURCES: * Mostly based on information from "Logical Description for the Apollo * Guidance Computer (AGC4)", Albert Hopkins, Ramon Alonso, and Hugh * Blair-Smith, R-393, MIT Instrumentation Laboratory, 1963. * * NOTES: * ***************************************************************************** */ #ifndef TPG_H #define TPG_H #include "reg.h" // Start/Stop Logic and Time Pulse Generator Subsystem enum tpType { STBY PWRON TP1 TP2 TP3 TP4 TP5 TP6 TP7 TP8 TP9 TP10 TP11 TP12 SRLSE WAIT }; class regSG : public reg { public: regSG() : reg(4, "%02o") { } }; class TPG { public: static void doexecWP_TPG(); static regSG register_SG; static char* tpTypestring[]; }; #endif =0, =1, =2, =3, =4, =5, =6, =7, =8, =9, =10, =11, =12, =13, =14, =15 // TIME PULSE 1: start of memory cycle time (MCT)
// EMEM is available in G register by TP6 // FMEM is available in G register by TP7 // G register written to memory beginning at TP10 // TIME PULSE 11: end of memory cycle time (MCT) // select new subsequence/select new instruction // step switch release
TPG (TPG.cpp)
/**************************************************************************** * TPG - TIME PULSE GENERATOR subsystem * * AUTHOR: John Pultorak * DATE: 9/22/01 * FILE: TPG.cpp * * NOTES: see header file. * ***************************************************************************** */ #include "TPG.h" #include "MON.h" #include "SCL.h" #include "SEQ.h" #include "OUT.h" char* TPG::tpTypestring[] = // must correspond to tpType enumerated type { "STBY", "PWRON", "TP1", "TP2", "TP3", "TP4", "TP5", "TP6", "TP7", "TP8", "TP9", "TP10", "TP11", "TP12", "SRLSE", "WAIT" }; regSG TPG::register_SG; // static member
void TPG::doexecWP_TPG() { unsigned mystate = register_SG.read(); if(MON::PURST) mystate = STBY; else switch(mystate) { case STBY: if(!MON::PURST && ((!MON::FCLK) || SCL::F17x())) mystate = PWRON; break; case PWRON: if(((!MON::FCLK) || SCL::F13x())) mystate = TP1; break; case case case case case case case case case case case case TP1: mystate = TP2; break; TP2: mystate = TP3; break; TP3: mystate = TP4; break; TP4: mystate = TP5; break; TP5: mystate = TP6; break; TP6: mystate = TP7; break; TP7: mystate = TP8; break; TP8: mystate = TP9; break; TP9: mystate = TP10; break; TP10: mystate = TP11; break; TP11: mystate = TP12; break; TP12: if(SEQ::register_SNI.read() && OUT::register_OUT1.readField(8,8) && MON::SA) mystate = STBY; // the next transition to TP1 is incompletely decoded; it works because // the transition to STBY has already been tested. else if((MON::RUN) || (!SEQ::register_SNI.read() && MON::INST)) mystate = TP1; else mystate = SRLSE; break; case SRLSE: if(!MON::STEP) mystate = WAIT; break; case WAIT: if(MON::STEP || MON::RUN) mystate = TP1; break; default: break; } register_SG.write(mystate); }
Abstract
This report describes my successful project to build a working reproduction of the 1964 prototype for the Block I Apollo Guidance Computer. The AGC is the flight computer for the Ap ollo m oon lan din gs, and is the wo rlds first in tegra ted c ircuit com pu ter. I built it in my ba sem ent. It took me 4 yea rs. If you like, you can build one too. It will take you less time, and yours will be better than mine. I docum ented m y project in 9 separate .pdf files: Part 1 Part 2 Part 3 Part 4 Part 5 Part 6 Part 7 Part 8 O v ervie w : Introdu ces the p roject. CTL Module: Design and construction of the control module. PROC M odule: Design and construction of the processing (CPU) modu le. MEM Module: Design and construction of the mem ory module. IO Module: Design and construction of the display/keyboard (DSKY) m odule. Assem bler: A cross-a ssem bler for AG C softw are dev elopm ent. C+ + S imu lator: A low-level simulator that runs assemb led AGC code. Flight Software: My translation of portions of the COLOSSUS 249 flight software. Test & Che ckou t: A suite of test programs in AG C assembly langu age.
Part 9
Overview
I wan ted ge nuin e Block I flight softwa re for my AG C, bu t could nt find an y. I eventu ally woun d up recreating Block I software from Block II code listings that were available. Major portions of Block II were originally coded as Block I anyway, so the conversion back was not too difficult. A bou t 95% of the instru ctions w ere alread y Block I, so I just had to transla te the rem aining 5 % into their Block I equivalen ts. I dow nloa ded a partia l listing of th e CO LOS SU S 24 9 fligh t softwa re for the Blo ck II Apollo Com man d Modu le AGC from a M.I.T website in late 2001. The listing (at that time) com prised first half of the flight software load. The second half was missing. The part that was present contained erase able m em ory declarations, and PINBALL, the AGC user interface. The missing portion contained (among other things) the EXEC and WA ITLIST pieces of the operating system, bank register calling routin es, and ma th libraries. The down loaded doc um ent wa s a .pd f file con tain ing 300 or so fuzzy dig ital im ages of assem bler listing. I printed it, and then retyped the erasable memory and PINBALL portions into a text file, m arkin g off ea ch reentered line in th e orig ina l listin g w ith a hig hlig hter. I coded my own versions of the EXEC, WAITLIST, BANKC ALL, and other missing routines used by PINBALL. The R-393 d ocumen t from M .I.T. provided some guidance. Over a 6 month period, I was able to get all regular verbs and generic normal nouns working. These are listed near the top of my assembler listing. I add ed a dd ition al com m ents to portion s of cod e tak en from CO LOSS US . The pag e nu m bers in my comments refer to pages in the COLOSSUS 249 assembler listing.
Scenarios
Heres how some AGC verbs and nouns are used to do commonplace operations. The overview (part 1) and simulator (part 7) docum ents contain actual examples of some of these operations in the simu lated and hardw are AGC s. Display elapsed time from the AGC clock: <VERB> <0> <6> <NOUN> <3> <6> <ENTER> Start a monitor program to continuously display the AGC clock: <VERB> <1> <6> <NOUN> <3> <6> <ENTER> Terminate a monitor program: <VERB> <3> <4> <ENTER> Test DSJT display lights: <VERB> <3> <5> <ENTER> All DSKY lamps and display segments illuminate for 5 sec. after 5 sec, the DSKY lamps extinguish. Load component 1 for dataset at octal address 50 with octal 123: <VERB> <2> <1> <NOUN> <0> <1> <ENTER> Verb/no un disp lay flashes: wa iting for address. <5> <0> <ENTER> Verb/noun display flash continues: waiting for data. <1> <2> <3> <ENTER> Octal word from R1 is loaded at address 50. Display component 1 of dataset at octal address 50: <VERB> <0> <1> <NOUN> <0> <1> <ENTER> Verb/no un disp lay flashes: wa iting for address. <5> <0> <ENTER> Octal word from address 50 is displayed in R1. Display component 1 of dataset incrementing from 50: <VERB> <0> <1> <NOUN> <0> <1> <ENTER> Verb/no un disp lay flashes: wa iting for address. <5> <0> <ENTER> Octal word from address 50 is displayed in R1. <NOUN> <1> <5> <ENTER> Octal word from address 51 is displayed in R1, address in R3. <ENTER> Octal word from address 52 is displayed in R1, address in R3.
Load 3 component dataset at octal address 50 with octal values: 123, 456, 701: <VERB> <2> <5> <NOUN> <0> <1> <ENTER> Verb/no un disp lay flashes: wa iting for address. <5> <0> <ENTER> Verb/noun display flash continues: waiting for data. <1> <2> <3> <ENTER> <4> <5> <6> <ENTER> <7> <0> <1> <ENTER>
Octal wo rd from R1 is loaded at add ress 50; Octal w ord from R2 is loaded at add ress 51, Octal word from R3 is loaded at address 52. Display 3 component dataset beginning at address 50: <VERB> <0> <5> <NOUN> <0> <1> <ENTER> Verb/no un disp lay flashes: wa iting for address. <5> <0> <ENTER> Octa l word from a ddres s 50 is d isplay ed in R 1; O ctal w ord from add ress 51 is displayed in R2; Octal word from address 52 is displayed in R3. Change major mode to P00: <VERB> <3> <7> <ENTER> Verb/noun display flashes: waiting for major mode <0> <0> <ENTER>
(Spare) (Spare) (Spare) Monitor octal comp 1 in R1 Monitor octal comp 2 in R2 Monitor octal comp 3 in R3 Monitor octal comp 1,2 in R1,R2 Monitor octal comp 1,2,3 in R1,R2,R3
Performs octal display of updated data every 1/2 second on REGISTER 1. Performs octal display of updated data every 1/2 second on REGISTER 1. Performs octal display of updated data every 1/2 second on REGISTER 1. Performs octal display of updated data every 1/2 second on REGISTER 1 and REGISTER 2. Performs octal display of updated data every 1/2 second on REGISTER 1, REGISTER 2, and REGISTER 3.
16
17
18 19 20 21
22
23
24
25
26 27
28 29 30
31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Request WAITLIST
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Performs decimal display of updated data every 1/2 second on appropriate registers. Performs double precision display of decimal data on REGISTER 1 and REGISTER 2. No scale factoring is performed. Provides 10-character, fractional decimal conversion of two consecutive erasable registers. The sign is placed in the sign-bit position of REGISTER 1. REGISTER 2 sign bit is blank.
Performs data loading. Octal quantities are unsigned. Decimal quantities are preceded by + or sign. Data is displayed on REGISTER 1. Performs data loading. Octal quantities are unsigned. Decimal quantities are preceded by + or sign. Data is displayed on REGISTER 2. Performs data loading. Octal quantities are unsigned. Decimal quantities are preceded by + or sign. Data is displayed on REGISTER 3. Performs data loading. Octal quantities are unsigned. Decimal quantities are preceded by + or sign. Data is displayed on REGISTER 1 and REGISTER 2. Performs data loading. Octal quantities are unsigned. Decimal quantities are preceded by + or sign. Data is displayed on REGISTER 1, REGISTER 2, and REGISTER 3.
This verb is included to permit displaying the contents of fixed memory in any bank. Its intended use is for checking program ropes and the BANK positions of program ropes.
Enters request to executive routine for any machine address with priority involved. This verb assumes that the desired priority has been loaded into bits 10-14 of the prio/delay register (noun 26). This verb is used with the noun, "machine address to be specified". The complete address of the desired location is then keyed in. (Refer to "Machine address to be specified" in paragraph on Verb/Noun Formats.) Enters request to "waitlist routine"
| (Used only during ground | for any machine address with delay | checkout.) | involved. This verb assumes that the | | desired number of 10-millisecond units | | of delay has been loaded into the low | | order bits of the prio/delay register | | (noun 26). This verb is used with the | | "machine address to be specified" noun. | | The complete address of the desired | | location is then keyed in. (Refer to | | "Machine address to be specified" in | | paragraph on Verb/Noun Formats.) | | 32 | Recycle | | | 33 | Proceed (without data) | Informs routine requesting data that | | the operator chooses not to load | | fresh data, but wishes the routine to | | continue as best it can with old data. | | Final decision for what action should | | be taken is left to the requesting | | routine. | | 34 | Terminate | Informs routine requesting data to be | | loaded that the operator chooses not | | to load fresh data and wishes the | | routine to terminate. Final decision | | for what action should be taken is | | left to the requesting routine. If | | monitor is on, it is turned off. | | 35 | Test lights | | | 36 | Request fresh start | Initializes the program control | | software and the keyboard and display | | system program. | | 37 | Change program (major mode) | Change to new major mode. (Refer to | | "Change major mode" in paragraph on | | Verb/Noun Formats.) | | ;--------------------------------------------------------------------------
04 05 06 07 08 09
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27 28 29 30 31 32 33 34 35 36
37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
(Spare) (Spare) (Spare) (Spare) (Spare) Increment address (Spare) (Spare) (Spare) (Spare) (Spare) (Spare) (Spare) (Spare) (Spare) (Spare) Prio/delay, address
(Spare) (Spare) (Spare) (Spare) (Spare) (Spare) (Spare) (Spare) (Spare) Time of CMC clock: REGISTER 1 REGISTER 2 REGISTER 3 (Spare)
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
OCT
; MIT Instrumentation Laboratory, Cambridge, MA, Mar. 1963. ; Contains the software interfaces for EXEC and WAITLIST, and ; portions of the dual precision (DP) math library. ; ;================= ========================================================= INC L doc.asm ;================= ========================================================= ; AGC documentatio n (file:doc.asm) ; ; Version: 1.0 ; Author: John P ultorak ; Date: 06/01/ 2002 ; ; PURPOSE: ; Documents AGC op s source code. ;================= =========================================================
;----------------- --------------------------------------------------------; DSKY OPERATION ( examples) ; ; verb/noun (V/N) flash: When the verb and noun indicators flash ; at 1Hz, the DSKY is waiting for keyboard input. ; ; ; Display elapsed time from the AGC clock: ; <VERB> <0> <6> <NOUN> <3> <6> <ENTER> ; ; Test display lig hts ; a) <VERB> <3> <5> <ENTER> ; b) all DSKY lamps and display segments illuminate for 5 sec. ; c) after 5 sec, the DSKY lamps extinguish ; ; Load component 1 for dataset at octal address 50 with octal 123 ; a) <VERB> <2> <1> <NOUN> <0> <1> <ENTER> ; b) verb/noun display flashes; waiting for address ; c) <5> <0> <ENTER> ; d) verb/noun display flash continues; waiting for data ; e) <1> <2> <3> <ENTER> ; f) octal word from R1 is loaded at address 50, ; ; Display componen t 1 of dataset at octal address 50: ; a) <VERB> <0> <1> <NOUN> <0> <1> <ENTER> ; b) verb/noun display flashes; waiting for address ; c) <5> <0> <ENTER> ; d) octal word from address 50 is displayed in R1 ; ; Load 3 component dataset at octal address 50 with octal values ; 123,456,701 ; a) <VERB> <2> <5> <NOUN> <0> <1> <ENTER> ; b) verb/noun display flashes; waiting for address ; c) <5> <0> <ENTER> ; d) verb/noun display flash continues; waiting for data ; e) <1> <2> <3> <ENTER> ; f) <4> <5> <6> <ENTER> ; g) <7> <0> <1> <ENTER> ; h) octal word from R1 is loaded at address 50, ; octal word from R2 is loaded at address 51, ; octal word from R3 is loaded at address 52 ; ; Display 3 compon ent dataset beginning at address 50: ; a) <VERB> <0> <5> <NOUN> <0> <1> <ENTER> ; b) verb/noun display flashes; waiting for address ; c) <5> <0> <ENTER> ; d) octal word from address 50 is displayed in R1, ; octal word from address 51 is displayed in R2, ; octal word from address 52 is displayed in R3 ; ;----------------- ---------------------------------------------------------
;----------------- --------------------------------------------------------; COLOSSUS REGULAR VERBS (00-39 decimal) ; ; This is adapted from the Apollo 204 accident report posted on multiple ; web sites by Ric hard F. Drushel. The information has been changed as ; necessary to be consistent with usage in COLOSSUS. ; ; ; Verb | | ; Code | Description | Remarks ; | | ; 01 | Display octal comp 1 in R1 | Performs octal display of data on ; | | REGISTER 1. ; | | ; 02 | Display octal comp 2 in R2 | Performs octal display of data on
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
03
04
05
06
07
08 09 10 11
12
13
14
15
16
17
18 19 20 21
22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Display octal comp 1,2 in R1,R2 Display octal comp 1,2,3 in R1,R2 ,R3 Display decimal in R1 or R1,R2 or R1,R2,R3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
REGISTER 1. Performs octal display of data on REGISTER 1. Performs octal display of data on REGISTER 1 and REGISTER 2 Performs octal display of data on REGISTER 1, REGISTER 2, and REGISTER 3 . Performs decimal display of data on appropriate registers. The scale factors, types of scale factor routines, and component information are stored within the machine for eac h noun which it is required to display in decimal. Performs a double precision decimal display of data on REGISTER 1 and REGISTER 2. It does no scale factoring. It merely performs a 10character, fractional decimal conversion of two consecutive, erasab l e registers, using REGISTER 1 and REGISTER 2. The sign is placed in th e REGISTER 1 sign position with the REGISTER 2 sign position remaining blank. It cannot be used with mixed nouns. Its intended use is primarily with "machine address to be specified " nouns.
Performs octal display of updated dat a every 1/2 second on REGISTER 1. Performs octal display of updated dat a every 1/2 second on REGISTER 1. Performs octal display of updated dat a every 1/2 second on REGISTER 1. Performs octal display of updated dat a every 1/2 second on REGISTER 1 and REGISTER 2. Performs octal display of updated dat a every 1/2 second on REGISTER 1, REGISTER 2, and REGISTER 3. Performs decimal display of updated data every 1/2 second on appropriate registers. Performs double precision display of decimal data on REGISTER 1 and REGISTER 2. No scale factoring is performed. Provides 10-character, fractional decimal conversion of two consecutive erasable registers. The sign is placed in the sign-bit position of REGISTER 1. REGISTER 2 sign bit is blank.
Performs data loading. Octal quantities are unsigned. Decimal quantities are preceded by + or sign. Data is displayed on REGISTER 1. Performs data loading. Octal quantities are unsigned. Decimal quantities are preceded by + or sign. Data is displayed on REGISTER
; | | 2. ; | | ; 23 | Load com ponent 3 into R3 | Performs data loading. Octal ; | | quantities are unsigned. Decimal ; | | quantities are preceded by + or ; | | sign. Data is displayed on REGISTER ; | | 3. ; | | ; 24 | Load com ponent 1,2 into | Performs data loading. Octal ; | R1,R2 | quantities are unsigned. Decimal ; | | quantities are preceded by + or ; | | sign. Data is displayed on REGISTER ; | | 1 and REGISTER 2. ; | | ; 25 | Load com ponent 1,2,3 into | Performs data loading. Octal ; | R1,R2,R3 | quantities are unsigned. Decimal ; | | quantities are preceded by + or ; | | sign. Data is displayed on REGISTER ; | | 1, REGISTER 2, and REGISTER 3. ; | | ; 26 | (Spare) | ; | | ; 27 | Display fixed memory | This verb is included to permit ; | | displaying the contents of fixed ; | | memory in any bank. Its intended use ; | | is for checking program ropes and the ; | | BANK positions of program ropes. ; | | ; 28 | (Spare) | ; | | ; 29 | (Spare) | ; | | ; 30 | Request EXECUTIVE | Enters request to executive routine ; | (Used on ly during ground | for any machine address with priority ; | checkout .) | involved. This verb assumes that the ; | | desired priority has been loaded into ; | | bits 10-14 of the prio/delay register ; | | (noun 26). This verb is used with th e ; | | noun, "machine address to be ; | | specified". The complete address of ; | | the desired location is then keyed in . ; | | (Refer to "Machine address to be ; | | specified" in paragraph on Verb/Noun ; | | Formats.) ; | | ; 31 | Request WAITLIST | Enters request to "waitlist routine" ; | (Used on ly during ground | for any machine address with delay ; | checkout .) | involved. This verb assumes that the ; | | desired number of 10-millisecond unit s ; | | of delay has been loaded into the low ; | | order bits of the prio/delay register ; | | (noun 26). This verb is used with th e ; | | "machine address to be specified" nou n . ; | | The complete address of the desired ; | | location is then keyed in. (Refer to ; | | "Machine address to be specified" in ; | | paragraph on Verb/Noun Formats.) ; | | ; 32 | Recycle | ; | | ; 33 | Proceed (without data) | Informs routine requesting data that ; | | the operator chooses not to load ; | | fresh data, but wishes the routine to ; | | continue as best it can with old data . ; | | Final decision for what action should ; | | be taken is left to the requesting ; | | routine. ; | | ; 34 | Terminat e | Informs routine requesting data to be ; | | loaded that the operator chooses not ; | | to load fresh data and wishes the ; | | routine to terminate. Final decision ; | | for what action should be taken is ; | | left to the requesting routine. If ; | | monitor is on, it is turned off. ; | | ; 35 | Test lig hts | ; | | ; 36 | Request fresh start | Initializes the program control ; | | software and the keyboard and display ; | | system program. ; | | ; 37 | Change p rogram (major mode) | Change to new major mode. (Refer to ; | | "Change major mode" in paragraph on ; | | Verb/Noun Formats.) ; | | ;----------------- ---------------------------------------------------------
;----------------- --------------------------------------------------------; COLOSSUS EXTENDE D VERBS (40-99 decimal) ; ; Not implemented. Use of these verbs triggers the 'check fail' indicator. ;----------------- ---------------------------------------------------------
;----------------- --------------------------------------------------------; COLOSSUS NORMAL NOUNS (00-39 decimal) ; ; This is adapted from the Apollo 204 accident report posted on multiple ; web sites by Ric hard F. Drushel. The information has been changed as ; necessary to be consistent with usage in COLOSSUS. ; ; ; Noun | | ; Code | Description | Scale/Units ; | | ; 01 | Specify machine address (frac) | .XXXXX FRAC ; | | .XXXXX FRAC ; | | .XXXXX FRAC ; | | ; 02 | Specify machine address (whole) | XXXXX INTEGER ; | | XXXXX INTEGER ; | | XXXXX INTEGER ; | | ; 03 | Specify machine address (degree) | XXX.XX DEG ; | | XXX.XX DEG ; | | XXX.XX DEG ; | | ; 04 | (Spare) | ; | | ; 05 | (Spare) | ; | | ; 06 | (Spare) | ; | | ; 07 | (Spare) | ; | | ; 08 | (Spare) | ; | | ; 09 | Alarm co des | OCT ; | | OCT ; | | OCT ; | | ; 10 | (Spare) | ; | | ; 11 | (Spare) | ; | | ; 12 | (Spare) | ; | | ; 13 | (Spare) | ; | | ; 14 | (Spare) | ; | | ; 15 | Incremen t address | OCT ; | | ; | | ; 16 | (Spare) | ; | | ; 17 | (Spare) | ; | | ; 18 | (Spare) | ; | | ; 19 | (Spare) | ; | | ; 20 | (Spare) | ; | | ; 21 | (Spare) | ; | | ; 22 | (Spare) | ; | | ; 23 | (Spare) | ; | | ; 24 | (Spare) | ; | | ; 25 | (Spare) | ; | | ; 26 | Prio/del ay, address | OCT (prio/delay) ; | | OCT (14-bit CADR) ; | | (not used) ; | | ; 27 | (Spare) | ; | |
; 28 | (Spare) | ; | | ; 29 | (Spare) | ; | | ; 30 | (Spare) | ; | | ; 31 | (Spare) | ; | | ; 32 | (Spare) | ; | | ; 33 | (Spare) | ; | | ; 34 | (Spare) | ; | | ; 35 | (Spare) | ; | | ; 36 | Time of CMC clock: | ; | REGIST ER 1 | 00XXX. hours ; | REGIST ER 2 | 000XX. minutes ; | REGIST ER 3 | 0XX.XX seconds ; | | ; 37 | (Spare) | ; | | ; 38 | (Spare) | ; | | ; 39 | (Spare) | ; | | ;----------------- ---------------------------------------------------------
;----------------- --------------------------------------------------------; COLOSSUS MIXED N OUNS (40-99 decimal) ; ; Not implemented. ;----------------- ---------------------------------------------------------
;----------------- --------------------------------------------------------; AGC ADDRESS ASSI GNMENTS ; ; Central Register s ; ; 000000 A accumulator ; 000001 Q subroutine return address ; 000002 Z program counter ; 000003 LP lower product register ; ; Input Registers ; ; 000004 IN0 ; 000005 IN1 ; 000006 IN2 ; 000007 IN3 ; ; Output Registers ; ; 000010 OUT0 ; 000011 OUT1 ; 000012 OUT2 ; 000013 OUT3 ; 000014 OUT4 ; ; Memory Bank Sele ct ; ; 000015 BANK ; ; Interrupt Contro l ; ; 000016 RELINT re-enable interrupts ; 000017 INHINT inhibit interrupts ; ; Editing Register s ; ; 000020 CYR cycle right ; 000021 SR shift rRight ; 000022 CYL cycle left ; 000023 SL shift left ; ; Interrupt Storag e Area ; ; 000024 ZRUPT save program counter (Z) ; 000025 BRUPT save B register ; 000026 ARUPT save accumulator (A) ; 000027 QRUPT save Q register ;
; 000030 - 000033 NOT USED ; ; Involuntary Coun ters ; ; 000034 OVCTR arithmetic overflow counter ; 000035 TIME2 AGC clock (high) ; 000036 TIME1 AGC clock (low) ; 000037 TIME3 WAITLIST (T3) timer ; 000040 TIME4 DISPLAY (T4) timer ; ; Involuntary Coun ters -- currently unused ; ; 000041 - 000056 NOT USED ; ; Eraseable Memory ; ; 000057 - 001777 ; ; Start of fixed m emory ; ; 002000 GOPROG AGC (re)start vector ; ; 002004 T3RUPT interrupt vector for TIME3 (T3RUPT) ; 020010 ERRUPT interrupt vector ; 020014 DSRUPT interrupt vector for DSRUPT (T4RUPT) ; 020020 KEYRUPT interrupt vector for keyboard ; 020024 UPRUPT interrupt vector for uplink ;----------------- ---------------------------------------------------------
;----------------- --------------------------------------------------------; AGC TABLES (name , file, description) ; ; Keyboard/display ; CHARIN2 bank40_1.asm keyboard character table ; INRELTAB bank40_1.asm DSKY register/display table map ; DSPTAB dsky_e.asm display table for DSKY ; ; Verbs: ; VERBTAB bank41_1.asm regular verb routines (00-39) ; ; Nouns: ; NNADTAB bank42_3.asm noun address table (00-99) ; NNTYPTAB bank42_3.asm noun type table (00-99) ; SFINTAB bank42_3.asm noun input scale factor select ; SFOUTAB bank42_3.asm nout output scale factor select ; IDADDTAB bank42_3.asm mixed noun address table (40-99) ; RUTMXTAB bank42_3.asm mixed noun scale factor routine (40-9 9 ) ; ; Noun scale facto r routines: ; SFOUTABR bank41_1.asm scale factor output routines ; SFINTABR bank41_2.asm scale factor input routines ; ; Major Modes: ; FCADRMM bank04_1.asm entry points for MM jobs ; EPREMM1 bank04_1,asm priorities for MM jobs ;----------------- ---------------------------------------------------------
; ERASEABLE MEMORY DECLARATIONS ORG BANK0 ; immediately following counters INC L waitlist_e.asm ; WAITLIST variables ;================= ========================================================= ; WAITLIST (file:w aitlist_e.asm) ; ; Version: 1.0 ; Author: John P ultorak ; Date: 11/15/ 2001 ; ; PURPOSE: ; Eraseable memory variables and structures for the WAITLIST. See the ; WAITLIST source code file for more information. ;================= =========================================================
7 ; max number of tasks %037777 ; largest pos 15-bit int (+16383 dec) 12000 ; 120 seconds (in .01 sec ticks) MAXVAL-MAXDELAY+1 ; TIME3 setting for MAXDELAY
; task delta t: nu mber of 10 mSec ticks until timeout. ; i.e.: 0=timeou t, 1=10mS until timeout, 2=20mS until timeout... ; maximum time d elay is 120 (decimal) seconds. ;
; If a task record is empty (unused), the address is always set to ; zero and the tim e is set to MAXDELAY. ; task record stru cture TSKTIME EQU 0 TSKADDR EQU 1 TRECSZ EQU 2
; offset to task delta time ; offset to 14-bit task address ; size of task record (words)
00057 00060 00061 00062 00063 00064 00065 00066 00067 00070 00071 00072 00073 00074
0057 0060 0061 0062 0063 0064 0065 0066 0067 0070 0071 0072 0073 0074
00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1
; record 0
; record 1
; record 2
; record 3
; record 4
; record 5
; record 6
00075 00076 00077 00100 00101 00102 00103 00104 00105 00106 00107 00110 00111 00112 00113 00114 00115 00116 00117 00120 00121 00122 00123 00124 00125 00126 00127
0075 0076 0077 0100 0101 0102 0103 0104 0105 0106 0107 0110 0111 0112 0113 0114 0115 0116 0117 0120 0121 0122 0123 0124 0125 0126 0127
00000 1 WL_IN_saveQ 00000 1 WL_IN_taskPtr 00000 1 WL_IN_loopCnt 00000 00000 00000 00000 00000 1 1 1 1 1 WL_AT_saveQ WL_AT_taskPtr WL_AT_newTime WL_AT_timeLeft WL_AT_loopCnt
DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
; return address ; points to task rec in list ; loop counter ; ; ; ; ; return address points to task rec in list time to be inserted time remaining until timeout loop counter
00000 1 WL_T3_saveQ 00000 1 WL_T3_oldBank 00000 00000 00000 00000 1 1 1 1 WL_ST_saveQ WL_ST_taskPtr WL_ST_newTime WL_ST_loopCnt
; return address ; current bank ; ; ; ; return address points to task rec in list time-out time loop counter
00000 1 WL_RT_saveQ 00000 1 WL_RT_runAddr 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 1 1 1 1 1 1 1 1 1 1 1 WL_RM_saveQ WL_RM_taskPtr WL_RM_taskPtr2 WL_RM_loopCnt WL_RM_retval WL_IS_newTime WL_IS_newAddr WL_IS_saveQ WL_IS_taskPtr WL_IS_taskPtr2 WL_IS_loopCnt
; return address ; address of task to run ; ; ; ; ; ; ; ; ; ; ; return address points to task rec in list points to task rec behind taskPtr loop counter tmp store for return value INPUT: time to INPUT: address return address points to task points to task loop counter be inserted to be inserted rec in list rec ahead of taskPtr
INC L exec_e.asm ; EXEC variables ;================= ========================================================= ; EXEC (file:exec_ e.asm) ; ; Version: 1.0 ; Author: John P ultorak ; Date: 04/26/ 2002 ; ; PURPOSE: ; Eraseable memory variables and structures for the EXEX. See the EXEC ; source code file for more information. ; ; The COLOSSUS ver sion of this is on p. 70. ; ; ERRATA: The curr ent version of the EXEC does not set the BANKSET parameter. ; Instead, it stor es the 14-bit CADR in LOC. Also, the JOBPRIOBASE field ; has been added. ;================= =========================================================
MAXJOBS JRECSZ
EQU EQU
7 13
; max number jobs (not incl current job) ; size of job record (words)
; (COLOSSUS, p. 70 ) ; dynamically allo cated core sets for EXEC jobs (8 sets) ; record for curre nt (running) job ; Job priority: 0= no job, 1=lowest priority job, 2=... EX_currentJob EQU *
MPAC 00130 00131 00132 00133 00134 00135 00136 00137 00140 00141 00142 00143 00144 0130 0131 0132 0133 0134 0135 0136 0137 0140 0141 0142 0143 0144 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 1 1 1 1 1 1 1 1 1 1 1 1 1 MODE LOC BANKSET PUSHLOC PRIORITY JOBPRIOBASE
EQU DS DS DS DS DS DS DS DS DS DS DS DS DS
* 0 0 0 0 0 0 0 0 0 0 0 0 0
; multi-purpose accumulator
; ; ; ; ; ;
+1 for TP, +0 for DP, or -1 for vector location associated with job usually contains bank setting word of packed interpretive parameters priority of present job and work area nominal job priority
; records for addi tional jobs waiting to run JREC0 EQU ORG EQU ORG EQU ORG EQU ORG EQU ORG EQU ORG EQU ORG * JREC0+JRECSZ * JREC1+JRECSZ * JREC2+JRECSZ * JREC3+JRECSZ * JREC4+JRECSZ * JREC5+JRECSZ * JREC6+JRECSZ
JREC1
JREC2
JREC3
JREC4
JREC5
JREC6
; ; ; ; ;
sorted list of j obs to run. The list with the highest priority job at the entry on the lis t is a word index to relative to 'EX_ currentJob', but the list. EQU ORG
is sorted by job priority top of the list. Each a job record; the indexes are current job is not on the
EX_jobList
* EX_jobList+MAXJOBS
LOCCTR
EQU
EX_jobList
00307 00310 00311 00312 00313 00314 00315 00316 00317 00320 00321 00322 00323 00324
0307 0310 0311 0312 0313 0314 0315 0316 0317 0320 0321 0322 0323 0324
CHGJOB KEEPJOB 00000 1 newJob 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 1 1 1 1 1 1 1 1 1 1 1 1 1 EX_JW_saveQ EX_JW_loopCnt EX_JW_CADR EX_JW_foundit EX_JW_jobPtr EX_JW_jobPtr2 EX_JW_fndIndx EX_AJ_saveQ EX_AJ_loopCnt EX_AJ_jobPrio EX_AJ_jobPtr EX_AJ_field EX_AJ_findx
EQU EQU DS DS DS DS DS DS DS DS DS DS DS DS DS DS
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
; change jobs at next opportunity ; keep the same job ; change flag (set to CHGJOB or KEEPJOB) ; ; ; ; ; ; ; ; ; ; ; ; ; return address loop counter address of job to wake 0=job not found, 1=found points to job rec in list points to job rec ahead of jobPtr index to awoken record return address loop counter priority of new job initialized to EX_jobList at startup index to field from start of record total index to field
00325 00326 00327 00330 00331 00332 00333 00334 00335 00336 00337 00340 00341 00342 00343 00344 00345 00346 00347 00350 00351 00352 00353 00354
0325 0326 0327 0330 0331 0332 0333 0334 0335 0336 0337 0340 0341 0342 0343 0344 0345 0346 0347 0350 0351 0352 0353 0354
1 1 1 1 1 1
DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
; ; ; ; ; ;
return address loop counter points to job rec in list record index init counter index to field from start of record total index to field
00000 1 EX_MN_runAddr 00000 1 EX_MN_field 00000 1 EX_MN_findx 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 EX_RM_saveQ EX_RM_jobPtr EX_RM_jobPtr2 EX_RM_savePtr EX_RM_loopCnt EX_RM_retval EX_RM_field EX_RM_findx EX_IS_newPrio EX_IS_newPrioB EX_IS_newLoc EX_IS_saveQ EX_IS_jobPtr EX_IS_jobPtr2 EX_IS_loopCnt
; address of job to run ; index to field from start of record ; total index to field ; ; ; ; ; ; ; ; return address points to job rec in list points to job rec behind jobPtr tmp store for index taken off list loop counter tmp store for return value index to field from start of record total index to field
DS 0 ; INPUT: priority to be inserted DS 0 ; INPUT: nominal priority to be inserted DS 0 ; INPUT: address to be inserted DS 0 ; return address DS 0 ; points to job rec in list DS 0 ; points to job rec ahead of jobPtr DS 0 ; loop counter INC L dsky_e.asm ; DSKY variables ;================= ========================================================= ; DSKY (file:dsky_ e.asm) ; ; Version: 1.0 ; Author: John P ultorak ; Date: 12/14/ 2001 ; ; PURPOSE: ; Eraseable memory variables and structures for the DSKY. See the EXEC ; source code file for more information. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968. ;================= ========================================================= DS 0
00355
0355
00000 1 FLAGWRD5
; interrupt tempor ary storage pool ; (ITEMP1 through RUPTREG4) 00356 0356 00000 1 ITEMP1 WAITEXIT EXECTEM1 00000 1 ITEMP2 WAITBANK EXECTEM2 00000 1 ITEMP3 RUPTSTOR WAITADR NEWPRIO 00000 1 ITEMP4 ;LOCCTR WAITTEMP 00000 1 ITEMP5 NEWLOC 00000 1 ITEMP6 NEWLOCP1 00000 00000 00000 00000 00000 1 1 1 1 1 NEWJOB RUPTREG1 RUPTREG2 RUPTREG3 RUPTREG4 KEYTEMP1 DSRUPTEM DS EQU EQU DS EQU EQU DS EQU EQU EQU DS EQU EQU DS EQU DS EQU DS DS DS DS DS EQU EQU 0 ITEMP1 ITEMP1 0 ITEMP2 ITEMP2 0 ITEMP3 ITEMP3 ITEMP3 0 ITEMP4 ITEMP4 0 ITEMP5 0 ITEMP6 0 0 0 0 0 RUPTREG4 RUPTREG4 ; moved to EXEC
00357
0357
00360
0360
00361
0361
00362
0362
00363
0363
STATE 00371 00372 00373 00374 00375 00376 00377 00400 00401 00402 00403 00404 0371 0372 0373 0374 0375 0376 0377 0400 0401 0402 0403 0404 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 1 1 1 1 1 1 1 1 1 1 1 1 FLAGFILL 00405 00406 00407 00410 0405 0406 0407 0410 00000 00000 00000 00000 1 1 1 1
EQU DS DS DS DS DS DS DS DS DS DS DS DS EQU DS DS DS DS
* 0 0 0 0 0 0 0 0 0 0 0 0 * 0 0 0 0
; 12 words
; pad load for DAP s ; (COLOSSUS, p. 67 ) EMDOT ; exit for VB3 STATEXIT EQU FLAGFILL+2 EQU FLAGFILL
; EXEC temporaries which may be used between CCS NEWJOBS. ; (INTB15P through RUPTMXM) 00411 0411 00000 1 INTB15P DSEXIT EXITEM BLANKRET 00000 1 INTBIT15 WRDRET WDRET DECRET _2122REG DS EQU EQU EQU DS EQU EQU EQU EQU 0 INTB15P INTB15P INTB15P 0 INTBIT15 INTBIT15 INTBIT15 INTBIT15 ; ; ; ; ; ; ; ; ; reflects 15th bit of indexable address e s return for DSPIN return for scale factor routine select return for 2BLANK similar to above return for 5BLANK return for DSPWD return for PUTCOM (dec load) temp for CHARIN
00412
0412
; The registers be tween ADDRWD and PRIORITY must stay in the following order ; for interpretive trace. 00413 00414 0413 0414 00000 1 ADDRWD 00000 1 POLISH UPDATRET CHAR ERCNT DECOUNT 00000 1 FIXLOC 00000 1 OVFIND VBUF 00417 00420 00421 00422 00423 00424 0417 0420 0421 0422 0423 0424 00000 00000 00000 00000 00000 00000 1 1 1 1 1 1 SGNON NOUNTEM DISTEM DECTEM DS DS EQU EQU EQU EQU DS DS EQU DS DS DS DS DS DS EQU EQU EQU EQU 0 0 POLISH POLISH POLISH POLISH 0 0 * 0 0 0 0 0 0 VBUF VBUF VBUF VBUF VBUF+1 VBUF+1 VBUF+1 VBUF+1 ; ; ; ; ; ; 12 bit interpretive operand subaddress holds CADR made from POLISH address return for UPDATNN, UPDATVB temp for CHARIN counter for error light reset counter for scaling and display (dec)
00415 00416
0415 0416
; work area address ; set non-zero on overflow ; temporary storage used for vectors
; ; ; ; ; ; ; ;
temp for +,- on counter for MIXNOUN fetch counter for octal display verbs counter for fetch (dec display verbs) temp for +,- off temp for NVSUB storage for SF const hi part(=SFTEMP2- 1 ) temp for load of hrs, min, sec
SGNOFF EQU NVTEMP EQU SFTEMP1 EQU HITEMIN EQU ; must = LOWTEMIN- 1 CODE EQU SFTEMP2 EQU LOWTEMIN EQU ; must = HITEMIN+1 ; (COLOSSUS, p. 68 ) MIXTEMP SIGNRET EQU EQU
; for DSPIN ; storage for SF const low part(=SFTEMP1 + 1 ) ; temp for load of hrs, min, sec
VBUF+3 VBUF+3
; Also, MIXTEMP+1 = VBUF+4, MIXTEMP+2 = VBUF+5 BUF EQU * ; temporary scalar storage
00000 1 00000 1 00000 1 00000 1 BUF2 00000 1 INDEXLOC SWWORD SWBIT 00000 1 MPTEMP DMPNTEMP 00000 1 DOTINC DVSIGN ESCAPE ENTRET 00000 1 DOTRET DVNORMCT ESCAPE2 WDCNT INREL 00000 1 MATINC MAXDVSW POLYCNT DSPMMTEM MIXBR 00000 1 TEM1 POLYRET DSREL 00000 1 TEM2 DSMAG IDADDTEM 00000 1 TEM3 COUNT 00000 1 TEM4 LSTPTR RELRET FREERET DSPWDRET SEPSCRET SEPMNRET 00000 1 TEM5 NOUNADD
DS DS DS DS DS EQU EQU EQU DS EQU DS EQU EQU EQU DS EQU EQU EQU EQU DS EQU EQU EQU EQU DS EQU EQU DS EQU EQU DS EQU DS EQU EQU EQU EQU EQU EQU DS EQU
0 0 0 0 0 BUF BUF BUF+1 0 MPTEMP 0 DOTINC DOTINC DOTINC 0 DOTRET DOTRET DOTRET DOTRET 0 MATINC MATINC MATINC MATINC 0 TEM1 TEM1 0 TEM2 TEM2 0 TEM3 0 TEM4 TEM4 TEM4 TEM4 TEM4 TEM4 0 TEM5 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; contains address of specified index address of switch word switch bit within switch word temporary used in multiply and shift DMPSUB temporary component increment for DOT subroutine determines sign of DDV result used in arcsin/arccos exit from enter return from DOT subroutine dividend normalization count in DDV alternate arcsin/arccos switch char counter for DSPWD input buffer selector (X,Y,Z REG) vector increment in MXV and VXM +0 if DP quotient is near one - else - 1 polynomial loop counter DSPCOUNT save for DSPMM indicator for mixed or normal noun
00432 00433
0432 0433
00434
0434
00435
0435
00436
0436
; EXEC temp ; rel address for DSPIN ; EXEC temp ; magnitude store for DSPIN ; mixnoun indirect address store ; EXEC temp ; for DSPIN ; ; ; ; ; ; ; EXEC temp list pointer for GRABUSY return for RELDSP return for FREEDSP return for DSPSIGN return for SEPSEC return for SEPMIN
00437
0437
00440
0440
00441
0441
00442
0442
; (COLOSSUS, p. 69 ) 00443 00444 00445 00446 00447 00450 0443 0444 0445 0446 0447 0450 00000 1 NNADTEM DS 0 00000 1 NNTYPTEM DS 0 00000 1 IDAD1TEM DS 0 ; must - IDAD2TEM- 1, = IDAD3TEM-2 00000 1 IDAD2TEM DS 0 ; must - IDAD2TEM+ 1, = IDAD3TEM-1 00000 1 IDAD3TEM DS 0 ; must - IDAD1TEM+ 2, = IDAD2TEM+1 00000 1 RUTMXTEM DS 0 ; AX*SR*T storage DEXDEX DEX1 DEX2 RTNSAVER TERM1TMP EQU EQU EQU EQU EQU TEM2 TEM3 TEM4 TEM5 BUF2 ; ; ; ; ; B(1) B(1) B(1) B(1) B(2) tmp tmp tmp tmp tmp ; temp for noun address table entry ; temp for noun type table entry ; temp for indir address table entry (MI X N N ) ; temp for indir address table entry (MI X N N ) ; temp for indir address table entry (MI X N N ) ; temp for SF rout table entry (MIXNN on l y )
; (COLOSSUS, p. 70 ) Note: the eraseable memory for the EXEC. ; Moved to the EXE C area
; (COLOSSUS, p. 72 ) ; unswitched for d isplay interface routines 00451 00452 00453 00454 00455 00456 0451 0452 0453 0454 0455 0456 00000 00000 00000 00000 RESTREG DS 0 ; B(1) prm for display starts NVWORD DS 0 MARXNV DS 0 NVSAVE DS 0 ; (retain the orde r of CADRFLSH to FAILREG+2 for downlink purposes) 00000 1 CADRFLSH DS 0 ; B(1) tmp 00000 1 CADRMARK DS 0 ; B(1) tmp 1 1 1 1
DS DS DS DS
0 0 0 0
; (COLOSSUS, p. 73 ) ; verb 37 storage 00463 00464 0463 0464 00000 1 MINDEX 00000 1 MMNUMBER DS DS 0 0 ; B(1) tmp index for major mode ; B(1) tmp major mode requested via V37
; pinball interrup t storage 00465 0465 00000 1 DSPCNT DS 0 ; B(1) prm DSPOUT counter
; pinball executiv e action 00466 00467 00470 00471 00472 00473 00474 00475 00476 0466 0467 0470 0471 0472 0473 0474 0475 0476 00000 1 DSPCOUNT DS 0 ; display position indicator 00000 1 DECBRNCH DS 0 ; Bits2,1: octal=0, +dec=1, -dec=2 ; Bit5=R1 (dec), B it4=R2 (dec), Bit3=R3 (dec) 00000 1 VERBREG DS 0 ; verb code 00000 1 NOUNREG DS 0 ; noun code 00000 1 XREG DS 0 ; R1 input buffer 00000 1 YREG DS 0 ; R2 input buffer 00000 1 ZREG DS 0 ; R3 input buffer 00000 1 XREGLP DS 0 ; low part of XREG (for ded conv only) 00000 1 YREGLP DS 0 ; low part of YREG (for ded conv only) HITEMOUT EQU YREGLP ; temp for display of HRS, MIN, SEC ; must equal LOT EMOUT-1 00000 1 ZREGLP DS 0 ; low part of ZREG (for ded conv only) LOTEMOUT EQU ZREGLP ; temp for display of HRS, MIN, SEC ; must equal HIT EMOUT+1 ; (COLOSSUS, p. 74 ) 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 1 1 1 1 1 1 1 1 1 1 MODREG DSPLOCK REQRET LOADSTAT CLPASS NOUT NOUNCADR MONSAVE MONSAVE1 MONSAVE2 DS DS DS DS DS DS DS DS DS DS 0 0 0 0 0 0 0 0 0 0 ; ; ; ; ; ; ; ; ; ; mode code keyboard/subroutine call interlock return register for load status indicator for LOADTST pass indicator clear activity counter for DSPTAB machine CADR for noun N/V code for monitor (= MONSAVE1 - 1) NOUNCADR for monitor (MATBS) = MONSAVE + 1 NVMONOPT options
00477
0477
00500 00501 00502 00503 00504 00505 00506 00507 00510 00511
0500 0501 0502 0503 0504 0505 0506 0507 0510 0511
; The 11 register table for the display panel (COLOSSUS, p.74, p.306) ; comment key = RELADD: RELAYWD BIT11 BITS10-6 BITS5-1 DSPTAB 00512 00513 00514 00515 00516 00517 00520 00521 00522 00523 00524 00525 00526 00527 00530 00531 00532 00533 00534 00535 00536 00537 00540 00541 0512 0513 0514 0515 0516 0517 0520 0521 0522 0523 0524 0525 0526 0527 0530 0531 0532 0533 0534 0535 0536 0537 0540 0541 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 1 1 1 1 1 1 1 1 1 1 1 1 EQU DS DS DS DS DS DS DS DS DS DS DS DS * 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DSPTEM2 DSPTEM1
; ; ; ; ; ; ; ; ; ; ; ;
0: 0001 -R3 R3D4( 1) 1: 0010 +R3 R3D2( 3) 2: 0011 --- R2D5( 5) 3: 0100 -R2 R2D3( 7) 4: 0101 +R2 R2D1(11) 5: 0110 -R1 R1D4(13) 6: 0111 +R1 R1D2(15) 7: 1000 --- -------8: 1001 --- ND1 (21) 9: 1010 --- VD1 (23) 10:1011 --- MD1 (25) 11: C/S lights
R3D5( 0) R3D3( 2) R3D1( 4) R2D4( 6) R2D2(10) R1D5(12) R1D3(14) R1D1(16) ND2 (20) VD2 (22) MD1 (24)
00000 1 NVQTEM DS ; must = NVBNKTEM- 1 00000 1 NVBNKTEM DS ; must = NVQTEM+1 00000 1 VERBSAVE DS 00000 1 CADRSTOR DS 00000 1 DSPLIST DS 00000 1 EXTVRACT DS 00000 1 DSPTEM1 00000 1 00000 1 00000 1 DSPTEM2 00000 1 00000 1 DSPTEMX NORMTEM1 DS DS DS DS DS DS EQU EQU
; NVSUB storage for calling address ; NVSUB storage for calling bank ; ; ; ; needed for recycle ENDIDLE storage waiting reg for DSP syst internal use extended verb activity interlock
; B(2) S-S display buffer for external v e r b s ; B(3) DSP normal display registers
; display for exte nded verbs OPTIONX EQU DSPTEMX ; B(2) extended verb option code N12(VB2 )
; temp store for m ajor mode change 00542 0542 00000 1 MMTEMP DS 0
; T4RUPT Erasable 00543 00544 00545 00546 0543 0544 0545 0546 00000 00000 00000 00000 1 1 1 1 DSRUPTSW T4RET DSPOUTRET DK_IN_saveQ DS DS DS DS 0 0 0 0 ; ; ; ; (COLOSSUS, added, not added, not return for p. 78) part of COLOSSUS part of COLOSSUS T4RUPT init
; Replacement for Block II LXCH instruction (not part of COLOSSUS) 00547 00550 0547 0550 00000 1 LXCH_LPRET 00000 1 LXCH_A DS DS 0 0 ; LP return address ; save A
; Vars for DPTEST (not part of COLOSSUS) 00552 00553 0552 0553 00000 1 DPTEST_A 00000 1 DPTEST_Q DS DS 0 0
; Vars for REQDATX , REQDATY, REQDATZ (not part of COLOSSUS) 00554 0554 00000 1 REQ_Q DS 0
; Vars for SETNCAD R (not part of COLOSSUS) 00555 0555 00000 1 SETNCADR_Q DS 0
; Vars for ALLDC_O C (not part of COLOSSUS) 00556 0556 00000 1 ALLDC_OC_Q DS 0
; Vars for SFRUTMI X (not part of COLOSSUS) 00557 0557 00000 1 SFRUTMIX_L DS 0
; Vars for SFCONUM (not part of COLOSSUS) 00560 0560 00000 1 SFCONUM_L DS 0
; vars for BLANKSU B (not part of COLOSSUS) 00561 0561 00000 1 BLANKSUB_Q DS 0
; Vars for GTSFOUT , GTSFIN (not part of COLOSSUS) 00562 0562 00000 1 GTSF_RET DS 0
; Vars for FIXRANG E (not part of COLOSSUS) 00563 0563 00000 1 FR_RETQ DS 0
; Vars for NVSUB ( not part of COLOSSUS) 00564 00565 0564 0565 00000 1 NVSUB_L 00000 1 NVSUB_A DS DS 0 0
; Vars for ENDIDLE (not part of COLOSSUS) 00566 0566 00000 1 ENDIDLE_L DS 0
; Vars for NVSUBUS Y (not part of COLOSSUS) 00567 0567 00000 1 NBSUBSY1_L DS 0
; Vars for FLASHON /FLASHOFF (not part of COLOSSUS) 00570 0570 00000 1 FLASHRET DS 0
; vars for PASTEVB (not part of COLOSSUS) 00571 0571 00000 1 PASTE_TMP DS 0
; vars for NEWMODE A (not part of COLOSSUS) 00572 0572 00000 1 NEWMODEA_Q DS 0
; Vars for MATH LI B (not part of COLOSSUS) 00573 00574 00575 00576 00577 00600 0573 0574 0575 0576 0577 0600 00000 00000 00000 00000 00000 00000 1 1 1 1 1 1 SHORTMP_A SHORTMP_OVFL SHORTMP_OVFH ADDRWD1 MATH_Q PRSHRTMP_Q DS DS DS DS DS DS 0 0 0 0 0 0
; KEYRUPT Eraseabl e 00601 00602 0601 0602 00000 1 KEYRET 00000 1 SAVEQ DS DS 0 0 ; added, not part of COLOSSUS ; temp for return addr
; Bank intercommun ication 00603 00604 00605 00606 00607 00610 00611 00612 00613 00614 00615 00616 00617 0603 0604 0605 0606 0607 0610 0611 0612 0613 0614 0615 0616 0617 00000 1 BJBANK 00000 1 BJRET 00000 1 PJBANK 00000 1 PJRET 00000 1 PJA 00000 1 BCBANK 00000 1 BCRET 00000 1 BCA 00000 1 MBCBANK 00000 1 MBCRET 00000 1 MBCA 00000 1 DCBANK 00000 1 DCRET DS DS DS DS DS DS DS DS DS DS DS DS DS 0 0 0 0 0 0 0 0 0 0 0 0 0
05777
5777
47777 0
;----------------- --------------------------------------------------------; RESTART/INTERRUP T ENTRY POINTS ;----------------- --------------------------------------------------------; Program (re)star t ORG TC ; Interrupt vector s ORG TS XCH TS TC ORG TS XCH TS TC ORG TS XCH TS TC ORG TS XCH TS TC ORG TS XCH TS TC
02000
2000 0
1,2126 0
GOPROG goMAIN
5 3 5 0
0 0 1 1
T3RUPT ARUPT Q QRUPT goT3 ERRUPT ARUPT Q QRUPT goER DSRUPT ARUPT Q QRUPT goDS KEYRUPT ARUPT Q QRUPT goKEY UPRUPT ARUPT Q QRUPT goUP
5 3 5 0
0 0 1 0
5 3 5 0
0 0 1 1
5 3 5 0
0 0 1 0
5 3 5 0
0 0 1 1
; restore Q and A registers and resume endRUPT 02030 02031 02032 02033 2030 2031 2032 2033 3 5 3 2 0,0027 0,0001 0,0026 0,0000 1 0 0 1 EQU XCH TS XCH RES UME * QRUPT Q ARUPT
;----------------- --------------------------------------------------------; RUPT (INTERRUPT) SERVICE ROUTINES ; ; Upon entry, regi sters will contain these values: ; - ZRUPT: Prior c ontents of program counter (Z register). ; - BRUPT: Prior c ontents of B register. ; - ARUPT: Prior c ontents of accumulator (A register). ; - QRUPT: Prior c ontents of Q register. ; ; When the service routine is finished, jump to endRUPT to restore the A ; and Q registers. Call RESUME to restore Z and B, which causes a return ; to normal (non-i nterrupt) execution. Interrupts are disabled upon entry ; to the service r outine; they are reenabled following RESUME. ;----------------- --------------------------------------------------------goT3 02034 02035 2034 0 2035 0 1,2347 0 1,2030 0 goER 02036 2036 0 1,2030 0 goDS 02037 02040 2037 0 2040 0 2,4047 0 1,2030 0 goKEY 02041 02042 2041 0 2042 0 2,4132 0 1,2030 0 goUP 02043 2043 0 1,2030 0 EQU TCR TC EQU TC EQU TCR TC EQU TCR TC EQU TC * WL_TIME3task endRUPT * endRUPT * T4PROG endRUPT * KEYPROG endRUPT * endRUPT
;----------------- --------------------------------------------------------; FIXED MEMORY CON STANTS ;----------------- --------------------------------------------------------02044 02045 02046 02047 02050 02051 02052 02053 02054 02055 02056 02057 02060 02061 2044 2045 2046 2047 2050 2051 2052 2053 2054 2055 2056 2057 2060 2061 00200 0 ofbit 77777 0 NEG0 77776 1 NEG1 77775 1 NEG2 00000 00001 00002 00003 00004 00005 00006 00007 00012 00013 1 0 0 1 0 1 1 0 1 0 ZERO ONE TWO THREE FOUR FIVE SIX SEVEN TEN ELEVEN DS DS DS DS DS DS DS DS DS DS DS DS DS DS %200 -0 -1 -2 0 1 2 3 4 5 6 7 10 11 ; OUT1, bit 8 initiates standby
; must be in rever se order. Pinball treats this as a table ; and indexes thru it. 02062 02063 02064 02065 02066 02067 02070 02071 02072 02073 02074 02075 02076 02077 02100 02101 02102 02103 02104 2062 2063 2064 2065 2066 2067 2070 2071 2072 2073 2074 2075 2076 2077 2100 2101 2102 2103 2104 40000 20000 10000 04000 02000 01000 00400 00200 00100 00040 00020 00010 00004 00002 00001 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 BIT15 BIT14 BIT13 BIT12 BIT11 BIT10 BIT9 BIT8 BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS %40000 %20000 %10000 %04000 %02000 %01000 %00400 %00200 %00100 %00040 %00020 %00010 %00004 %00002 %00001 %00177 %6000 %1777 %1400 ; fixed-switchable addr range starts her e ; mask for 10-bit address
02105 02106
2105 2106
DS DS
11 %37777
;----------------- -------------------------------------------------------; CLRMEM - INITIAL IZE ERASEABLE MEMORY ; ; Uses QRUPT and A RUPT as scratchpad. This is OK, because interrupts ; are disabled any way. All eraseable memory above the AGC clock (TIME1, ; TIME2) is cleare d. The AGC clock is not cleared because this might ; be a restart or a startup from standby mode. ;----------------- -------------------------------------------------------CLRMEM 02107 02110 02111 02112 2107 3 2110 5 2111 3 2112 5 0,0001 0 0,0027 1 1,2123 0 0,0026 0 CLRMEM_CHK 02113 02114 02115 2113 1 2114 0 2115 0 0,0026 1 1,2116 0 0,0027 1 CLRMEM_WORD 02116 02117 02120 02121 02122 2116 2117 2120 2121 2122 5 3 2 5 0 0,0026 1,2050 0,0026 0,0037 1,2113 0 0 1 0 0 EQU XCH TS XCH TS EQU CCS TC TC EQU TS CAF IND EX TS TC EQU EQU DS * Q QRUPT CLRMEM_WC ARUPT * ARUPT CLRMEM_WORD QRUPT * ARUPT CLRMEM_VAL ARUPT CLRMEM_BADDR CLRMEM_CHK ZERO TIME3 %1777-TIME3+1
; return
; clear a word ; done? ; set memory to this value ; base address to clear ; clear everything >= TIME3
02123
2123
;----------------- -------------------------------------------------------; FRESH START ; ; AGC starts execu ting here, following power-up, or restart. ;----------------- -------------------------------------------------------02124 02125 2124 2125 10000 0 V37BANK 37600 0 SAMASK DS DS %10000 %37600 ; BANK (4) containg PREMM1, FCADRMM1 ; mask to zero lower 7 bits
* goMAIN
; First, check for standby operation. Loosely based on the standby ; algorithm in R-3 93. Probably should flash the 'computer activity' ; light as well. 02127 02130 02131 02132 02133 02134 02135 02136 02137 02140 02141 02142 2127 3 2130 6 2131 5 2132 3 2133 6 2134 5 2135 3 2136 7 2137 5 2140 3 2141 5 2142 0 1,2071 0 0,0036 1 0,0036 1 1,2050 0 0,0035 1 0,0035 1 1,2125 0 0,0036 0 0,0036 1 1,2044 0 0,0011 1 1,2107 0 CAF AD TS CAF AD TS CAF MAS K TS XCH TS TC BIT8 TIME1 TIME1 ZERO TIME2 TIME2 SAMASK TIME1 TIME1 ofbit OUT1 CLRMEM ; add 2 to 7th power to AGC clock
; skipped on ovf and C(A) set to 1 ; bump TIME2 with overflow, if any
; set fresh start major mode to P00 (AGC CMC idle) 02143 02144 02145 02146 2143 3 2144 5 2145 3 2146 5 1,2124 1 0,0015 0 4,6046 0 0,0463 0 CAF TS CAF TS V37BANK BANK NOV37MM MINDEX
; bank for major mode tables ; assumes BANK is set (above) ; index to P00
* ; inhibit interrupts
; Initialize WAITL IST and EXEC eraseable memory. Initialize DSKY eraseable
; memory (but don' t initialize BANK or MINDEX; they are used to start the ; main job for thi s major mode. 02150 02151 02152 2150 0 2151 0 2152 0 1,3252 1 1,2204 0 2,4007 1 ; ; ; ; TCR TCR TCR EX_initEX WL_initWL DK_initDK ; initialize EXEC ; initialize WAITLIST ; initialize DSKY
Start the major mode job. This is modified from COLOSSUS because block I doesn't have E-b ank and my SPVAC interface is a little different from the original. The re ferences to PREMM1 and FCADRMM1 assume that the BANK is set to the one c ontaining those tables. EQU INH INT IND EX CAF TS MAS K TC TC TS IND EX CAF TC * MINDEX PREMM1 MMTEMP HI5 RIGHT5 RIGHT5 NEWPRIO MINDEX FCADRMM1 SPVAC * ZERO MMTEMP LOW7 NEWMODEA RELDSP ; job CADR in C(A), job prio in NEWPRIO ; obtain priority bits 15-11 ; shift right to bits 5-1 ; store PRIO for SPVAC
V37XEQ 02153 02154 02155 02156 02157 02160 02161 02162 02163 02164 02165 2153 2154 2155 2156 2157 2160 2161 2162 2 2 3 5 7 0 0 5 0,0000 0,0463 4,6037 0,0542 2,4666 2,4640 2,4640 0,0360 0 1 0 1 1 1 1 1
3 6 7 0
0 1 1 1
; ; ; ;
was CA MMTEMP in Block II upon return from FINDVAC, place the new MM in MODREG (the low 7 bits of PHSERDT1)
2172 0
2,5003 1
; release display
;----------------- -------------------------------------------------------; AGC LIBRARIES ; ; System services in fixed-fixed memory. ;----------------- -------------------------------------------------------INC L waitlist_f.asm ; WAITLIST, incl. T3RUPT handler ;================= ========================================================= ; WAITLIST (file:w aitlist_f.asm) ; ; Version: 1.0 ; Author: John P ultorak ; Date: 11/15/ 2001 ; ; PURPOSE: ; Constants and so urce code for WAITLIST. ; ; Non-preemptive i nterrupt timer routines, originally implemented by J. H. ; Laning, Jr. for AGC3 and later adapted for AGC4. Briefly discussed in ; R-393, which giv es some of the software interfaces into the WAITLIST. ; This is my own r ecreation, and the internals may differ from the original. ; ; A task is schedu led for execution by calling 'WAITLIST' and ; furnishing the t ime-out time and starting address. ; L XCH TASK_TIMEOUT ; in 10 mSec ticks ; L+1 TC WAITLIST ; L+2 DS TASK_ADDRESS ; 14-bit address ; L+3 ... execution resumes here ; ; TASK_TIMEOUT = a positive integer from 1 - MAXDELAY that specifies the delay ; in 10 mSec ti cks. Maximum delay is 12000 (2 minutes). ; TASK_ADDRESS = s tarting address of the task (14-bit address) ; ; WAITLIST can be called from from an interrupt, or from normal execution. ; It is the only p ublic function of the waitlist. ; ; **** WARNING *** * If WAITLIST is not called from an interrupt, be sure to ; inhibit interrup ts before calling it to protect the integrity of the list. ; ; Tasks execute wh en TIME3 overflows and generates an interrupt (T3RUPT). ; The task execute s during the interrupt. Tasks terminate themselves by ; jumping to TASKO VER. ; TC TASKOVER ; ; Because tasks ex ecute during an interrupt, they should be fairly short. ; Tasks can initia te longer operations by scheduling a 'job' using EXEC.
;================= =========================================================
0 0 0 1 1
DS DS DS DS DS DS DS DS
TRECSZ ; size of a task record (words) WL_taskList ; starting address for task list MAXTASK-1@TRECSZ+WL_taskList MAXTASK-1 ; init loop counter for all tasks MAXTASK-2 ; init loop counter for all tasks - 1 MAXVAL MAXDELAY MAXTIMEOUT
;----------------- --------------------------------------------------------; WL_initWL - INIT IALIZE WAITLIST ; ; Subroutine initi alizes the eraseable memory segment for WAITLIST. ; Necessary in cas e the AGC is restarted. ; ; Note: the valid range for TIME3 is 10440 to 37777 (which spans ; 12000 (base 10 ) ticks, which corresponds to 120 seconds) ; positive overf low occurs at 40000, which triggers T3RUPT. ; TIME3 values o f 0 to 10437 are illegal; these values occur ; after timeout when the counter overflows. TIME3 values in this ; range indicate that timeout has occurred and that T3RUPT is ; presently occu ring, or is pending. ;----------------- --------------------------------------------------------WL_initWL 02204 02205 02206 02207 2204 3 2205 5 2206 3 2207 5 0,0001 0 0,0075 0 1,2203 1 0,0037 0 EQU XCH TS CAF TS * Q WL_IN_saveQ WL_maxTimeOut TIME3
; Iterate through task list and initialize all records to NIL 02210 02211 02212 02213 02214 02215 02216 02217 02220 02221 02222 02223 02224 02225 02226 02227 02230 02231 2210 3 2211 5 2212 3 2213 5 2214 3 2215 2 2216 5 2217 3 2220 2 2221 5 2222 3 2223 6 2224 5 2225 1 2226 0 2227 3 2230 5 2231 0 1,2175 0 0,0076 0 1,2177 1 WL_IN_loop 0,0077 1 1,2202 0 0,0076 1 0,0000 1 1,2050 0 0,0076 1 0,0001 0 0,0076 0 1,2174 1 0,0076 0 0,0077 0 1,2213 0 0,0075 0 0,0001 0 0,0000 0 CAF TS CAF EQU TS CAF IND EX TS CAF IND EX TS XCH AD TS CCS TC XCH TS RET URN WL_tskLstStart ; init pointer to start of list WL_IN_taskPtr WL_numTasks * WL_IN_loopCnt WL_maxDelay WL_IN_taskPtr TSKTIME ZERO WL_IN_taskPtr TSKADDR WL_IN_taskPtr ; bump task pointer back 1 record WL_taskRecSize WL_IN_taskPtr WL_IN_loopCnt WL_IN_loop WL_IN_saveQ Q ; done checking task list? ; not yet ; loop for number of tasks
;----------------- --------------------------------------------------------; WAITLIST - ADD T ASK TO WAITLIST ; ; Subroutine adds a task to WL_taskList. The following conditions are ; true upon entry. ; 1) The task list is sorted so the next task scheduled for execution ; is at the fro nt of the list. ; 2) If no tasks a re currently scheduled, the task record at the front ; of the list w ill be NIL. ; 3) Unused (NIL) records in the task list have their time fields set to ; MAXDELAY and their address fields set to zero. ; 4) If any tasks are on the waitlist, the time field in that task's ; record will c ontain the remaining time AFTER the next timeout. The ; task schedule d for execution at timeout will have a time remaining ; of zero. ; Any other tas ks that will execute at that time will also have a time of ; zero. Tasks t hat will execute some time in the future AFTER timeout ; will have non zero times; these times indicate the additional time ; needed after the next timeout. ; ; This is the only 'public' function. It can be called from a job or from ; a task or other interrupt. It disables interrupts to maintain the integrity ; of the taskList.
;----------------- --------------------------------------------------------WAITLIST 02232 02233 02234 02235 02236 02237 02240 02241 2232 5 2233 3 2234 5 2235 2236 2237 2240 2241 3 2 6 1 0 0,0102 1 0,0001 0 0,0100 0 1,2050 1,2176 0,0001 0,0000 1,2343 0 1 0 0 1 EQU TS XCH TS CAF IND EX AD CCS TC * WL_AT_newTime Q WL_AT_saveQ ZERO WL_tskLstEnd TSKADDR A WL_AT_done
; Calculate time r emaining until currently scheduled time-out. 02242 02243 02244 2242 3 2243 6 2244 5 1,2050 0 0,0037 0 0,0103 0 CAF AD TS ZERO TIME3 ; get time WL_AT_timeLeft ; save it, temporarily
; Did TIME3 recent ly overflow? If so, we are inside T3RUPT, or T3RUPT ; is pending. TIME 3 values from 0 - 10437 are not legal, so they ; indicate that an overflow has occurred. 02245 02246 02247 02250 02251 02252 02253 2245 2246 2247 2250 2251 2252 2253 4 6 1 0 0 0 0 1,2203 0,0103 0,0000 1,2264 1,2264 1,2254 1,2264 0 0 0 0 0 0 0 CS AD CCS TC TC TC TC WL_maxTimeOut WL_AT_timeLeft A WL_AT_noOvf WL_AT_noOvf *+2 WL_AT_noOvf
; ; ; ; ;
; TIME3 already ti med-out, so we must be inside T3RUPT, or T3RUPT ; is pending. Just add the new task to the list. No time correction ; is necessary; th e epoch is NOW. 02254 02255 02256 02257 02260 02261 02262 02263 2254 3 2255 6 2256 5 2257 2 2260 3 2261 5 2262 0 2263 0 1,2050 0 0,0102 1 0,0122 0 0,0100 1 0,0000 1 0,0123 1 1,2473 0 1,2343 1 CAF AD TS IND EX CAF TS TCR TC ZERO WL_AT_newTime WL_IS_newTime WL_AT_saveQ 0 WL_IS_newAddr WL_insert WL_AT_done
; set time field in new task record ; indirectly address WL_AT_saveQ ; set addr field in new task record ; add new task to task list
; TIME3 has not ti med out yet. Calculate time remaining until timeout ; (timeout occurs when TIME3 overflows) WL_AT_noOvf 02264 02265 02266 02267 2264 2265 2266 2267 4 6 6 5 0,0103 1,2201 1,2051 0,0103 1 0 1 0 EQU CS AD AD TS * WL_AT_timeLeft ; get -TIME3 WL_maxVal ONE WL_AT_timeLeft ; time left = -TIME3 + %37777 + 1
; Compare that tim e against the timeout for the new task. WL_AT_chkOrder EQU CS AD CCS TC TC TC ; ; ; ; 02276 02277 02300 02301 02302 02303 02304 02305 2276 4 2277 6 2300 5 2301 2 2302 3 2303 5 2304 0 2305 0 0,0103 1 0,0102 1 0,0122 0 0,0100 1 0,0000 1 0,0123 1 1,2473 0 1,2343 1 * WL_AT_newTime WL_AT_timeLeft A WL_AT_mkFirst *+2 *+1
4 6 1 0 0 0
0 0 0 0 0 0
; ; ; ;
compare new task to current >0 (make new task 1st) +0 <0
The new task doe s not need to run before the current time-out, so just add it to t he list. Subtract the remaining time interval from the new task's time, so the new task will have the same epoch as the other tasks on the lis t. CS AD TS IND EX CAF TS TCR TC WL_AT_timeLeft WL_AT_newTime ; make epoch correction WL_IS_newTime ; set time field in new task record WL_AT_saveQ 0 WL_IS_newAddr WL_insert WL_AT_done ; indirectly address WL_AT_saveQ ; set addr field in new task record ; add new task to task list
; The new task nee ds to run prior to the current time-out. Add the time ; remaining to all tasks currently on the list to change their epoch ; to NOW. WL_AT_mkFirst 02306 2306 3 1,2175 0 EQU CAF * WL_tskLstStart ; set pointer to front of list
02307 02310 02311 02312 02313 02314 02315 02316 02317 02320 02321 02322 02323 02324 02325 02326 02327 02330 02331 02332
2307 5 2310 3 2311 5 2312 2313 2314 2315 2316 2317 2320 2321 2322 2323 2324 2325 3 2 6 1 0 0 3 2 6 6 2 5
0,0101 1 1,2177 1 WL_AT_loop 0,0104 1 1,2050 0,0101 0,0001 0,0000 1,2320 1,2333 1,2050 0,0101 0,0000 0,0103 0,0101 0,0000 0 0 0 0 1 0 0 0 1 0 0 1
TS CAF EQU TS CAF IND EX AD CCS TC TC CAF IND EX AD AD IND EX TS XCH AD TS CCS TC
WL_AT_taskPtr WL_numTasks * WL_AT_loopCnt ZERO WL_AT_taskPtr TSKADDR A *+2 WL_AT_schTsk ; loop for number of tasks
; end of list? ; >0 no, so keep going ; +0 yes, add the new task
ZERO WL_AT_taskPtr TSKTIME WL_AT_timeLeft ; time-out = time-out + timeLeft WL_AT_taskPtr TSKTIME WL_AT_taskPtr ; bump task pointer back 1 record WL_taskRecSize WL_AT_taskPtr WL_AT_loopCnt WL_AT_loop ; done fixing the times? ; not yet
; Now that the tas ks all share the same epoch, add the new task to the ; list and call th e scheduler to schedule the next task. WL_AT_schTsk 02333 02334 02335 02336 02337 02340 02341 02342 2333 3 2334 6 2335 5 2336 2 2337 3 2340 5 2341 0 2342 0 1,2050 0 0,0102 1 0,0122 0 0,0100 1 0,0000 1 0,0123 1 1,2473 0 1,2417 1 WL_AT_done 02343 02344 02345 02346 2343 2344 2345 2346 3 6 5 0 0,0100 1,2051 0,0001 0,0000 0 1 0 0 EQU CAF AD TS IND EX CAF TS TCR TCR EQU XCH AD TS RET URN * ZERO WL_AT_newTime WL_IS_newTime WL_AT_saveQ 0 WL_IS_newAddr WL_insert WL_schedTask * WL_AT_saveQ ONE Q
; set time field in new task record ; indirectly address WL_AT_saveQ ; set addr field in new task record ; add new task to task list ; schedule the next task
;----------------- --------------------------------------------------------; WL_TIME3task - T 3 TIMEOUT ; ; Perform WAITLIST activities when TIME3 times-out. Called by the ; T3 interrupt han dler. ;----------------- --------------------------------------------------------WL_TIME3task 02347 02350 02351 02352 2347 2350 2351 2352 3 5 3 5 0,0001 0,0105 0,0015 0,0106 0 0 0 0 EQU XCH TS XCH TS * Q WL_T3_saveQ BANK WL_T3_oldBank
; Execute all time d-out tasks. 02353 2353 0 1,2362 1 TCR WL_runTasks
; Set up TIME3 to overflow at the next task's time-out. ; Adjust the time- outs for all remaining tasks. 02354 02355 02356 02357 02360 02361 2354 0 2355 2356 2357 2360 2361 3 5 3 5 0 1,2417 1 0,0106 0,0015 0,0105 0,0001 0,0000 0 0 0 0 0 TCR XCH TS XCH TS RET URN WL_schedTask WL_T3_oldBank BANK WL_T3_saveQ Q
;----------------- --------------------------------------------------------; WL_runTasks - RU N TIMED-OUT TASK(S) ; ; Runs all tasks t imed-out on WL_taskList. Tasks are removed ; from the list be fore they are run. ;----------------- --------------------------------------------------------WL_runTasks 02362 02363 2362 3 2363 5 0,0001 0 0,0113 1 EQU XCH TS * Q WL_RT_saveQ
; loop, checking t he task on the front of the list. If it is ; timed out, remov e it from the list and run it. WL_RT_loop 02364 02365 02366 02367 02370 02371 02372 2364 2365 2366 2367 2370 2371 2372 3 2 6 1 0 0 0 1,2050 1,2175 0,0000 0,0000 1,2414 1,2373 1,2373 0 1 1 0 1 1 1 EQU CAF IND EX AD CCS TC TC TC * ZERO WL_tskLstStart TSKTIME A WL_RT_done *+2 *+1
; ; ; ;
; This task has ti med out, so run it. 02373 02374 2373 0 2374 5 1,2565 0 0,0114 0 TCR TS WL_remove WL_RT_runAddr ; remove task from list ; save 14-bit address of task to run
; The task address is always 14-bit, so check whether the address falls ; within erasable or fixed-fixed memory. If so, use it as-is; otherwise, ; set the bank reg ister and change the address to 12-bit. 02375 02376 02377 02400 02401 02402 02403 02404 02405 02406 02407 02410 2375 2376 2377 2400 2401 2402 4 6 1 0 0 0 0,0000 1,2102 0,0000 1,2411 1,2403 1,2403 0 0 0 1 1 1 COM AD CCS TC TC TC CAF AD TS MAS K AD TS WL_RT_runIt 02411 02412 2411 2 2412 0 0,0114 1 0,0000 1 TASKOVER 02413 2413 0 1,2364 1 WL_RT_done 02414 02415 02416 2414 3 2415 5 2416 0 0,0113 1 0,0001 0 0,0000 0 EQU IND EX TC EQU TC EQU XCH TS RET URN ; -(14bitAddr)+%6000 bankAddr A WL_RT_runIt *+2 *+1 ZERO WL_RT_runAddr BANK lowAddr bankAddr WL_RT_runAddr * WL_RT_runAddr 0 * WL_RT_loop * WL_RT_saveQ Q ; ; ; ; task is bank addressed? >0 no, just run it, as is +0 yes <0 yes
; set the bank ; get lowest 10-bits of address ; set bits 11,12 for fixed-switchable
; apply indirect address to next instr. ; run the task ; task returns here ; check next task on list
;----------------- --------------------------------------------------------; WL_schedTask - S CHEDULE NEXT TASK ; ; Schedule task on the front of list for the next time-out. Adjust the ; time-out for all other tasks on the list, so they contain the remaining ; time after the n ext timeout. ;----------------- --------------------------------------------------------WL_schedTask 02417 02420 02421 02422 02423 02424 02425 02426 02427 02430 02431 02432 2417 3 2420 5 2421 2422 2423 2424 2425 2426 2427 2430 2431 2432 3 2 6 1 0 0 3 2 6 5 0,0001 0 0,0107 1 1,2050 1,2175 0,0001 0,0000 1,2427 1,2466 1,2050 1,2175 0,0000 0,0111 0 1 0 0 1 1 0 1 1 0 EQU XCH TS CAF IND EX AD CCS TC TC CAF IND EX AD TS * Q WL_ST_saveQ
ZERO WL_tskLstStart TSKADDR A ; task scheduled? *+2 ; >0 yes WL_ST_noTask ; +0 no, so we are done ZERO WL_tskLstStart TSKTIME WL_ST_newTime ; save the new task's time-out
; Iterate through all tasks on the list. Subtract the time-out time ; from each task. (The 1st task on the list will now have a time-out ; of zero) 02433 02434 02435 02436 02437 02440 02441 2433 3 2434 5 2435 3 2436 5 2437 3 2440 2 2441 6 1,2175 0 0,0110 1 1,2177 1 WL_ST_loop 0,0112 0 1,2050 0 0,0110 0 0,0001 0 CAF TS CAF EQU TS CAF IND EX AD WL_tskLstStart ; set pointer to front of list WL_ST_taskPtr WL_numTasks * WL_ST_loopCnt ZERO WL_ST_taskPtr TSKADDR ; loop for number of tasks
02442 02443 02444 02445 02446 02447 02450 02451 02452 02453 02454 02455 02456 02457 02460
2442 1 2443 0 2444 0 2445 2446 2447 2450 2451 2452 2453 3 2 6 2 6 2 5
0,0000 0 1,2445 0 1,2461 0 1,2050 0,0110 0,0000 0,0000 0,0111 0,0110 0,0000 0 0 1 1 0 0 1
WL_ST_taskPtr ; bump task pointer back 1 record WL_taskRecSize WL_ST_taskPtr WL_ST_loopCnt WL_ST_loop ; done fixing the times? ; not yet
; Set TIME3 to ove rflow at the time-out of the task on the front ; of the list: TIM E3 = %37777 - WL_ST_newTime + 1 WL_ST_setT3 02461 02462 02463 02464 02465 2461 2462 2463 2464 2465 4 6 6 5 0 0,0111 1,2201 1,2051 0,0037 1,2470 1 0 1 0 0 WL_ST_noTask 02466 02467 2466 3 2467 5 1,2203 1 0,0037 0 WL_ST_done 02470 02471 02472 2470 3 2471 5 2472 0 0,0107 1 0,0001 0 0,0000 0 EQU CS AD AD TS TC EQU CAF TS EQU XCH TS RET URN * WL_ST_newTime WL_maxVal ONE TIME3 WL_ST_done * WL_maxTimeOut TIME3 * WL_ST_saveQ Q
;----------------- --------------------------------------------------------; WL_insert - INSE RT TASK INTO SORTED LIST ; ; Insert a task re cord into the sorted list. Use 'WL_IS_newTime' and ; 'WL_IS_newAddr' to set the fields of record to be inserted. ; Performs an inse rtion sort, with the records sorted by time. ; Lowest times are at the front of the list. If several records ; have the same ti me, the records inserted first will appear first ; in the list. NIL records have a time of NOTASK and a address ; of positive zero . ;----------------- --------------------------------------------------------WL_insert 02473 02474 02475 02476 02477 02500 02501 02502 02503 02504 02505 02506 2473 3 2474 5 2475 3 2476 5 2477 2 2500 6 2501 5 2502 2503 2504 2505 2506 3 2 6 1 0 0,0001 0 0,0124 0 1,2176 0 0,0125 1 0,0000 1 1,2174 1 0,0126 1 1,2050 0,0125 0,0001 0,0000 1,2562 0 0 0 0 1 EQU XCH TS CAF TS EXT END SU TS CAF IND EX AD CCS TC * Q WL_IS_saveQ WL_tskLstEnd WL_IS_taskPtr
WL_taskRecSize ; set pointer to rec in front of it WL_IS_taskPtr2 ZERO WL_IS_taskPtr TSKADDR A WL_IS_done
; Work from the ba ck of the list to the front, pushing each record ; to the back unti l the insertion point is found. 02507 02510 02511 02512 02513 02514 02515 02516 2507 3 2510 5 2511 2512 2513 2514 2515 2516 3 2 6 1 0 0 1,2200 1 WL_IS_loop 0,0127 0 1,2050 0,0126 0,0001 0,0000 1,2517 1,2541 0 0 0 0 0 0 CAF EQU TS CAF IND EX AD CCS TC TC WL_numTasks1 * WL_IS_loopCnt ; loop for number of tasks minus 1
ZERO WL_IS_taskPtr2 TSKADDR A ; previous record is NIL? *+2 ; no, so check it WL_IS_bumpPtr ; yes, so skip to next record
; Is this the inse rtion point? 02517 02520 02521 2517 4 2520 2 2521 6 0,0122 1 0,0126 0 0,0000 1 CS IND EX AD WL_IS_newTime WL_IS_taskPtr2 TSKTIME
1 0 0 0 0
0 0 1 1 1
CCS TC TC TC TC
; ; ; ; ;
found insertion point? >0 no, keep checking +0 yes <0 yes -0 yes
; No, bump the rec ord toward the back of the list. 02527 02530 02531 02532 02533 02534 02535 02536 02537 02540 2527 2530 2531 2532 2533 2534 2535 2536 2537 2540 3 2 6 2 5 3 2 6 2 5 1,2050 0,0126 0,0000 0,0125 0,0000 1,2050 0,0126 0,0001 0,0125 0,0001 0 0 1 0 1 0 0 0 0 0 WL_IS_bumpPtr 02541 02542 02543 02544 02545 02546 02547 02550 02551 2541 2542 2543 2544 3 2 6 5 0,0125 0,0000 1,2174 0,0125 1 1 1 1 CAF IND EX AD IND EX TS CAF IND EX AD IND EX TS EQU XCH EXT END SU TS EXT END SU TS CCS TC ; Insert new recor d. WL_IS_insRec 02552 02553 02554 02555 02556 02557 02560 02561 2552 2553 2554 2555 2556 2557 2560 2561 3 6 2 5 3 6 2 5 1,2050 0,0122 0,0125 0,0000 1,2050 0,0123 0,0125 0,0001 0 0 0 1 0 1 0 0 WL_IS_done 02562 02563 02564 2562 3 2563 5 2564 0 0,0124 0 0,0001 0 0,0000 0 EQU CAF AD IND EX TS CAF AD IND EX TS EQU XCH TS RET URN * ZERO WL_IS_newTime WL_IS_taskPtr TSKTIME ZERO WL_IS_newAddr WL_IS_taskPtr TSKADDR * WL_IS_saveQ Q ZERO WL_IS_taskPtr2 TSKTIME WL_IS_taskPtr TSKTIME ; copy time field ZERO WL_IS_taskPtr2 TSKADDR WL_IS_taskPtr TSKADDR ; copy address field * WL_IS_taskPtr WL_taskRecSize WL_IS_taskPtr
WL_taskRecSize ; set pointer to record in front of it WL_IS_taskPtr2 WL_IS_loopCnt WL_IS_loop ; done bumping tasks backward? ; not yet
;----------------- --------------------------------------------------------; WL_remove - REMO VE TASK FROM FRONT OF LIST ; ; Returns the addr ess of the task in register A. If the list is ; empty, it return s zero in A. If a task is removed from the list, ; the remaining ta sks are moved up to the front. ;----------------- --------------------------------------------------------WL_remove 02565 02566 02567 02570 02571 02572 2565 3 2566 5 2567 3 2570 5 2571 6 2572 5 0,0001 0 0,0115 1 1,2175 0 0,0116 1 1,2174 1 0,0117 0 EQU XCH TS CAF TS AD TS * Q WL_RM_saveQ
WL_tskLstStart ; set pointer to front of list WL_RM_taskPtr WL_taskRecSize ; set pointer to next rec behind it WL_RM_taskPtr2
; Save the address of record at the front of the list. 02573 02574 02575 02576 02577 02600 02601 2573 2574 2575 2576 3 2 6 5 1,2050 0,0116 0,0001 0,0121 0 0 0 0 CAF IND EX AD TS CCS TC TC ZERO WL_RM_taskPtr TSKADDR WL_RM_retval A *+2 WL_RM_done
; get address of 1st task ; list empty? ; >0, no ; +0, yes, so exit
; Loop through the remaining records in the task list and ; bubble them up t o the front. 02602 02603 2602 3 2603 5 1,2200 1 WL_RM_loop 0,0120 1 CAF EQU TS WL_numTasks1 * WL_RM_loopCnt ; loop for number of tasks minus 1
02604 02605 02606 02607 02610 02611 02612 02613 02614 02615 02616 02617 02620 02621 02622 02623 02624 02625 02626 02627
2604 2605 2606 2607 2610 2611 2612 2613 2614 2615
3 2 6 2 5 3 2 6 2 5
1,2050 0,0117 0,0000 0,0116 0,0000 1,2050 0,0117 0,0001 0,0116 0,0001
0 1 1 0 1 0 1 0 0 0
ZERO WL_RM_taskPtr2 TSKTIME WL_RM_taskPtr TSKTIME ; copy time field ZERO WL_RM_taskPtr2 TSKADDR WL_RM_taskPtr TSKADDR ; copy address field A *+2 WL_RM_done ; remainder of list empty? ; >0, no ; +0, yes, so exit
2616 1 2617 0 2620 0 2621 3 2622 6 2623 5 2624 6 2625 5 2626 1 2627 0
0,0000 0 1,2621 0 1,2636 0 0,0116 1 1,2174 1 0,0116 1 1,2174 1 0,0117 0 0,0120 0 1,2603 0
WL_RM_taskPtr ; bump task pointer back 1 record WL_taskRecSize WL_RM_taskPtr WL_taskRecSize ; set pointer to record behind it WL_RM_taskPtr2 WL_RM_loopCnt WL_RM_loop ; done bumping tasks upward? ; not yet
; Since we removed a record, the last record on the list ; should be NIL. 02630 02631 02632 02633 02634 02635 2630 3 2631 2 2632 5 2633 3 2634 2 2635 5 1,2202 0 0,0116 0 0,0000 1 1,2050 0 0,0116 0 0,0001 0 WL_RM_done 02636 02637 02640 02641 2636 2637 2640 2641 3 5 3 0 0,0115 0,0001 0,0121 0,0000 1 0 0 0 CAF IND EX TS CAF IND EX TS WL_maxDelay WL_RM_taskPtr TSKTIME ZERO WL_RM_taskPtr TSKADDR
EQU * XCH WL_RM_saveQ TS Q ; restore return address XCH WL_RM_retval ; return task address in A RET URN INC L exec_f.asm ; EXEC ;================= ========================================================= ; EXEC (file:exec_ f.asm) ; ; Version: 1.0 ; Author: John P ultorak ; Date: 04/26/ 2002 ; ; PURPOSE: ; Constants and so urce code for EXEC. ; ; Non-preemptive m ultitasking routines, originally implemented by J. H. ; Laning, Jr. for AGC3 and later adapted for AGC4. Briefly discussed in ; R-393, which giv es some of the software interfaces into the ; multitasking. Th is is my own recreation, and it only includes the job ; scheduling. The original EXEC also includes memory management for the ; eraseable memory ; this is not reproduced here. ; ; Overview: schedu led elements are called 'jobs'. Up to 7 jobs can be ; concurrently sch eduled. An 8th 'dummy' job is always scheduled. Each ; job has an assig ned priority (1-n, where 1 is the lowest priority). ; The highest prio rity job always executes. When that job terminates, ; the next highest priority job is selected for execution. If several ; jobs have the sa me priority, they are executed round-robin. ; ; A job is schedul ed for execution by calling 'NOVAC' and ; furnishing the j ob priority and starting address. ; L XCH JOB_PRIORITY ; L+1 TC NOVAC ; L+2 DS JOB_ADDRESS ; L+3 ... execution resumes here ; ; JOB_PRIORITY = a positive integer from %3 - %37776 where a higher number ; indicates hig her priority. Priorities below 3 are reserved for ; internal EXEC use: 0=no job, 1=sleeping job, 2=dummy job. ; Priority %377 77 is also reserved for woken jobs. ; JOB_ADDRESS = st arting address of the job. ; ; **** WARNING *** * If NOVAC is not being called from an interrupt, be sure to ; inhibit interrup ts before calling it to protect the integrity of the list. ; ; When a new job i s added, the new job's record (core set) is ; initialized with a copy of the current job's record (MPAC and other ; parameters), exc ept for the new job priority and address, which are ; set by the 'add job' routine. Therefore, data can be stored into
; MPAC prior to st arting a new job as a method of passing data into ; the new job. ; ; Jobs terminate t hemselves by jumping to ENDOFJOB. This removes them ; from the EXEC sc heduler: ; TC ENDOFJOB ; ; Jobs can suspend themselves (yield to a higher priority job) by ; executing the fo llowing sequence. If there is no other job of ; higher priority, executing of the yielded job resumes at L+2 ; L CCS newJob ; L+1 TC CHANG1 ; L+2 ... execution resumes here ; ; If there is no o ther job of equal or higher priority, the branch is ; not taken. ; ; Jobs can put the mselves to sleep by calling JOBSLEEP. The address ; where execution of the sleeping job should resume must be in register ; A before calling JOBSLEEP. The job will remain sleeping until JOBWAKE ; is called: ; ; L CAF WAKECADR ; L+1 TC JOBSLEEP ; (does not return from JOBSLEEP) ; ; Sleeping jobs ar e awakened by calling JOBWAKE. The address where ; execution of the sleeping job should resume must be in register A. ; JOBWAKE returns to the address after the call and execution continues ; for the calling job. The job that was sleeping will now be the next ; job to execute. ; ; L CAF WAKECADR ; L+1 TC JOBWAKE ; L+2 ... execution continues here ; ;================= ========================================================= 02642 02643 02644 02645 02646 02647 02650 02651 02652 02653 2642 2643 2644 2645 2646 2647 2650 2651 2652 2653 37777 1 EX_WAKE_PRIO 00002 0 EX_DUMMY_PRIO 00001 0 EX_SLEEP_PRIO DS DS DS %37777 %00002 %00001 EX_currentJob ; waking job priority (highest) ; dummy job priority (lowest runnable) ; sleeping job; must be < dummy ; starting address for current job
00130 0 EX_jobCurStart DS 00015 00300 00307 00306 00006 00005 0 1 0 1 1 1 EX_jobRecSize EX_jobLstStart EX_jobLstEnd EX_jobLstEnd1 EX_numJobs EX_numJobs1 DS DS DS DS DS DS
JRECSZ ; size of a job record (words) EX_jobList ; starting address for jobList MAXJOBS+EX_jobList MAXJOBS-1+EX_jobList MAXJOBS-1 ; init loop counter for all jobs MAXJOBS-2 ; init loop counter for all jobs - 1
02654 02655
2654 2655
; enumerated types for setting change flag: 00001 0 EX_changeJob DS CHGJOB ; change job 00000 1 EX_keepJob DS KEEPJOB ; keep job
;----------------- --------------------------------------------------------; EX_exec -- EXEC SCHEDULER ; ; Executes the hig hest priority job. Enables interrupts while the job is ; running. Once ca lled, this function never returns. ;----------------- --------------------------------------------------------EX_exec EQU * ; entry point
; Add a dummy job (lowest priority) that never terminates. 02656 02657 02660 02661 2656 3 2657 0 2660 2661 2 1,2643 1,3162 03510 0,0000 1 1 0 0 CAF TC DS INH INT EX_DUMMY_PRIO NOVAC dumJob ; job priority ; 14 bit job address ; inhibit RUPTs enab by addJob
; Get the next job to run. EX_MN_findJob 02662 2662 0 1,3410 1 EQU TCR * EX_remove
; compare priority of current job to priority of next waiting job. ; If next job has same priority as current job, set the newJob ; flag so they wil l be scheduled round-robin. 02663 02664 02665 02666 2663 4 2664 2 2665 2 2666 6 0,0143 0 1,2647 1 0,0000 0 0,0143 1 CS IND EX IND EX AD PRIORITY ; get priority of current job
1 0 0 0 0
0 0 0 0 0
; ; ; ; ;
next job has equal priority? >0 (error!) +0 yes, set flag <0 no, clear flag -0 yes, set flag
02677 02700
2677 3 2700 5
1,2654 1 0,0307 0
; Start the job. I nterrupts are reenabled before 'EX_curJobPtr' is ; referenced, but the interrupts can only call 'NOVAC' which does ; not change 'EX_c urJobPtr'. ; The job address is always 14-bit, so check whether the address falls ; within erasable or fixed-fixed memory. If so, use it as-is; otherwise, ; set the bank reg ister and change the address to 12-bit. EX_MN_runJob 02701 02702 02703 02704 02705 02706 02707 02710 02711 02712 02713 02714 02715 02716 02717 2701 3 2702 6 2703 5 2704 2705 2706 2707 2710 2711 4 6 1 0 0 0 1,2050 0 0,0140 1 0,0333 1 0,0000 1,2102 0,0000 1,2720 1,2712 1,2712 0 0 0 0 1 1 EQU CAF AD TS COM AD CCS TC TC TC CAF AD TS MAS K AD TS EX_MN_runIt 02720 02721 02722 2720 2 2721 2 2722 0 0,0000 1 0,0333 0 0,0000 1 EQU REL INT IND EX TC * ZERO LOC EX_MN_runAddr
bankAddr A EX_MN_runIt *+2 *+1 ZERO EX_MN_runAddr BANK lowAddr bankAddr EX_MN_runAddr * EX_MN_runAddr 0
; ; ; ; ;
-(14bitAddr)+%6000 job is bank addressed? >0 no, just run it, as is +0 yes <0 yes
; set the bank ; get lowest 10-bits of address ; set bits 11,12 for fixed-switchable
; enable interrupts ; apply indirect address to next instr. ; run the job
; Job is terminate d. Delete the job record. ENDOFJOB 02723 02724 2723 2 2724 0 0,0000 0 1,2662 1 ; ; ; ; EQU INH INT TC * EX_MN_findJob ; inhibit interrupts ; get next job
job is sleeping. Keep the job record, but drop the priority so it is below the pri ority of the dummy job. This will keep the job from running unt il JOBWAKE is called. The address where it should resume running w hen awoken is in register A. EQU INH INT TS CAF TS TS TC * LOC EX_SLEEP_PRIO PRIORITY EX_IS_newPrio EX_MN_mvRec ; inhibit interrupts ; save restart address
JOBSLEEP 02725 02726 02727 02730 02731 02732 2725 2 2726 5 2727 3 2730 5 2731 5 2732 0 0,0000 0 0,0140 1 1,2644 0 0,0143 1 0,0346 0 1,2757 0
; finish up
; Job is suspended . Keep the job record, but update the address, so ; execution will r esume at the point after suspension. CHANG1 02733 02734 02735 02736 02737 02740 02741 02742 02743 02744 02745 2733 2 2734 3 2735 5 2736 2737 2740 2741 2742 2743 4 6 1 0 0 0 0,0000 0 0,0001 0 0,0333 1 0,0000 1,2102 0,0000 1,2750 1,2744 1,2744 0 0 0 1 1 1 EQU INH INT XCH TS COM AD CCS TC TC TC CS AD * ; inhibit interrupts Q EX_MN_runAddr ; save job's 12 bit restart address
; ; ; ; ;
-(12bitAddr)+%6000 job is bank addressed? >0 no, just save it, as is +0 yes <0 yes
2744 4 2745 6
1,2102 1 0,0333 1
; 12bitAddr - %6000
02746 02747
2746 6 2747 0
02750 02751
2750 3 2751 6
; given the priori ty, find the insertion point in the list. Copy ; the current job into the list at the correct insertion point. EX_MN_mvRec 02757 02760 2757 0 2760 5 1,3332 0 0,0352 0 EQU TCR TS * EX_findIns EX_IS_jobPtr
; copy all fields in current record to list 02761 02762 2761 3 2762 5 1,2646 1 0,0334 0 EX_MN_loop3 02763 02764 02765 02766 2763 2764 2765 2766 1 0 0 5 0,0334 1,2766 1,3002 0,0334 1 1 0 0 XCH TS EQU CCS TC TC TS EX_jobRecSize EX_MN_field * EX_MN_field *+2 EX_MN_done3 EX_MN_field
; copy this field to list 02767 02770 02771 02772 02773 02774 02775 02776 02777 03000 03001 2767 2770 2771 2772 2773 2774 2775 2776 2777 3000 3 2 6 6 5 3 2 6 2 5 1,2050 0,0352 0,0000 0,0334 0,0335 1,2050 0,0334 0,0130 0,0335 0,0130 0 1 1 0 1 0 1 0 0 0 CAF IND EX AD AD TS CAF IND EX AD IND EX TS TC EX_MN_done3 03002 3002 0 1,2662 1 EQU TC ZERO EX_IS_jobPtr 0 EX_MN_field EX_MN_findx ZERO EX_MN_field EX_currentJob EX_MN_findx EX_currentJob EX_MN_loop3 * EX_MN_findJob
; get index to record in list ; add field displacement ; save index to field in list
3001 0
1,2763 1
;----------------- --------------------------------------------------------; JOBWAKE - wake u p the job identified by address in register A ; ; Search jobList f or a job with address matching the address in A. ; If found, bump t he priority up to the highest level, so the job ; will be the next to run. ; ; This is a 'publi c' function. It assumes that interrupts are already ; disabled before it is called. Disabling interrupts during JOBWAKE ; is necessary to preserve the integrity of the joblist. ;----------------- --------------------------------------------------------JOBWAKE 03003 03004 03005 3003 5 3004 3 3005 5 0,0312 1 0,0001 0 0,0310 0 EQU TS XCH TS * EX_JW_CADR Q EX_JW_saveQ
; Search the jobli st for the job to wake (job address matches ; EX_JW_CADR). 03006 03007 03010 03011 03012 03013 03014 03015 3006 3 3007 5 3010 3 3011 5 3012 6 3013 5 3014 3 3015 5 1,2050 0 0,0313 0 1,2651 1 0,0314 1 1,2046 1 0,0315 0 1,2653 0 EX_JW_loop 0,0311 1 CAF TS CAF TS AD TS CAF EQU TS ZERO EX_JW_foundit EX_jobLstEnd1 EX_JW_jobPtr NEG1 EX_JW_jobPtr2 EX_numJobs1 * EX_JW_loopCnt
; the front of t he list. ; if foundit=1, th e job has been found and removed from the list. ; push all jobs in front of the removed job one step to the back ; to fill in the gap and to make room at the front of the list ; for the awoken job. 03016 03017 3016 1 3017 0 0,0313 1 1,3035 1 CCS TC ; Is this the job? 03020 03021 03022 03023 03024 03025 03026 03027 3020 3021 3022 3023 3024 3025 3026 3027 4 2 2 6 1 0 0 0 0,0312 0,0314 0,0000 0,0140 0,0000 1,3041 1,3030 1,3041 0 0 0 1 0 1 1 1 CS IND EX IND EX AD CCS TC TC TC ; found the job to wake. 03030 03031 3030 3 3031 5 1,2051 1 0,0313 0 CAF TS ONE EX_JW_foundit EX_JW_CADR EX_JW_jobPtr 0 LOC A EX_JW_bumpPtr *+2 EX_JW_bumpPtr EX_JW_foundit EX_JW_moveRec ; already found job to wake? ; >0, yes
; ; ; ;
; save record inde x for awoken job 03032 03033 03034 3032 2 3033 3 3034 5 0,0314 0 0,0000 1 0,0316 0 IND EX XCH TS ; bump prior recor d back EX_JW_moveRec 03035 03036 03037 03040 3035 3036 3037 3040 2 3 2 3 0,0315 0,0000 0,0314 0,0000 1 1 0 1 EX_JW_bumpPtr 03041 03042 03043 03044 03045 03046 03047 03050 03051 03052 03053 03054 03055 3041 3 3042 6 3043 5 3044 6 3045 5 3046 1 3047 0 3050 1 3051 0 3052 0 3053 3 3054 2 3055 5 0,0314 1 1,2046 1 0,0314 1 1,2046 1 0,0315 0 0,0311 0 1,3015 0 0,0313 1 1,3053 1 1,3056 1 0,0316 0 1,2647 1 0,0000 1 EX_JW_done EQU IND EX XCH IND EX XCH EQU XCH AD TS AD TS CCS TC CCS TC TC XCH IND EX TS EQU * EX_JW_jobPtr2 0 EX_JW_jobPtr 0 * EX_JW_jobPtr NEG1 EX_JW_jobPtr NEG1 EX_JW_jobPtr2 EX_JW_loopCnt EX_JW_loop EX_JW_foundit *+2 EX_JW_done EX_JW_jobPtr 0 EX_JW_fndIndx
; done bumping jobs backward? ; not yet ; found job to wake? ; >0, yes ; no
; Is the awoken jo b at the front of the list? ; (If it was alrea dy there before we started searching, 'foundIt' ; will be false (0 ) so we need to make this test). 03056 03057 03060 03061 03062 03063 03064 03065 3056 3057 3060 3061 3062 3063 3064 3065 4 2 2 6 1 0 0 0 0,0312 1,2647 0,0000 0,0140 0,0000 1,3074 1,3066 1,3074 0 1 0 1 0 1 1 1 CS IND EX IND EX AD CCS TC TC TC EX_JW_CADR EX_jobLstStart 0 LOC A EX_JW_return *+2 EX_JW_return
; ; ; ;
; set awoken prior ity and change job flag 03066 03067 03070 03071 03072 03073 3066 3067 3070 3071 3 2 2 5 1,2642 1,2647 0,0000 0,0143 0 1 0 1 CAF IND EX IND EX TS CAF TS EX_JW_return 03074 3074 0 0,0310 0 EQU TC EX_WAKE_PRIO EX_jobLstStart 0 PRIORITY ; set waking priority EX_changeJob newJob * EX_JW_saveQ ; set the change flag
3072 3 3073 5
1,2654 1 0,0307 0
; return
;----------------- --------------------------------------------------------; SPVAC - ADD A JO B TO THE JOBLIST ; ; Similar to NOVAC , but used by VERB 37. The job CADR is in register A. ; The job priority is in NEWPRIO. Return to the address in Q. ; ; NOVAC differs fr om SPVAC, because NOVAC has the job CADR at the address ; in Q, and return s to Q+1. Also, in NOVAC the job priority is in A. ; ; This is a 'publi c' function. It can be called from a job ; or from an inter rupt. ;----------------- --------------------------------------------------------SPVAC 03075 03076 03077 3075 5 3076 3 3077 5 0,0350 1 0,0001 0 0,0317 1 EQU TS XCH TS * EX_IS_newLoc Q EX_AJ_saveQ
; add new job to e nd of list 03100 03101 03102 03103 03104 03105 3100 3101 3102 3103 3 6 5 5 1,2050 0,0360 0,0346 0,0347 0 1 0 1 CAF AD TS TS TCR TS ZERO NEWPRIO EX_IS_newPrio EX_IS_newPrioB ; store new job priority EX_findIns EX_IS_jobPtr ; find insertion point in list ; save address of insertion point
3104 0 3105 5
1,3332 0 0,0352 0
; Initialize relev ant fields in new job. The remaining fields ; should already b e zeroed.
; Initialize field s for new job record. New job inherits copy of ; MPAC from curren t job, so copy all fields in current job to new ; job in list 03106 03107 3106 3 3107 5 1,2646 1 0,0323 0 EX_SP_loop1 03110 03111 03112 03113 3110 3111 3112 3113 1 0 0 5 0,0323 1,3113 1,3127 0,0323 1 1 0 0 XCH TS EQU CCS TC TC TS EX_jobRecSize EX_AJ_field * EX_AJ_field *+2 EX_SP_done1 EX_AJ_field
; copy this field to list 03114 03115 03116 03117 03120 03121 03122 03123 03124 03125 03126 3114 3115 3116 3117 3120 3121 3122 3123 3124 3125 3 2 6 6 5 3 2 6 2 5 1,2050 0,0352 0,0000 0,0323 0,0324 1,2050 0,0323 0,0130 0,0324 0,0130 0 1 1 0 1 0 1 0 0 0 CAF IND EX AD AD TS CAF IND EX AD IND EX TS TC ZERO EX_IS_jobPtr 0 EX_AJ_field EX_AJ_findx ZERO EX_AJ_field EX_currentJob EX_AJ_findx EX_currentJob EX_SP_loop1
; get index to record in list ; add field displacement ; save index to field in list
3126 0
1,3110 1
; now, overwrite f ields in the record with the priority ; and location uni que to this job. EX_SP_done1 03127 03130 03131 03132 03133 03134 03135 03136 03137 03140 03141 03142 03143 03144 03145 3127 3130 3131 3132 3133 3134 3135 3136 3137 3140 3141 3142 3143 3144 3145 3 6 2 2 5 3 6 2 2 5 3 6 2 2 5 1,2050 0,0346 0,0352 0,0000 0,0143 1,2050 0,0347 0,0352 0,0000 0,0144 1,2050 0,0350 0,0352 0,0000 0,0140 0 0 1 0 1 0 1 1 0 0 0 1 1 0 1 EQU CAF AD IND EX IND EX TS CAF AD IND EX IND EX TS CAF AD IND EX IND EX TS * ZERO EX_IS_newPrio EX_IS_jobPtr 0 PRIORITY
ZERO EX_IS_newPrioB EX_IS_jobPtr 0 JOBPRIOBASE ; set nominal priority field ZERO EX_IS_newLoc EX_IS_jobPtr 0 LOC
EX_SP_testFlg 03146 03147 03150 03151 03152 03153 03154 03155 3146 4 3147 3150 3151 3152 3153 6 1 0 0 0 0,0143 0 0,0321 0,0000 1,3154 1,3154 1,3156 1 0 1 1 0
; get -priority of current job ; ; ; ; ; add new >0, +0, <0, positive priority of new job job is highest priority? yes yes no, current job is higher priority
3154 3 3155 5
;----------------- --------------------------------------------------------; FINDVAC - not im plemented ; ;----------------- --------------------------------------------------------03161 3161 0 0,0001 0 FINDVAC TC Q ; just return
;----------------- --------------------------------------------------------; NOVAC - ADD A JO B TO THE JOBLIST ; ; Search jobList f or an empty slot. If found, put the new job in the ; empty slot. If t he new job has the same, or higher, priority than the ; current job, set the change flag to 'CHGJOB' (change jobs at the next ; opportunity). ; ; This is a 'publi c' function. It can be called from a job ; or from an inter rupt. ;----------------- --------------------------------------------------------NOVAC 03162 03163 03164 3162 5 3163 3 3164 5 0,0321 1 0,0001 0 0,0317 1 EQU TS XCH TS * EX_AJ_jobPrio Q EX_AJ_saveQ
; add new job to e nd of list 03165 03166 03167 03170 03171 03172 03173 03174 03175 3165 3166 3167 3170 3 6 5 5 1,2050 0,0321 0,0346 0,0347 0 1 0 1 CAF AD TS TS IND EX CAF TS TCR TS ZERO EX_AJ_jobPrio EX_IS_newPrio EX_IS_newPrioB ; store new job priority EX_AJ_saveQ 0 EX_IS_newLoc EX_findIns EX_IS_jobPtr ; indirectly address addJobQ ; store new job address ; find insertion point in list ; save address of insertion point
; Initialize relev ant fields in new job. The remaining fields ; should already b e zeroed.
; Initialize field s for new job record. New job inherits copy of ; MPAC from curren t job, so copy all fields in current job to new ; job in list 03176 03177 3176 3 3177 5 1,2646 1 0,0323 0 EX_AJ_loop1 03200 03201 03202 03203 3200 3201 3202 3203 1 0 0 5 0,0323 1,3203 1,3217 0,0323 1 0 0 0 XCH TS EQU CCS TC TC TS EX_jobRecSize EX_AJ_field * EX_AJ_field *+2 EX_AJ_done1 EX_AJ_field
; copy this field to list 03204 03205 03206 03207 03210 03211 03212 03213 03214 3204 3205 3206 3207 3210 3211 3212 3213 3214 3 2 6 6 5 3 2 6 2 1,2050 0,0352 0,0000 0,0323 0,0324 1,2050 0,0323 0,0130 0,0324 0 1 1 0 1 0 1 0 0 CAF IND EX AD AD TS CAF IND EX AD IND EX ZERO EX_IS_jobPtr 0 EX_AJ_field EX_AJ_findx ZERO EX_AJ_field EX_currentJob EX_AJ_findx
; get index to record in list ; add field displacement ; save index to field in list
03215 03216
3215 5 3216 0
0,0130 0 1,3200 0
TS TC
EX_currentJob EX_AJ_loop1
; now, overwrite f ields in the record with the priority ; and location uni que to this job. EX_AJ_done1 03217 03220 03221 03222 03223 03224 03225 03226 03227 03230 03231 03232 03233 03234 03235 3217 3220 3221 3222 3223 3224 3225 3226 3227 3230 3231 3232 3233 3234 3235 3 6 2 2 5 3 6 2 2 5 3 6 2 2 5 1,2050 0,0346 0,0352 0,0000 0,0143 1,2050 0,0347 0,0352 0,0000 0,0144 1,2050 0,0350 0,0352 0,0000 0,0140 0 0 1 0 1 0 1 1 0 0 0 1 1 0 1 EQU CAF AD IND EX IND EX TS CAF AD IND EX IND EX TS CAF AD IND EX IND EX TS * ZERO EX_IS_newPrio EX_IS_jobPtr 0 PRIORITY
ZERO EX_IS_newPrioB EX_IS_jobPtr 0 JOBPRIOBASE ; set nominal priority field ZERO EX_IS_newLoc EX_IS_jobPtr 0 LOC
; Set changeflag i f priority of new job >= priority of current job EX_AJ_testFlg 03236 03237 03240 03241 03242 03243 03244 03245 3236 4 3237 3240 3241 3242 3243 6 1 0 0 0 0,0143 0 0,0321 0,0000 1,3244 1,3244 1,3246 1 0 0 0 1 EQU CS AD CCS TC TC TC CAF TS EX_AJ_done2 03246 03247 03250 03251 3246 3247 3250 3251 3 6 5 0 0,0317 1,2051 0,0001 0,0000 1 1 0 0 EQU XCH AD TS RET URN * PRIORITY EX_AJ_jobPrio A *+3 *+2 EX_AJ_done2 EX_changeJob newJob * EX_AJ_saveQ ONE Q
; get -priority of current job ; ; ; ; ; add new >0, +0, <0, positive priority of new job job is highest priority? yes yes no, current job is higher priority
3244 3 3245 5
1,2654 1 0,0307 0
;----------------- --------------------------------------------------------; EX_initEX - INIT IALIZE EXEC ; ; Initialize the e raseable memory segment for EXEC. Necessary in ; case the AGC is restarted. ;----------------- --------------------------------------------------------EX_initEX 03252 03253 03254 03255 03256 03257 3252 3 3253 5 3254 3 3255 5 3256 3 3257 5 0,0001 0 0,0325 0 1,2655 0 0,0307 0 1,2050 0 0,0143 1 EQU XCH TS CAF TS CAF TS * Q EX_IN_saveQ EX_keepJob newJob ZERO PRIORITY
; Iterate through jobList, initialize each element on the list so it ; points to its ow n job record. 03260 03261 03262 03263 03264 03265 03266 03267 03270 03271 03272 03273 03274 03275 3260 3 3261 5 3262 3 3263 6 3264 5 3265 3 3266 5 3267 3270 3271 3272 3273 3 2 5 6 5 1,2647 0 0,0327 1 1,2050 0 1,2646 1 0,0330 1 1,2652 1 EX_IN_loop1 0,0326 0 0,0330 0,0327 0,0000 1,2646 0,0330 1 0 1 1 1 CAF TS CAF AD TS CAF EQU TS XCH IND EX TS AD TS XCH AD EX_jobLstStart ; init pointer to start of list EX_IN_jobPtr ZERO EX_jobRecSize EX_IN_recIndex EX_numJobs * EX_IN_loopCnt ; loop for number of jobs
EX_IN_recIndex EX_IN_jobPtr 0 ; initialize record index EX_jobRecSize EX_IN_recIndex ; bump index to next record EX_IN_jobPtr ONE ; bump job pointer back 1 record
3274 3 3275 6
0,0327 1 1,2051 1
TS CCS TC
; Iterate through job records, initialize each field to zero. 03301 03302 03303 03304 3301 3 3302 5 3303 3 3304 5 1,2647 0 0,0327 1 1,2652 1 EX_IN_loop2 0,0326 0 CAF TS CAF EQU TS EX_jobLstStart ; init pointer to start of list EX_IN_jobPtr EX_numJobs * EX_IN_loopCnt ; loop for number of jobs
; loop for number of fields in each record 03305 03306 3305 3 3306 5 1,2646 1 0,0331 0 EX_IN_loop3 03307 03310 03311 03312 3307 3310 3311 3312 1 0 0 5 0,0331 1,3312 1,3324 0,0331 1 1 1 0 XCH TS EQU CCS TC TC TS EX_jobRecSize EX_IN_field * EX_IN_field *+2 EX_IN_done EX_IN_field
; set the field to zero 03313 03314 03315 03316 03317 03320 03321 03322 03323 3313 3314 3315 3316 3317 3320 3321 3322 3 2 6 6 5 3 2 5 1,2050 0,0327 0,0000 0,0331 0,0332 1,2050 0,0332 0,0130 0 0 1 0 0 0 1 0 CAF IND EX AD AD TS CAF IND EX TS TC ZERO EX_IN_jobPtr 0 EX_IN_field EX_IN_findx ZERO EX_IN_findx EX_currentJob EX_IN_loop3
; clear field
3323 0
1,3307 0
; done clearing al l fields in record, so do next record EX_IN_done 03324 03325 03326 03327 03330 03331 3324 3 3325 6 3326 5 3327 1 3330 0 3331 0 0,0327 1 1,2051 1 0,0327 1 0,0326 1 1,3304 0 0,0325 0 EQU XCH AD TS CCS TC TC * EX_IN_jobPtr ONE EX_IN_jobPtr EX_IN_loopCnt EX_IN_loop2 EX_IN_saveQ
;----------------- --------------------------------------------------------; EX_findIns - FIN D INSERTION POINT INTO SORTED LIST ; ; Insert a job rec ord into the sorted list. Use 'EX_IS_newPrio', ; EX_IS_newPrioB a nd 'EX_IS_newLoc' to set the fields of record to ; be inserted. ; Performs an inse rtion sort, with the records sorted by priority. ; Highest priority is at the front of the list. If several records ; have the same pr iority, the records inserted first will appear first ; in the list. NIL records have a priority of zero. ;----------------- --------------------------------------------------------EX_findIns 03332 03333 03334 03335 03336 03337 03340 03341 03342 03343 03344 03345 3332 3 3333 5 3334 3 3335 5 3336 6 3337 5 3340 3341 3342 3343 3 2 2 6 0,0001 0 0,0351 0 1,2651 1 0,0352 0 1,2046 1 0,0353 1 1,2050 0,0352 0,0000 0,0143 0 1 0 1 EQU XCH TS CAF TS AD TS CAF IND EX IND EX AD CCS TC * Q EX_IS_saveQ EX_jobLstEnd1 EX_IS_jobPtr NEG1 EX_IS_jobPtr2 ZERO EX_IS_jobPtr 0 PRIORITY A EX_FI_done
3344 1 3345 0
0,0000 0 1,3405 0
; Work from the ba ck of the list to the front, pushing each record ; to the back unti l the insertion point is found. 03346 3346 3 1,2653 0 EX_FI_loop CAF EQU EX_numJobs1 * ; loop for number of jobs minus 1
; Is this the inse rtion point? 03357 03360 03361 03362 03363 03364 03365 03366 03367 3357 3360 3361 3362 3363 3364 3365 3366 3367 4 2 2 6 1 0 0 0 0 0,0346 0,0353 0,0000 0,0143 0,0000 1,3405 1,3405 1,3370 1,3405 1 0 0 1 0 0 0 0 0 CS IND EX IND EX AD CCS TC TC TC TC EX_IS_newPrio EX_IS_jobPtr2 0 PRIORITY A EX_FI_insRec EX_FI_insRec *+2 EX_FI_insRec
; ; ; ; ;
found insertion point? >0 yes +0 yes <0 no, keep checking -0 yes
; No, bump the rec ord toward the back of the list. 03370 03371 03372 03373 03374 03375 3370 3371 3372 3373 3374 3375 2 3 2 3 2 3 0,0353 0,0000 0,0352 0,0000 0,0353 0,0000 0 1 1 1 0 1 EX_FI_bumpPtr 03376 03377 03400 03401 03402 03403 03404 3376 3 3377 6 3400 5 3401 6 3402 5 3403 1 3404 0 0,0352 0 1,2046 1 0,0352 0 1,2046 1 0,0353 1 0,0354 1 1,3347 1 IND EX XCH IND EX XCH IND EX XCH EQU XCH AD TS AD TS CCS TC EX_IS_jobPtr2 0 EX_IS_jobPtr 0 EX_IS_jobPtr2 0 * EX_IS_jobPtr NEG1 EX_IS_jobPtr NEG1 EX_IS_jobPtr2 EX_IS_loopCnt EX_FI_loop
; New record shoul d be inserted at EX_IS_jobPtr. EX_FI_insRec EX_FI_done 03405 03406 03407 3405 3 3406 6 3407 0 1,2050 0 0,0352 0 0,0351 0 EQU EQU CAF AD TC * * ZERO EX_IS_jobPtr EX_IS_saveQ
;----------------- --------------------------------------------------------; EX_remove - REMO VE JOB FROM FRONT OF LIST ; ; Remove job from front of list and copy it to the current job. Bubble ; any remaining jo bs toward the front of the list. ;----------------- --------------------------------------------------------EX_remove 03410 03411 03412 03413 03414 03415 3410 3 3411 5 3412 3 3413 5 3414 6 3415 5 0,0001 0 0,0336 1 1,2647 0 0,0337 0 1,2051 1 0,0340 0 EQU XCH TS CAF TS AD TS * Q EX_RM_saveQ
EX_jobLstStart ; set pointer to front of list EX_RM_jobPtr ONE EX_RM_jobPtr2 ; set pointer to next rec behind it
; Dequeue the reco rd at the top of the list (the next job to run). ; Make it the curr ent job by copying it to the current job record. 03416 03417 3416 3 3417 5 1,2646 1 0,0344 1 EX_RM_loop1 03420 03421 03422 03423 3420 3421 3422 3423 1 0 0 5 0,0344 1,3423 1,3437 0,0344 0 1 1 1 XCH TS EQU CCS TC TC TS EX_jobRecSize EX_RM_field * EX_RM_field *+2 EX_RM_done1 EX_RM_field
; copy field from list to current job 03424 03425 03426 3424 3 3425 2 3426 6 1,2050 0 0,0337 1 0,0000 1 CAF IND EX AD ZERO EX_RM_jobPtr 0
6 5 3 2 6 2 5
1 0 0 1 0 0 0
3436 0
1,3420 1
; done copying rec ord for current job. Restore the current job to ; its default prio rity, in case it was previously elevated. EX_RM_done1 03437 03440 03441 03442 03443 03444 3437 3 3440 6 3441 5 3442 2 3443 3 3444 5 1,2050 0 0,0144 0 0,0143 1 0,0337 1 0,0000 1 0,0341 1 EQU CAF AD TS IND EX XCH TS * ZERO JOBPRIOBASE PRIORITY EX_RM_jobPtr 0 EX_RM_savePtr
; Loop through the remaining records in the job list and ; bubble them up t o the front. 03445 03446 3445 3 3446 5 1,2653 0 EX_RM_loop2 0,0342 1 CAF EQU TS EX_numJobs1 * EX_RM_loopCnt ; loop for number of jobs minus 1
03447 03450 03451 03452 03453 03454 03455 03456 03457 03460 03461 03462 03463 03464
2 3 2 5
1 1 1 1
EX_RM_jobPtr2 0 EX_RM_jobPtr 0 A *+2 EX_RM_done2 EX_RM_jobPtr ONE EX_RM_jobPtr ONE EX_RM_jobPtr2 EX_RM_loopCnt EX_RM_loop2 ; remainder of list empty? ; >0, no ; +0, yes, so exit ; bump job pointer back 1 record
3453 1 3454 0 3455 0 3456 3 3457 6 3460 5 3461 6 3462 5 3463 1 3464 0
0,0000 0 1,3456 0 1,3465 0 0,0337 0 1,2051 1 0,0337 0 1,2051 1 0,0340 0 0,0342 0 1,3446 1
; Since we removed a record, the last record on the list ; should be NIL. EX_RM_done2 03465 03466 03467 3465 3 3466 2 3467 5 0,0341 1 0,0337 1 0,0000 1 EQU XCH IND EX TS * EX_RM_savePtr EX_RM_jobPtr 0
; move the index for the top record ; to the bottom of the list
; set all fields i n NIL record to zero 03470 03471 3470 3 3471 5 1,2646 1 0,0344 1 EX_RM_loop3 03472 03473 03474 03475 3472 3473 3474 3475 1 0 0 5 0,0344 1,3475 1,3507 0,0344 0 1 0 1 XCH TS EQU CCS TC TC TS EX_jobRecSize EX_RM_field * EX_RM_field *+2 EX_RM_done3 EX_RM_field
; set this field t o zero 03476 03477 03500 03501 03502 03503 03504 03505 03506 3476 3477 3500 3501 3502 3503 3504 3505 3 2 6 6 5 3 2 5 1,2050 0,0337 0,0000 0,0344 0,0345 1,2050 0,0345 0,0130 0 1 1 1 0 0 1 0 CAF IND EX AD AD TS CAF IND EX TS TC EX_RM_done3 03507 3507 0 0,0336 1 EQU TC ZERO EX_RM_jobPtr 0 EX_RM_field EX_RM_findx ZERO EX_RM_findx EX_currentJob EX_RM_loop3 * EX_RM_saveQ
; clear field
3506 0
1,3472 0
; return
;----------------- ---------------------------------------------------------
; DUMMY JOB - runs at the lowest priority and never terminates. Ensures ; that there is al ways at least one job executing. Sleeping jobs are ; given a lower pr iority than the dummy job. ; ; The dummy job co ntrols the computer activity light on the DSKY. When ; the dummy job is running, the light is off. When the dummy job is ; preempted by a h igher priority job, the light is on. ; ; I couldn't find good information on the computer activity light ; in COLOSSUS, so this is my best guess concerning its operation. It ; seems consistent witht the MPEG video of the Apollo 11 DSKY. ;----------------- ---------------------------------------------------------
; entering dummy j ob -- turn off computer activity light dumJob 03510 03511 03512 03513 3510 3511 3512 3513 3 6 7 5 1,2050 0,0011 1,3525 0,0011 0 1 1 1 EQU CAF AD MAS K TS * ZERO DSALMOUT NOTACTLT DSALMOUT
; runtime loop for dummy job dumJob1 03514 03515 03516 3514 1 3515 0 3516 0 0,0307 1 1,3517 1 1,3514 1 EQU CCS TC TC * newJob dumJob2 dumJob1
; exiting dummy jo b -- turn on computer activity light dumJob2 03517 03520 03521 03522 03523 03524 03525 3517 3520 3521 3522 4 7 4 5 0,0011 1,3525 0,0000 0,0011 0 1 0 1 EQU CS MAS K COM TS TC TC * DSALMOUT NOTACTLT DSALMOUT CHANG1 dumJob ; exit to run higher priority job ; job done, return here, light off again
DS %77776 ; 1's compliment of bit1 (comp activity l i g h t ) INC L bank_f.asm ; bank intercommunication routines ;================= ========================================================= ; BANK INTERCOMMUN ICATION (file:bank_f.asm) ; ; Version: 1.0 ; Author: John P ultorak ; Date: 01/19/ 2002 ; ; PURPOSE: ; Contains bank in tercommunication routines. ; The source is mi ssing from my (incomplete) listing of COLOSSUS. The ; implementation h ere is inferred from the usage in the COLOSSUS pinball ; routines. Some o f these routines could probably be combined or optimized ; away if I unders tood the pinball software architecture a little better. ;================= ========================================================= ;----------------- --------------------------------------------------------; DXCHJUMP ; Do a bank jump t o the CADR in register A. After the bank jump, the return ; CADR is in regis ter A. Contents of register Q are destroyed. ; This is my attem pt to implement the block I equivalent for ; DCA MY2CADR ; DXCH Z ;... which is used in some places in COLOSSUS to implement bank jumps. In that ; implementation, MY2CADR has the lower portion of the address in MYCADR and ; the bank portion in MY2CADR+1. DCA loads the lower address into A and the ; bank address int o L. DXCH loads the lower address into Z and the bank portion ; into BB (both ba nk register), thereby doing a bank call. After the call, ; the lower return address is in A and the return bank is in L. ;----------------- --------------------------------------------------------DXCHJUMP EQU TS XCH TS XCH TS * ADDRWD1 Q DCRET BANK DCBANK
; put the 12-bit d estination address in ADDRWD1 03533 03534 03535 03536 3533 3534 3535 3536 4 6 1 0 0,0576 1,2102 0,0000 1,3547 1 0 0 1 CS AD CCS TC ADDRWD1 bankAddr A DODXCHCALL ; -(14bitAddr)+%6000 ; CADR is bank addressed? ; >0 no, just run it, as is
TC TC CAF AD TS MAS K AD TS
; set the bank ; get lowest 10-bits of address ; set bits 11,12 for fixed-switchable ; save 12-bit destination address
; put the 14-bit r eturn CADR into A. DODXCHCALL 03547 03550 03551 03552 03553 03554 03555 03556 03557 03560 3547 3550 3551 3552 3553 3554 3555 3556 3557 3560 4 6 1 0 0 0 4 6 6 0 0,0617 1,2102 0,0000 1,3561 1,3555 1,3555 1,2102 0,0617 0,0616 1,3563 0 0 0 0 1 1 1 1 0 1 DC_NOTBANK 03561 03562 03563 03564 3561 3 3562 6 3563 2 3564 0 1,2050 0 0,0617 1 0,0576 1 0,0000 1 EQU CS AD CCS TC TC TC CS AD AD TC EQU CAF AD IND EX TC * DCRET bankAddr A DC_NOTBANK *+2 *+1 bankAddr DCRET DCBANK *+3 * ZERO DCRET ADDRWD1 0
; ; ; ; ; ;
get 12-bit return address -(12bitAddr)+%6000 return address is bank addressed? >0 no, just use it, as is +0 yes <0 yes
; put return CADR in A ; apply indirect address to next instr. ; make the jump
;----------------- --------------------------------------------------------; BANKCALL ; Do a bank jump t o the location referenced by the 14-bit address referenced ; in Q. Does not a ffect register A (but assumes A does not contain an ; overflow). Funct ionally identical to POSTJUMP. ; Usage: ; TC BANKCALL ; bank jump to CADR ; DS MYCADR ; the 14-bit address ; returns here if MYCADR calls TC Q. ; ; Inferred from th e AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968. ;----------------- --------------------------------------------------------BANKCALL 03565 03566 03567 03570 03571 03572 03573 03574 03575 03576 03577 03600 03601 03602 03603 03604 03605 03606 03607 03610 3565 5 3566 2 3567 3 3570 5 3571 3 3572 5 3573 3 3574 5 3575 3576 3577 3600 3601 3602 4 6 1 0 0 0 0,0612 1 0,0001 1 0,0000 1 0,0576 0 0,0001 0 0,0611 1 0,0015 0 0,0610 0 0,0576 1,2102 0,0000 1,3611 1,3603 1,3603 1 0 0 1 1 1 EQU TS IND EX CAF TS XCH TS XCH TS CS AD CCS TC TC TC CAF AD TS MAS K AD TS DOBANKCALL 03611 03612 03613 3611 3 3612 2 3613 0 0,0612 1 0,0576 1 0,0000 1 EQU XCH IND EX TC * BCA Q 0 ADDRWD1 Q BCRET BANK BCBANK ADDRWD1 bankAddr A DOBANKCALL *+2 *+1 ZERO ADDRWD1 BANK lowAddr bankAddr ADDRWD1 * BCA ADDRWD1 0
; save old bank ; -(14bitAddr)+%6000 ; ; ; ; CADR is bank addressed? >0 no, just run it, as is +0 yes <0 yes
; set the bank ; get lowest 10-bits of address ; set bits 11,12 for fixed-switchable
; Jump returns her e; restore the old bank and return 03614 03615 03616 3614 5 3615 3 3616 5 0,0612 1 0,0610 0 0,0015 0 TS XCH TS BCA BCBANK BANK ; save A
; skip CADR
; restore A
;----------------- --------------------------------------------------------; MYBANKCALL ; Functionally ide ntical to BANKCALL. Used for converting the FLASHON/FLASHOFF ; COLOSSUS block I I code to block I. In Block II, the V/N flash is controlled b y ; setting a bit in an I/O channel. In Block I, a bit in the display table must ; be set using _11 DSPIN. Because _11DSPIN is in fixed/switchable memory, but is ; called from fixe d/fixed, a bank call function is needed. The original BANKCAL L ; could not be use d because it is not reentrant and I dont understand its usage ; in COLOSSUS well enough to be certain that FLASHON/FLASHOFF isn't already ; being called som ewhere through BANKCALL. ;----------------- --------------------------------------------------------MYBANKCALL 03624 03625 03626 03627 03630 03631 03632 03633 03634 03635 03636 03637 03640 03641 03642 03643 03644 03645 3624 5 3625 2 3626 3 3627 5 3630 3 3631 6 3632 5 3633 3 3634 5 3635 3 3636 6 3637 5 3640 7 3641 6 3642 5 3643 3 3644 2 3645 0 0,0615 0 0,0001 1 0,0000 1 0,0576 0 0,0001 0 1,2051 1 0,0614 1 0,0015 0 0,0613 0 1,2050 0 0,0576 0 0,0015 0 1,2103 0 1,2102 0 0,0576 0 0,0615 0 0,0576 1 0,0000 1 EQU TS IND EX CAF TS XCH AD TS XCH TS CAF AD TS MAS K AD TS XCH IND EX TC * MBCA Q 0 ADDRWD1 Q ONE MBCRET BANK MBCBANK ZERO ADDRWD1 BANK lowAddr bankAddr ADDRWD1 MBCA ADDRWD1 0
; set the bank ; get lowest 10-bits of address ; set bits 11,12 for fixed-switchable
; Jump returns her e; restore the old bank and return 03646 03647 03650 03651 03652 3646 5 3647 3 3650 5 3651 3 3652 0 0,0615 0 0,0613 0 0,0015 0 0,0615 0 0,0614 1 TS XCH TS XCH TC MBCA MBCBANK BANK MBCA MBCRET ; save A
; restore A
;----------------- --------------------------------------------------------; POSTJUMP ; Do a bank jump t o the location referenced by the 14-bit address referenced ; in Q. Does not affect register A (but assumes A does not contain an ; overflow). Funct ionally identical to BANKCALL ; Usage: ; TC POSTJUMP ; bank jump to CADR ; DS MYCADR ; the 14-bit address ; returns here if MYCADR calls TC Q. ; ; Inferred from th e AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968. ;----------------- --------------------------------------------------------POSTJUMP 03653 03654 03655 03656 03657 03660 03661 03662 03663 03664 03665 03666 3653 5 3654 2 3655 3 3656 5 3657 3 3660 5 3661 3 3662 5 3663 3664 3665 3666 4 6 1 0 0,0607 0 0,0001 1 0,0000 1 0,0576 0 0,0001 0 0,0606 1 0,0015 0 0,0605 1 0,0576 1,2102 0,0000 1,3677 1 0 0 1 EQU TS IND EX CAF TS XCH TS XCH TS CS AD CCS TC * PJA Q 0 ADDRWD1 Q PJRET BANK PJBANK ADDRWD1 bankAddr A DOPOSTJUMP
; save old bank ; -(14bitAddr)+%6000 ; CADR is bank addressed? ; >0 no, just run it, as is
*+2 *+1 ZERO ADDRWD1 BANK lowAddr bankAddr ADDRWD1 * PJA ADDRWD1 0
; set the bank ; get lowest 10-bits of address ; set bits 11,12 for fixed-switchable
; Jump returns her e; restore the old bank and return 03702 03703 03704 03705 03706 03707 03710 03711 3702 5 3703 3 3704 5 3705 3 3706 6 3707 5 3710 3 3711 0 0,0607 0 0,0605 1 0,0015 0 0,0606 1 1,2051 1 0,0001 0 0,0607 0 0,0000 0 TS XCH TS XCH AD TS XCH RET URN PJA PJBANK BANK PJRET ONE Q PJA ; save A
; skip CADR
; restore A
;----------------- --------------------------------------------------------; BANKJUMP ; Do a bank jump t o the location referenced by the 14-bit address in A. ; Usage: ; CADRSTOR DS MYCADR ; ; CAF CADRSTOR ; load the 14-bit address ; TC BANKJUMP ; bank jump to CADR ; returns here if MYCADR calls TC Q ; ; Inferred from th e AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968. ;----------------- --------------------------------------------------------BANKJUMP 03712 03713 03714 03715 03716 03717 03720 03721 03722 03723 03724 03725 03726 03727 03730 03731 03732 3712 5 3713 3 3714 5 3715 3 3716 5 3717 3720 3721 3722 3723 3724 4 6 1 0 0 0 0,0576 0 0,0001 0 0,0604 0 0,0015 0 0,0603 1 0,0576 1,2102 0,0000 1,3733 1,3725 1,3725 1 0 0 0 1 1 EQU TS XCH TS XCH TS CS AD CCS TC TC TC CAF AD TS MAS K AD TS DOBANKJUMP 03733 03734 3733 2 3734 0 0,0576 1 0,0000 1 EQU IND EX TC * ADDRWD1 Q BJRET BANK BJBANK ADDRWD1 bankAddr A DOBANKJUMP *+2 *+1 ZERO ADDRWD1 BANK lowAddr bankAddr ADDRWD1 * ADDRWD1 0
; save old bank ; -(14bitAddr)+%6000 ; ; ; ; CADR is bank addressed? >0 no, just run it, as is +0 yes <0 yes
; set the bank ; get lowest 10-bits of address ; set bits 11,12 for fixed-switchable
; Jump returns her e; restore the old bank and return 03735 03736 03737 03740 03741 3735 3 3736 5 3737 3 3740 5 3741 0 0,0603 1 0,0015 0 0,0604 0 0,0001 0 0,0000 0 XCH TS XCH TS RET URN BJBANK BANK BJRET Q
;----------------- --------------------------------------------------------; DATACALL ; Retrieve memory contents at location referenced by the 14-bit address in A. ; Usage:
; CADRSTOR DS MYCADR ; ; CAF CADRSTOR ; load the 14-bit address ; TC DATACALL ; return data in A ; ; Inferred from th e AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968. ;----------------- --------------------------------------------------------DATACALL 03742 03743 03744 03745 03746 03747 03750 03751 03752 03753 03754 03755 03756 03757 03760 03761 03762 3742 5 3743 3 3744 5 3745 3 3746 5 3747 3750 3751 3752 3753 3754 4 6 1 0 0 0 0,0576 0 0,0001 0 0,0604 0 0,0015 0 0,0603 1 0,0576 1,2102 0,0000 1,3763 1,3755 1,3755 1 0 0 0 0 0 EQU TS XCH TS XCH TS CS AD CCS TC TC TC CAF AD TS MAS K AD TS DODATACALL 03763 03764 03765 03766 03767 03770 03771 3763 3 3764 2 3765 6 3766 3 3767 5 3770 3 3771 0 1,2050 0 0,0576 1 0,0000 1 0,0603 1 0,0015 0 0,0603 1 0,0604 0 EQU CAF IND EX AD XCH TS XCH TC * ADDRWD1 Q BJRET BANK BJBANK ADDRWD1 bankAddr A DODATACALL *+2 *+1 ZERO ADDRWD1 BANK lowAddr bankAddr ADDRWD1 * ZERO ADDRWD1 0 BJBANK BANK BJBANK BJRET
; save old bank ; -(14bitAddr)+%6000 ; ; ; ; CADR is bank addressed? >0 no, just use it, as is +0 yes <0 yes
; set the bank ; get lowest 10-bits of address ; set bits 11,12 for fixed-switchable
; apply indirect address to next instr. ; load the word ; restore the old bank
INC L T4rupt_f.asm ; T4RUPT handler ;================= ========================================================= ; T4RUPT (file:T4r upt_f.asm) ; ; Version: 1.0 ; Author: John P ultorak ; Date: 01/09/ 2002 ; ; PURPOSE: ; Contains T4RUPT handler and DSPOUT subroutine to update DSKY. ;================= ========================================================= ; RELTAB is a pack ed table. RELAYWORD code in upper 4 bits, RELAY code ; in lower 5 bits. In COLOSSUS, p. 129. RELTAB 1 0 0 0 1 1 1 1 1 0 0 1 RELTAB11 EQU DS DS DS DS DS DS DS DS DS DS DS DS * %04025 %10003 %14031 %20033 %24017 %30036 %34034 %40023 %44035 %50037 %54000 %60000
03772 03773 03774 03775 03776 03777 04000 04001 04002 04003 04004 04005
3772 3773 3774 3775 3776 3777 4000 4001 4002 4003 4004 4005
04025 10003 14031 20033 24017 30036 34034 40023 44035 50037 54000 60000
;----------------- --------------------------------------------------------; DK_initDK - INIT IALIZE DSKY ; ; Subroutine initi alizes the eraseable memory segment for DSKY displays. ; Blank DSKY regis ters program, verb, noun, R1, R2, R3. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, Fr esh Start and Restart, p.187. ;----------------- --------------------------------------------------------04006 4006 05265 0 DKTESTINIT DS %5265 ; init DSKY to all zeroes (TEST ONLY)
DK_initDK 04007 04010 04011 04012 04013 4007 3 4010 5 4011 3 4012 5 4013 4 0,0001 0 0,0546 0 1,2060 0 0,0130 0 DSPOFF 1,2065 1 ; 04014 04015 04016 04017 4014 4015 4016 4017 2 5 1 0 0,0130 0,0512 0,0130 2,4012 1 1 1 0
; followed by addi tional DSKY initialization p 187, 188) 04020 04021 04022 04023 04024 04025 04026 04027 04030 04031 04032 04033 04034 4020 4021 4022 4023 4024 4025 4026 4027 4030 4031 4032 3 5 5 5 5 5 5 5 5 5 5 1,2050 0,0465 0,0531 0,0502 0,0504 0,0501 0,0507 0,0510 0,0470 0,0471 0,0532 0 0 0 0 0 0 0 0 1 0 0 CAF TS TS TS TS TS TS TS TS TS TS CAF TS ZERO DSPCNT CADRSTOR REQRET CLPASS DSPLOCK MONSAVE MONSAVE1 VERBREG NOUNREG DSPLIST NOUTCON NOUT
; kill monitor
4033 3 4034 5
1,2105 1 0,0505 1
; set DSKY display bit (sign bit). Word must be negative, but ; not minus zero ( find out where they do this in COLOSSUS) 04035 04036 4035 4 4036 5 1,2051 0 0,0355 1 CS TS ONE FLAGWRD5
; initialize DSPCN T (index into DSPTAB). 04037 04040 04041 4037 3 4040 6 4041 5 1,2050 0 2,4072 0 0,0465 0 CAF AD TS ; schedule 1st T4R UPT 04042 04043 04044 04045 04046 4042 3 4043 5 4044 3 4045 5 4046 0 2,4074 0 0,0040 0 0,0546 0 0,0001 0 0,0000 0 CAF TS XCH TS RET URN _120MRUPT TIME4 DK_IN_saveQ Q ; reschedule interrupt for 120 mSec ZERO TABLNTH DSPCNT
;----------------- --------------------------------------------------------; T4PROG -- T4RUPT PROGRAM ; ; Performs T4RUPT (DSRUPT) functions. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 129. ;----------------- --------------------------------------------------------T4PROG 04047 04050 04051 04052 04053 04054 04055 04056 4047 3 4050 5 4051 0 4052 3 4053 5 4054 3 4055 5 4056 0 0,0001 0 0,0544 1 2,4116 0 2,4074 0 0,0040 0 0,0544 1 0,0001 0 0,0000 0 EQU XCH TS TC CAF TS XCH TS RET URN * Q T4RET DSPOUT _120MRUPT TIME4 T4RET Q
; save return address ; update DSKY display ; reschedule interrupt for 120 mSec
;----------------- --------------------------------------------------------; DSPOUT -- PUTS O UT DISPLAYS ; ; Writes changes i n the software display buffer to the AGC DSKY hardware ; display. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 131. ;----------------- --------------------------------------------------------DSPOUTSR EQU *
NOUT ZERO DSRUPTEM DSPCNT NEG0 DSPCNT * DSPCNT DSPTAB DSPCNT DSPSCAN-2 DSPLAY %12 DSRUPTEM 16372 NOUT DSPOUTEXIT DSRUPTEM TABLNTH DSPSCAN-1 DSPOUTEXIT
; decrement NOUT
; to prevent +0
04065 04066 04067 04070 04071 04072 04073 04074 04075 04076 04077 04100 04101 04102
4065 2 4066 1 4067 1 4070 0 4071 0 4072 4073 1 4074 4075 5 4076 0 4077 5 4100 3 4101 0 4102 0
0,0465 1 0,0512 0 0,0465 1 2,4063 0 2,4103 1 00012 1 TABLNTH 0,0370 1 37764 0 _120MRUPT 0,0505 1 2,4126 0 0,0370 0 2,4072 0 2,4064 1 2,4126 0
; test sign of DSPTAB + DSPCNT ; >0, already displayed, test DSPCNT ; if DSPCNT +, again ; <0, not yet displayed ; dec 10, length of DSPTAB ; if DSRUPTEM=+0, 2nd pass thru DSPTAB ; (DSPCNT=0), +0 into NOUT ; DSRUPTEM=+0, every table entry was che c k e d ; return ; DSRUPTEM=-0, 1st pass thru DSPTAB ; (DSPCNT=0), +0 into DSRUPTEM, pass aga i n
; return
DSPLAY 04103 04104 04105 04106 04107 04110 04111 04112 04113 04114 04115 4103 4104 4105 4106 4107 4110 4111 4112 4113 4114 6 2 5 7 5 3 2 7 6 5 1,2051 0,0465 0,0512 2,4672 0,0370 2,4666 0,0465 1,3772 0,0370 0,0010 1 1 1 1 0 0 1 1 0 0
* ONE DSPCNT DSPTAB LOW11 DSRUPTEM HI5 DSPCNT RELTAB DSRUPTEM OUT0 DSPOUTEXIT
4115 0
2,4126 0
DSPOUT 04116 04117 04120 04121 04122 04123 04124 04125 4116 3 4117 5 4120 4121 4122 4123 4124 4125 1 3 0 1 0 0 0,0001 0 0,0545 0 0,0355 1,2050 2,4126 0,0505 2,4057 2,4126 0 0 0 0 1 0 NODSPOUT DSPOUTEXIT 04126 04127 04130 4126 3 4127 5 4130 0 0,0545 0 0,0001 0 0,0000 0
EQU XCH TS CCS CAF TC CCS TC TC EQU EQU XCH TS RET URN
; save return address ; ; ; ; ; ; no display unless DSKY flag (sign bit) o n >0, DSKY disabled +0, DSKY disabled <0, DSKY enabled, so test NOUT >0, handle display requests +0, no display requests
INC L keyrupt_f.asm ; KEYRUPT handler ;================= ========================================================= ; KEYRUPT (file:ke yrupt_f.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 77. ;================= ========================================================= ;----------------- --------------------------------------------------------; KEYRUPT -- KEYBO ARD INTERRUPT HANDLER ; ; Performs keyRUPT functions. Triggered by a keyboard key entry. N-key ; rollover, implem ented as follows: When an interrupt occurs, the current ; job record is sa ved and then restored when the job resumes after the ; interrupt. The j ob record includes MPAC, a set of general purpose ; registers assign ed to the job. When the keyboard interrupt occurs, the ; interrupt handle r stores the keyboard character in MPAC. A job is then ; started to proce ss the character. The new job copies its MPAC fields from ; the current job, so the character is copied to storage owned by the job. ; When additional keyboard interrupts occur, they start their own jobs. ; Up to 7 jobs can be waiting in a queue for execution, so as many as ; 7 keyboard chara cters can be enqueued for processing. Since all keyboard ; jobs have the sa me priority, they are enqueued in the order received.
; Its OK for the k eyboard handler to modify the MPAC of the interrupted job ; because the inte rrupted job's record is restored at the end of the ; interrupt servic e routine. ; ; Not included in my partial AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, so I had to improvise it from the original flow charts in ; E-1574, p.77. ;----------------- --------------------------------------------------------04131 4131 37776 0 CHRPRIO KEYPROG 04132 04133 4132 3 4133 5 0,0001 0 0,0601 0 DS EQU XCH TS %37776 * Q KEYRET ; priority of CHARIN job (highest)
; prepare to EXEC a job to handle the keystroke. 04134 04135 04136 04137 4134 4135 4136 4137 3 7 3 3 0,0004 2,4664 0,0130 0,0551 0 0 0 0 XCH MAS K XCH XCH IN0 LOW5 MPAC KP_MPAC
; create the job. It terminates when it finishes processing the key. 04140 04141 04142 04143 04144 04145 04146 04147 4140 3 4141 0 4142 4143 3 4144 3 4145 3 4146 5 4147 0 2,4131 0 1,3162 1 12000 1 0,0551 0 0,0130 0 0,0601 0 0,0001 0 0,0000 0 CAF TC CAD R XCH XCH XCH TS RET URN CHRPRIO NOVAC CHARIN KP_MPAC MPAC KEYRET Q ; CHARIN job priority ; 14 bit CHARIN job address
INC L math_f.asm ; DP math routines ;================= ========================================================= ; MATH LIBRARY (fi le:math_f.asm) ; ; Version: 1.0 ; Author: John P ultorak ; Date: 03/01/ 2002 ; ; PURPOSE: ; Contains double precision math routines. ;================= ========================================================= ;----------------- --------------------------------------------------------; TPAGREE ; Force the signs in a triple precision (TP) word to agree. The word is ; in MPAC, MPAC+1, MPAC+2 ; ; The sign of the corrected number is always the sign of the most-significant ; non-zero word. ; ; This isn't inclu ded in my partial COLOSSUS listing, so I had to invent ; my own version. ;----------------- ---------------------------------------------------------
EQU XCH TS
* Q MATH_Q
; return address
; Find the sign to convert to. It will be the sign ; of the most sign ificant non-zero word. TPA_SGN0 04152 04153 04154 04155 04156 4152 4153 4154 4155 4156 1 0 0 0 0 0,0130 2,4157 2,4241 2,4210 2,4241 1 0 1 0 1 EQU CCS TC TC TC TC * MPAC TPA_P0 TPA_SGN1 TPA_M0 TPA_SGN1
; ; ; ;
sign will be + still don't know sign, check MPAC+ 1 sign will be still don't know sign, check MPAC+ 1
; MPAC is non-zero positive, so reconcile signs to a positive number. TPA_P0 04157 04160 04161 04162 04163 04164 4157 4160 4161 4162 4163 1 0 0 0 0 0,0131 2,4250 2,4167 2,4164 2,4167 0 1 0 0 0 EQU CCS TC TC TC TC CAF * MPAC+1 TPA_P1+2 TPA_PZ0 *+2 TPA_PZ0 TPA_MPAC0
; ; ; ;
>0, MPAC+1 is OK, check MPAC+2 +0, <0, fix MPAC+1 -0,
4164 3
2,4317 0
4165 0 4166 0
2,4337 1 2,4250 1
TC TC
TPA_FIXP TPA_P1+2
; MPAC is non-zero positive, MPAC+1 is zero TPA_PZ0 04167 04170 04171 04172 04173 04174 04175 04176 04177 4167 4170 4171 4172 4173 4174 4175 4176 4177 1 0 0 0 3 5 3 5 0 0,0132 2,4175 2,4173 2,4200 1,2050 0,0132 1,2050 0,0131 0,0577 0 0 0 1 0 1 0 1 1 EQU CCS TC TC TC CAF TS CAF TS TC * MPAC+2 *+5 *+2 TPA_PZ0FIX ZERO MPAC+2 ZERO MPAC+1 MATH_Q
; >0, zero MPAC+1, MPAC+2 is OK ; +0, MPAC+1, +2 both zero ; <0, ; make sure they're both +0
; MPAC is non-zero positive, MPAC+1 is zero, MPAC+2 is non-zero negative. ; Solution: borrow from MPAC, transfer borrowed value to MPAC+1, but also ; borrow from MPAC +1, use borrowed value to correct MPAC+2. TPA_PZ0FIX 04200 04201 04202 04203 04204 04205 04206 04207 4200 3 4201 5 4202 3 4203 0 4204 4205 4206 4207 3 3 5 0 0,0132 1 0,0131 1 2,4317 0 2,4337 1 2,4315 0,0131 0,0132 0,0577 1 1 1 1 EQU XCH TS CAF TC CAF XCH TS TC * MPAC+2 MPAC+1 TPA_MPAC0 TPA_FIXP MAXPOS MPAC+1 MPAC+2 MATH_Q
; move MPAC+2 to MPAC+1 so we can use ; our standard correction function ; borrow from MPAC to correct MPAC+1
; move corrected value from MPAC+1 back ; to MPAC+2. Set MPAC+1 to correct value ; borrowed from MPAC.
; The MPAC is non- zero negative, so reconcile signs to a negative number. TPA_M0 04210 04211 04212 04213 04214 04215 04216 04217 4210 4211 4212 4213 4214 1 0 0 0 0 0,0131 2,4215 2,4220 2,4264 2,4220 0 0 0 0 0 EQU CCS TC TC TC TC CAF TC TC * MPAC+1 *+4 TPA_MZ0 TPA_M1+2 TPA_MZ0 TPA_MPAC0 TPA_FIXM TPA_M1+2
; ; ; ;
>0, fix MPAC+1 +0, <0, MPAC+1 is OK, check MPAC+2 -0,
; MPAC is non-zero negative, MPAC+1 is zero TPA_MZ0 04220 04221 04222 04223 04224 04225 04226 04227 04230 4220 4221 4222 4223 4224 4225 4226 4227 4230 1 0 0 0 3 5 3 5 0 0,0132 2,4231 2,4224 2,4226 1,2045 0,0132 1,2045 0,0131 0,0577 0 0 1 0 1 1 1 1 1 EQU CCS TC TC TC CAF TS CAF TS TC * MPAC+2 TPA_MZ0FIX *+2 *+3 NEG0 MPAC+2 NEG0 MPAC+1 MATH_Q
; >0, ; +0, MPAC+1, +2 both zero ; <0, zero MPAC+1, MPAC+2 is OK ; make sure they're both -0
; MPAC is non-zero negative, MPAC+1 is zero, MPAC+2 is non-zero positive ; Solution: borrow from MPAC, transfer borrowed value to MPAC+1, but also ; borrow from MPAC +1, use borrowed value to correct MPAC+2. TPA_MZ0FIX 04231 04232 04233 04234 04235 04236 04237 04240 4231 3 4232 5 4233 3 4234 0 4235 4236 4237 4240 3 3 5 0 0,0132 1 0,0131 1 2,4317 0 2,4321 0 2,4316 0,0131 0,0132 0,0577 1 1 1 1 EQU XCH TS CAF TC CAF XCH TS TC * MPAC+2 MPAC+1 TPA_MPAC0 TPA_FIXM MAXNEG MPAC+1 MPAC+2 MATH_Q
; move MPAC+2 to MPAC+1 so we can use ; our standard correction function ; borrow from MPAC to correct MPAC+1
; move corrected value from MPAC+1 back ; to MPAC+2. Set MPAC+1 to correct value ; borrowed from MPAC.
; MPAC was zero, s o we still don't know the sign. Check MPAC+1. TPA_SGN1 04241 04242 04243 04244 04245 4241 4242 4243 4244 4245 1 0 0 0 0 0,0131 2,4246 2,4277 2,4262 2,4277 0 0 1 0 1 EQU CCS TC TC TC TC * MPAC+1 TPA_P1 TPA_SGN2 TPA_M1 TPA_SGN2
; ; ; ;
sign will be + still don't know sign, check MPAC+ 2 sign will be still don't know sign, check MPAC+ 2
; MPAC+1 is non-ze ro positive, so reconcile signs to a positive number. TPA_P1 04246 04247 04250 04251 04252 04253 04254 04255 04256 04257 04260 04261 4246 3 4247 5 4250 4251 4252 4253 4254 4255 4256 1 0 0 0 3 5 0 1,2050 0 0,0130 0 0,0132 0,0577 0,0577 2,4257 1,2050 0,0132 0,0577 0 1 1 0 0 1 1 EQU CAF TS CCS TC TC TC CAF TS TC CAF TC TC * ZERO MPAC MPAC+2 MATH_Q MATH_Q *+4 ZERO MPAC+2 MATH_Q TPA_MPAC1 TPA_FIXP MATH_Q
; set MPAC to +0
; ; ; ;
; MPAC+1 is non-ze ro negative, so reconcile signs to a negative number. TPA_M1 04262 04263 04264 04265 04266 04267 04270 04271 04272 04273 04274 04275 04276 4262 3 4263 5 4264 4265 4266 4267 4270 1 0 0 0 0 1,2045 1 0,0130 0 0,0132 2,4274 2,4271 0,0577 0,0577 0 1 1 1 1 EQU CAF TS CCS TC TC TC TC CAF TS TC CAF TC TC * NEG0 MPAC MPAC+2 *+7 *+3 MATH_Q MATH_Q NEG0 MPAC+2 MATH_Q TPA_MPAC1 TPA_FIXM MATH_Q
; set MPAC to -0
; ; ; ;
; MPAC and MPAC+1 were both zero, so we still don't know the sign. ; Check MPAC+2. TPA_SGN2 04277 04300 04301 04302 04303 04304 04305 04306 04307 04310 04311 04312 04313 04314 4277 4300 4301 4302 4303 1 0 0 0 0 0,0132 2,4304 2,4310 2,4306 2,4310 0 1 1 0 1 EQU CCS TC TC TC TC CAF TC CAF TC CAF TS TS TS TC * MPAC+2 TPA_P2 TPA_P3 TPA_M2 TPA_P3 ZERO *+5 NEG0 *+3 ZERO MPAC+2 MPAC+1 MPAC MATH_Q
; ; ; ;
1,2050 0 TPA_P2 2,4312 0 1,2045 1 TPA_M2 2,4312 0 1,2050 0 TPA_P3 0,0132 1 0,0131 1 0,0130 0 0,0577 1
DS DS DS DS
;----------------- --------------------------------------------------------; TPA_FIXM ; Reconcile the si gns in a double precision word. The most significant word ; is in C(A), the lesser word in C(A+1). Reconcilliation occurs by borrowing ; from C(A) and ad ding the borrowed amount to C(A+1). C(A) is assumed to be ; negative non-zer o number and C(A+1) positive non-zero. The reconciliation ; makes both numbe rs negative. ; ; This is part of my implementation of TPAGREE. ;----------------- --------------------------------------------------------TPA_FIXM 04321 04322 04323 4321 5 4322 2 4323 4 0,0576 0 0,0576 1 0,0000 0 EQU TS IND EX CS * ADDRWD1 ADDRWD1 0
04324 04325 04326 04327 04330 04331 04332 04333 04334 04335 04336
4324 4325 4326 4327 4330 4331 4332 4333 4334 4335 4336
1 4 2 5 3 6 2 6 2 5 0
0,0000 0,0000 0,0576 0,0000 2,4316 1,2046 0,0576 0,0001 0,0576 0,0001 0,0001
0 0 1 1 1 1 1 0 1 0 0
;----------------- --------------------------------------------------------; TPA_FIXP ; Reconcile the si gns in a double precision word. The most significant word ; is in C(A), the lesser word in C(A+1). Reconcilliation occurs by borrowing ; from C(A) and ad ding the borrowed amount to C(A+1). C(A) is assumed to be ; positive non-zer o number and C(A+1) negative non-zero. The reconciliation ; makes both numbe rs positive. ; ; This is part of my implementation of TPAGREE. ;----------------- --------------------------------------------------------TPA_FIXP 04337 04340 04341 04342 04343 04344 04345 04346 04347 04350 04351 04352 4337 5 4340 4341 4342 4343 4344 4345 4346 4347 4350 4351 4352 2 1 2 5 3 6 2 6 2 5 0 0,0576 0 0,0576 0,0000 0,0576 0,0000 2,4315 1,2051 0,0576 0,0001 0,0576 0,0001 0,0001 1 0 1 1 1 1 1 0 1 0 0 EQU TS IND EX CCS IND EX TS CAF AD IND EX AD IND EX TS TC * ADDRWD1 ADDRWD1 0 ADDRWD1 0 MAXPOS ONE ADDRWD1 1 ADDRWD1 1 Q
;----------------- --------------------------------------------------------; SHORTMP -- MULTI PLY DOUBLE WORD BY A SINGLE WORD ; Multiply C(MPAC, MPAC+1) by the contents of A. Put the product in MPAC, ; MPAC+1, MPAC+2. ;; ; These aren't inc luded in my partial COLOSSUS listing, so I had to invent ; my own version. ;----------------- --------------------------------------------------------SHORTMP 04353 4353 5 0,0573 0 EQU TS * SHORTMP_A
; MPAC+2 = MPAC+1 * A 04354 04355 04356 04357 04360 4354 4355 4356 4357 4360 2 4 5 3 5 0,0000 0,0131 0,0574 0,0003 0,0132 1 0 1 1 1 EXT END MP TS XCH TS
; MPAC+1 = (MPAC * A) + overflow 04361 04362 04363 04364 04365 04366 04367 04370 4361 4362 4363 4364 4365 4366 4367 4370 3 2 4 5 3 6 5 3 0,0573 0,0000 0,0130 0,0575 0,0003 0,0574 0,0131 1,2050 0 1 1 0 1 1 1 0 XCH EXT END MP TS XCH AD TS CAF ; MPAC = overflow 04371 04372 04373 4371 6 4372 5 4373 0 0,0575 0 0,0130 0 0,0001 0 AD TS TC SHORTMP_OVFH MPAC Q ; return SHORTMP_A MPAC SHORTMP_OVFH LP SHORTMP_OVFL MPAC+1 ZERO
;----------------- --------------------------------------------------------; DMP -- DOUBLE PR ECISION MULTIPLY ; Multiply val, va l+1 with C(MPAC, MPAC+1). 'ADDRWD1' contains the ; address of 'val' . The product appears in MPAC, MPAC+1, MPAC+2 ; ; This isn't inclu ded in my partial COLOSSUS listing, but is taken from
; the double preci sion math examples in R-393. ;----------------- --------------------------------------------------------DMP 04374 04375 04376 04377 04400 04401 04402 04403 04404 04405 04406 04407 04410 04411 04412 04413 04414 04415 04416 04417 04420 04421 04422 04423 04424 04425 04426 04427 04430 04431 04432 04433 04434 4374 4375 4376 4377 4400 4401 4402 4403 4404 4405 4406 4407 4410 4411 4412 4413 4414 4415 4416 4417 4420 4421 4422 4423 4424 4425 4426 4427 4430 4431 4432 4433 4434 2 3 6 5 3 5 2 4 3 2 4 3 6 3 5 2 4 3 3 6 3 2 4 3 6 6 3 3 5 3 6 5 0 0,0001 0,0000 2,5777 0,0576 0,0131 0,0034 0,0576 0,0001 0,0034 0,0576 0,0000 0,0034 0,0003 0,0130 0,0132 0,0576 0,0001 0,0034 0,0130 0,0003 0,0132 0,0576 0,0000 0,0034 0,0130 0,0003 0,0131 0,0034 0,0130 0,0001 1,2051 0,0001 0,0001 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 1 0 0 EQU IND EX CAF AD TS XCH TS IND EX MP XCH IND EX MP XCH AD XCH TS IND EX MP XCH XCH AD XCH IND EX MP XCH AD AD XCH XCH TS XCH AD TS TC * Q 0 EXTENDER ADDRWD1 MPAC+1 OVCTR ADDRWD1 1 OVCTR ADDRWD1 0 OVCTR LP MPAC MPAC+2 ADDRWD1 1 OVCTR MPAC LP MPAC+2 ADDRWD1 0 OVCTR MPAC LP MPAC+1 OVCTR MPAC Q ONE Q Q ; skip next word on return
BANKFF_1
EQU
;----------------- -------------------------------------------------------; PINBALL ; ; Now, do the "pin ball game" (DSKY) routines. ; ; Mimic the bank a ssignments in COLOSSUS. Since this is a block I AGC that ; has fewer banks, different bank numbers are used, but the sequence and ; relative allocat ion of routines to various banks is preserved. ;----------------- -------------------------------------------------------; don't change BAN K04_1 without also changing V37BANK BANK04_1 BANK40_1 BANK41_1 BANK42_1 BANK43_1 EQU EQU EQU EQU EQU BANK4 BANK5 BANK6 BANK7 BANK10 ; was BANK 04 in COLOSSUS ; ; ; ; was was was was BANK BANK BANK BANK 40 41 42 43 in in in in COLOSSUS COLOSSUS COLOSSUS COLOSSUS
; start of COLOSSU S routines ORG BANK04_1 ; COLOSSUS pp. 192-204 INC L bank04_1.asm ;================= ========================================================= ; MAJOR MODE CHANG E (file:bank04_1.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 192-204. ;================= ========================================================= ;----------------- --------------------------------------------------------; VERB 37 ; ; In COLOSSUS, a s uccessful V37 apparently also restarts the AGC. Here, ; we implement a s ubset of COLOSSUS to kick off a job associated with the ; verb. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 192-204. ;----------------- ---------------------------------------------------------
EQU TS
* MMNUMBER
; ** skipped quite a bit of guidance system-related code ** 10001 4,0001 0 4,6005 1 TC CHECKTAB
; ** skipped more guidance system-related code ** V37BAD 10002 10003 10004 4,0002 0 4,0003 0 4,0004 2,5003 1 1,3653 1 05067 0 EQU TC TC CAD R * RELDSP POSTJUMP PINBRNCH
; releases display from astronaut ; bring back last normal display if ther e ; was one, OY
; Search table for entry matching major mode number. Table entries ; are sorted by ma jor mode number, so the search occurs in order from ; lowest number to highest. CHECKTAB 10005 10006 10007 10010 10011 10012 10013 10014 10015 10016 10017 10020 10021 4,0005 3 4,0006 6 4,0007 5 4,0010 4,0011 4,0012 4,0013 4,0014 4,0015 4,0016 3 2 6 7 4 6 1 1,2050 0 4,6046 0 0,0131 1 AGAINMM 1,2050 0,0131 4,6037 1,2101 0,0000 0,0464 0,0000 0 0 0 1 0 1 0 EQU CAF AD TS CAF IND EX AD MAS K COM AD CCS CCS TC TC * ZERO NOV37MM MPAC+1 ZERO MPAC+1 PREMM1 LOW7 MMNUMBER A MPAC+1 AGAINMM V37NONO ; was CA PREMM1 in Block II ; obtain which MM this is for
; MMNUMBER - current table MM number ; if GR, see if anymore in list ; yes, get next one (was TCF) ; last time or passed MM (was TCF)
; Found the index into the major mode table for entry matching the ; major mode numbe r input by the user. 10022 10023 10024 10025 4,0022 3 4,0023 6 4,0024 5 4,0025 0 1,2050 0 0,0131 1 0,0463 0 1,2147 1 CAF AD TS TC ZERO MPAC+1 MINDEX goMMchange ; was CA MPAC+1 in Block II ; save index for later ; in Block II, jumped to restart AGC
; Requested MM doe sn't exist V37NONO 10026 10027 4,0026 0 4,0027 0 2,4701 0 4,6002 0 EQU TC TC * FALTON V37BAD
;----------------- --------------------------------------------------------; FCADRMM ; ; For verb 37, two tables are maintained. Each table has an entry for each ; major mode that can be started from the keyboard. The entries are put ; into the table w ith the entry for the highest major mode coming first, ; to the lowest ma jor mode which is the last entry in the table. ; ; The FCADRMM tabl e contains the FCADR of the starting job of the major mode. ; ; The entries in t his table must match the entries in PREMM1 below. ;----------------- --------------------------------------------------------FCADRMM1 10030 10031 10032 10033 10034 10035 10036 4,0030 4,0031 4,0032 4,0033 4,0034 4,0035 4,0036 22147 22142 22127 22066 22036 22022 22000 0 0 0 1 1 1 1 ; etc ********* ;----------------- --------------------------------------------------------; PREMM1 ; ; The PREMM1 table contains the E-bank, major mode, and priority information. ; It is in the fol lowing form: ; ; PPP PPE EEM MMM MMM ; ; Where, ; the 7 'M' bits contain the major mode number EQU CAD R CAD R CAD R CAD R CAD R CAD R CAD R * P79 P78 P04 P03 P02 P01 P00
; the 3 'E' bits contain the E-bank number (ignored in Block I) ; the 5 'P' bits contain the priority at which the job is to be started ; ; The entries in t his table must match the entries in FCADRMM1 above. ;----------------- --------------------------------------------------------PREMM1 10037 10040 10041 10042 10043 10044 10045 4,0037 4,0040 4,0041 4,0042 4,0043 4,0044 4,0045 26117 26116 26004 26003 26002 26001 26000 1 0 1 0 1 1 0 EQU DS DS DS DS DS DS DS * %26117 %26116 %26004 %26003 %26002 %26001 %26000 * EPREMM1-PREMM1-1 ; number of entries in table (minus 1) *
; ; ; ; ; ; ;
MM MM MM MM MM MM MM
13 13 13 13 13 13 13
; etc ********* EPREMM1 EQU 10046 4,0046 00006 1 NOV37MM BANK04_2 DS EQU
ORG BANK40_1 ; COLOSSUS pp. 310-317 INC L bank40_1.asm ;================= ========================================================= ; PINBALL GAME (fi le:bank40_1.asm) ; ; AGC Block II COL OSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 310-317. ;================= ========================================================= ;----------------- --------------------------------------------------------; CHARIN -- PROCES S KEYBOARD CHARACTER FROM KEYRUPT ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 310. ;----------------- --------------------------------------------------------CHARIN 12000 12001 12002 12003 12004 12005 12006 12007 5,0000 5,0001 5,0002 5,0003 5,0004 5,0005 5,0006 5,0007 3 3 5 1 0 0 4 6 1,2051 0,0501 0,0412 0,0531 5,6006 5,6016 5,6062 0,0130 1 0 0 1 1 0 1 0 ; VBRELDSP). 12010 12011 12012 12013 12014 12015 5,0010 5,0011 5,0012 5,0013 5,0014 1 0 0 0 0 0,0000 5,6015 5,6014 5,6015 5,6016 0 0 1 0 0 CCS TC TC TC TC TC CHARIN2 12016 12017 12020 12021 12022 12023 12024 12025 12026 12027 12030 12031 12032 12033 12034 12035 12036 12037 12040 12041 12042 12043 12044 12045 12046 12047 12050 12051 12052 12053 5,0016 5,0017 5,0020 5,0021 5,0022 5,0023 5,0024 5,0025 5,0026 5,0027 5,0030 5,0031 5,0032 5,0033 5,0034 5,0035 5,0036 5,0037 5,0040 5,0041 5,0042 5,0043 5,0044 5,0045 5,0046 5,0047 5,0050 5,0051 5,0052 5,0053 3 5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,0130 0,0414 0,0000 5,6022 5,7307 5,6101 5,6101 5,6101 5,6101 5,6101 5,6101 5,6101 5,6065 5,6065 5,7307 5,7307 5,7307 5,7307 5,7307 5,7307 5,6077 5,6272 5,7462 5,7307 5,7307 5,7307 5,7307 5,7307 5,7307 5,7327 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 EQU XCH TS IND EX TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC A *+4 *+2 *+2 CHARIN2 RELDSPON * MPAC CHAR A *+1 CHARALRM NUM NUM NUM NUM NUM NUM NUM _89TEST _89TEST CHARALRM CHARALRM CHARALRM CHARALRM CHARALRM CHARALRM NUM-2 VERB ERROR CHARALRM CHARALRM CHARALRM CHARALRM CHARALRM CHARALRM VBRELDSP ; ; ; ; ; was BZF CHARIN2 in Block II >0 +0 <0 -0 EQU CAF XCH TS CCS TC TC CS AD * ONE DSPLOCK _2122REG CADRSTOR *+2 CHARIN2 ELRCODE1 MPAC
; ; ; ; ; ; ; ;
block display syst make dsp syst busy, but save old C(DSPLOCK) for error light reset all keys except ER turn on KR lite if CADRSTOR is full. This reminds operato r to re-establish a flashing display which he has obscured with displays of his own (see remarks preceding routine
5,0015 0
2,4713 0
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
input_code function 0 1 2 3 4 5 6 7 11 12 13 14 15 16 17 20 21 22 23 24 25 26 27 30 31 9
KEY RELEASE
0 0 0 0 0 0
0 1 1 1 0 1
POSGN NEGSGN ENTERJMP CHARALRM CLEAR NOUN %22 POSTJUMP ENTER * DSPCOUNT *+4 *+3 ENDOFJOB ENDOFJOB THREE DECBRNCH A NUM CHARALRM
; ; ; ; ; ;
32 33 34 35 36 37
12065 12066 12067 12070 12071 12072 12073 12074 12075 12076
5,0065 5,0066 5,0067 5,0070 5,0071 5,0072 5,0073 5,0074 5,0075 5,0076
1 0 0 0 0 3 7 1 0 0
0,0466 5,6072 5,6072 1,2723 1,2723 1,2053 0,0467 0,0000 5,6101 5,7307
1 1 1 0 0 0 0 0 1 1
; ; ; ;
;----------------- --------------------------------------------------------; NUM -- PROCESS N UMERICAL KEYBOARD CHARACTER ; Assembles octal, 3 bits at a time. For decimal, it converts incoming word ; as a fraction, k eeping results to DP (double precision). ; Octal results ar e left in XREG, YREG, or ZREG. High part of DEC in XREG, ; YREG, ZREG; the low parts in XREGLP, YREGLP, or ZREGLP). ; DECBRNCH is left at +0 for octal, +1 for +DEC, +2 for -DEC. ; If DSPCOUNT was left -, no more data is accepted. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 311. ;----------------- --------------------------------------------------------12077 12100 5,0077 3 5,0100 5 1,2050 0 0,0414 0 NUM 12101 12102 12103 12104 12105 12106 12107 12110 12111 12112 12113 12114 12115 12116 12117 12120 12121 12122 12123 12124 12125 12126 12127 12130 12131 12132 12133 12134 12135 12136 5,0101 5,0102 5,0103 5,0104 5,0105 5,0106 5,0107 5,0110 5,0111 5,0112 5,0113 5,0114 5,0115 5,0116 5,0117 5,0120 5,0121 5,0122 5,0123 5,0124 5,0125 5,0126 5,0127 5,0130 5,0131 5,0132 5,0133 5,0134 5,0135 5,0136 1 0 0 0 0 0 1 3 5 0 2 3 7 5 3 6 5 0 3 7 1 0 2 3 5 4 4 3 6 0 0,0466 5,6106 5,6106 5,6105 1,2723 5,6241 0,0504 1,2050 0,0504 5,6113 0,0414 1,3772 2,4664 0,0421 1,2050 0,0466 0,0440 5,7161 1,2053 0,0467 0,0000 5,6137 0,0434 0,0470 0,0022 0,0022 0,0022 0,0022 0,0414 5,6155 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 0 0 1 0 1 1 0 0 1 0 0 DECTOBIN 12137 12140 12141 12142 12143 12144 12145 12146 12147 12150 12151 12152 5,0137 5,0140 5,0141 5,0142 5,0143 5,0144 5,0145 5,0146 5,0147 5,0150 5,0151 2 3 5 3 5 3 0 3 6 5 0 0,0434 0,0470 0,0130 1,2050 0,0131 1,2060 2,4353 0,0131 0,0414 0,0131 5,6155 0 1 0 0 1 0 0 1 0 1 0 CAF TS EQU CCS TC TC TC TC TC CCS CAF TS TC IND EX CAF MAS K TS CAF AD TS TC CAF MAS K CCS TC IND EX XCH TS CS CS XCH AD TC EQU IND EX XCH TS CAF TS CAF TC XCH AD TS TC AD ZERO CHAR * DSPCOUNT *+4 *+3 *+1 ENDOFJOB GETINREL CLPASS ZERO CLPASS *+1 CHAR RELTAB LOW5 CODE ZERO DSPCOUNT COUNT DSPIN THREE DECBRNCH A DECTOBIN INREL VERBREG CYL CYL CYL CYL CHAR ENDNMTST * INREL VERBREG MPAC ZERO MPAC+1 TEN SHORTMP MPAC+1 CHAR MPAC+1 ENDNMTST MPAC
; ; ; ;
5,0152 6
0,0130 0
12153 12154
5,0153 5 5,0154 0
TS TC EQU IND EX TS CS IND EX AD CCS TC TC TC TC TC ENDNUM EQU CAF MAS K CCS TC EQU CS TC
MPAC DECEND * INREL VERBREG DSPCOUNT INREL CRITCON A *+4 *+2 *+2 ENDNUM MORNUM * THREE DECBRNCH A DECEND * DSPCOUNT MORNUM+1 ; ; ; ; ; was BZF ENDNUM in Block II >0 +0, DSPCOUNT = CRITCON <0 -0
12155 12156 12157 12160 12161 12162 12163 12164 12165 12166 12167
5,0155 5,0156 5,0157 5,0160 5,0161 5,0162 5,0163 5,0164 5,0165 5,0166
2 5 4 2 6 1 0 0 0 0
0,0434 0,0470 0,0466 0,0434 5,6232 0,0000 5,6167 5,6166 5,6167 5,6170
0 1 1 0 1 0 1 0 1 1
5,0167 0
5,6227 0
; - , DSPCOUNT G/ CRITCON
3 7 1 0
0 0 0 1 ENDALL
12174 12175
5,0174 4 5,0175 0
0,0466 1 5,6230 0
DECEND 12176 12177 12200 12201 12202 12203 12204 12205 12206 12207 12210 12211 12212 12213 12214 12215 12216 12217 5,0176 4 5,0177 6 5,0200 5,0201 5,0202 5,0203 5,0204 1 0 0 0 0 1,2051 0 0,0434 1 0,0000 5,6205 5,6204 5,6204 5,6174 0 0 1 1 0
EQU CS AD CCS TC TC TC TC
* ONE INREL A *+4 *+2 *+1 ENDALL ; ; ; ; ; was >0 +0, <0, -0, BZMF ENDALL in Block II INREL=0,1(VBREG,NNREG), leave whol e INREL=0,1(VBREG,NNREG), leave whol e INREL=0,1(VBREG,NNREG), leave whol e
5,0205 0 5,0206 5,0207 5,0210 5,0211 5,0212 5,0213 5,0214 5,0215 5,0216 5,0217 3 7 2 0 0 4 5 4 5
2,4374 0 06237 1 1,2053 0,0467 0,0000 5,6212 5,6220 0,0131 0,0131 0,0132 0,0132 0 0 0 0 1 0 1 0 1
TC DMP ; if INREL=2,3,4(R1,R2,R3), convert to f r a c ; mult sum x2EXP-2 8 in MPAC, MPAC+1 by ADR ES DECON ; 2EXP14/10EPX5. Gives(sum/10EXP5)x2EXP- 1 4 ; in MPAC, +1, +2 CAF THREE MAS K DECBRNCH IND EX A TC *+0 TC PDECSGN CS TS CS TS PDECSGN EQU XCH IND EX TS XCH IND EX TS TC EQU CCS TS TC EQU DS DS DS DS DS EQU DS DS MPAC+1 MPAC+1 MPAC+2 MPAC+2 * MPAC+2 INREL XREGLP-2 MPAC+1 INREL VERBREG ENDALL * DSPCOUNT DSPCOUNT ENDOFJOB * %22 %20 %12 %5 %0 * %05174 %13261 ; - case (was DCS, DXCH in Block II)
3 2 5 3 2 5 0
1 0 1 1 0 1 0 MORNUM
; decrement DSPCOUNT
1 0 1 1 1 DECON
12237 12240
5,0237 5,0240
05174 0 13261 0
;----------------- --------------------------------------------------------; GETINREL ; Gets proper data register relative address for current C(DSPCOUNT) and ; puts into INREL: +0 VERBREG, 1 NOUNREG, 2 XREG, 3 YREG, 4 ZREG ;
; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 313. ;----------------- --------------------------------------------------------GETINREL 12241 12242 12243 12244 5,0241 5,0242 5,0243 5,0244 2 3 5 0 0,0466 5,6245 0,0434 0,0001 1 1 1 0 INRELTAB 12245 12246 12247 12250 12251 12252 12253 12254 12255 12256 12257 12260 12261 12262 12263 12264 12265 12266 12267 12270 5,0245 5,0246 5,0247 5,0250 5,0251 5,0252 5,0253 5,0254 5,0255 5,0256 5,0257 5,0260 5,0261 5,0262 5,0263 5,0264 0 5,0265 5,0266 5,0267 5,0270 00004 00004 00004 00004 00004 00003 00003 00003 00003 00003 00002 00002 00002 00002 00002 5,6271 00001 00001 00000 00000 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 EQU IND EX CAF TS TC EQU DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS TC DS DS DS DS * DSPCOUNT INRELTAB INREL Q * %4 %4 %4 %4 %4 %3 %3 %3 %3 %3 %2 %2 %2 %2 %2 CCSHOLE %1 %1 %0 %0
; (A TEMP, REG)
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
R3D5, 0 = DSPCOUNT R3D4, 1 R3D3, 2 R3D2, 3 R3D1, 4 R2D5, 5 R2D4, 6 R2D3, 7 R2D2, 8D R2D1, 9D R1D5, 10D R1D4, 11D R1D3, 12D R1D2, 13D R1D1, 14D no DSPCOUNT numbers ND2, 16D ND1, 17D VD2, 18D VD1, 19D
12271
5,0271 0
1,2723 0 CCSHOLE
TC
ENDOFJOB
;----------------- --------------------------------------------------------; VERB ; Verb key was pre ssed; prepare to enter a 2 decimal digit verb. ; Blank the verb d isplay and call ENDOFJOB. ; ; NOUN ; Noun key was pre ssed; prepare to enter a 2 decimal digit noun. ; Blank the noun d isplay and call ENDOFJOB. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 314. ;----------------- --------------------------------------------------------VERB 12272 12273 12274 5,0272 3 5,0273 5 5,0274 3 1,2050 0 0,0470 1 2,4675 1 NVCOM EQU CAF TS CAF * ZERO VERBREG VD1 * DSPCOUNT _2BLANK ONE DECBRNCH ZERO REQRET ENDINST ENTRET ENDOFJOB * ZERO NOUNREG ND1 NVCOM
5 0 3 5 3 5 3 5
5,0305 0
EQU TS TC CAF TS CAF TS CAF TS ; to TC ENDOFJOB 1,2723 0 TC 0,0466 5,6540 1,2051 0,0467 1,2050 0,0502 2,4553 0,0433 0 0 1 1 0 0 0 0 NOUN EQU CAF TS CAF TC
; set for dec V/N code ; set for ENTPAS0 ; if DSPALARM occurs before first ENTPAS 0 ; or NVSUB, ENTRET must already be set
3 5 3 0
0 0 1 1
;----------------- --------------------------------------------------------; NEGSGN ; Turn the minus s ign on for the register selected by DSPCOUNT. ; Call ENDOFJOB wh en done. ; ; POSGN ; Turn the plus si gn on for the register selected by DSPCOUNT. ; Call ENDOFJOB wh en done. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 314. ;----------------- --------------------------------------------------------NEGSGN EQU *
SIGNTEST M_ON TWO * INREL BIT7 DECBRNCH DECBRNCH * CLPASS ZERO CLPASS *+1 ENDOFJOB * SIGNTEST P_ON ONE BOTHSGN
2 6 6 5
0 0 1 1 PIXCLPAS
; set DEC compu bit to 1 (in DECBRNCH) ; Bit 5 for R1, bit 4 for R2, bit 3 for R 3
1 3 5 0 0
1 0 0 0 0 POSGN
0 0 3 0
0 0 1 0
;----------------- --------------------------------------------------------; P_ON ; Turn the plus si gn on for register selected by DSPCOUNT. ; Return when done . ; ; M_ON ; Turn the minus s ign on for register selected by DSPCOUNT. ; Return when done . ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 314. ;----------------- --------------------------------------------------------P_ON 12332 12333 12334 12335 12336 12337 12340 12341 5,0332 3 5,0333 5 5,0334 5,0335 5,0336 5,0337 5,0340 5,0341 0 2 3 5 6 5 0,0001 0 0,0547 1 5,6241 0,0434 5,6362 0,0420 1,2051 0,0417 0 0 0 1 1 0 SGNCOM 12342 12343 12344 12345 12346 12347 12350 12351 12352 5,0342 5,0343 5,0344 5,0345 5,0346 5,0347 5,0350 5,0351 3 5 3 0 3 5 3 0 1,2050 0,0421 0,0420 5,7253 1,2066 0,0421 0,0417 5,7253 0 0 1 1 0 0 0 1 EQU XCH TS TC IND EX CAF TS AD TS EQU CAF TS XCH TC CAF TS XCH TC TC M_ON 12353 12354 12355 12356 12357 12360 12361 12362 12363 5,0353 3 5,0354 5 5,0355 5,0356 5,0357 5,0360 5,0361 5,0362 5,0363 0 2 3 5 6 5 0 0,0001 0 0,0547 1 5,6241 0,0434 5,6362 0,0417 1,2051 0,0420 5,6342 0 0 0 0 1 1 1 SGNTAB 12364 12365 12366 5,0364 5,0365 5,0366 00005 1 00003 1 00000 1 EQU XCH TS TC IND EX CAF TS AD TS TC EQU DS DS DS * Q LXCH_LPRET GETINREL INREL SGNTAB-2 SGNOFF ONE SGNON * ZERO CODE SGNOFF _11DSPIN BIT11 CODE SGNON _11DSPIN LXCH_LPRET * Q LXCH_LPRET GETINREL INREL SGNTAB-2 SGNON ONE SGNOFF SGNCOM * %5 %3 %0 ; return
5,0352 0
0,0547 1
;----------------- --------------------------------------------------------; SIGNTEST ; Test whether thi s is a valid point for entering a + or - sign character. ; Returns if valid ; calls ENDOFJOB if invalid. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 314. ;----------------- ---------------------------------------------------------
EQU XCH TS
* Q LXCH_LPRET
12371 12372 12373 12374 12375 12376 12377 12400 12401 12402 12403
5,0371 5,0372 5,0373 5,0374 5,0375 5,0376 5,0377 5,0400 5,0401 5,0402 5,0403
3 7 1 0 4 0 4 0 4 0 0
1,2053 0,0467 0,0000 1,2723 2,4635 5,6404 2,4636 5,6404 2,4637 5,6404 1,2723
0 0 0 0 1 1 1 1 0 1 0
; allows +,- only when DSPCOUNT=R1D1 CAF THREE MAS K DECBRNCH CCS A TC ENDOFJOB CS TC CS TC CS TC TC SGNTST1 EQU AD CCS TC TC TC TC R1D1 SGNTST1 R2D1 SGNTST1 R3D1 SGNTST1 ENDOFJOB * DSPCOUNT A Q LXCH_LPRET Q LXCH_LPRET
; ; ; ;
R2D1, or D3D1. Allows only first of consecutive +/- characters. if low2 bits of DECBRNCH not=0, sign for this word already in, reject.
; DSPCOUNT is R1D1?
; ; ; ; ;
BZF *+2 in Block II no match, check next match found, sign is no match, check next match found, sign is
;----------------- --------------------------------------------------------; CLEAR -- PROCESS CLEAR KEY ; Clear blanks whi ch R1, R2, R3 is current or last to be displayed (pertinent ; XREG, YREG, ZREG is cleared). Successive clears take care of each RX L/ ; RC until R1 is d one, then no further action. ; ; The single compo nent load verbs allow only the single RC that is appropriate ; to be cleared. ; ; CLPASS = 0, PASS O, can be backed up ; CLPASS = +NZ, HI PASS, can be backed up ; CLPASS = -NZ, PA SSO, cannot be backed up ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 316. ;----------------- --------------------------------------------------------CLEAR 12412 12413 12414 12415 12416 12417 12420 12421 12422 12423 12424 12425 12426 12427 12430 5,0412 5,0413 5,0414 5,0415 5,0416 5,0417 5,0420 5,0421 5,0422 5,0423 5,0424 5,0425 5,0426 5,0427 5,0430 1 6 0 6 2 3 5 1 0 0 0 3 6 0 0 0,0466 1,2051 5,6416 1,2051 0,0000 5,6245 0,0434 0,0504 5,6431 5,6425 5,6425 1,2050 0,0434 5,6464 5,6454 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 CLPASHI 12431 12432 12433 12434 12435 12436 12437 12440 12441 12442 12443 12444 12445 12446 12447 12450 12451 12452 5,0431 1 5,0432 5 5,0433 0 5,0434 3 5,0435 6 5,0436 5 5,0437 3 5,0440 6 5,0441 5 5,0442 5,0443 5,0444 5,0445 5,0446 1 0 0 0 5 0,0434 0 0,0434 1 5,6464 1 5,6536 1 0,0502 0 0,0502 0 1,2050 0 0,0434 1 0,0422 0 0,0470 5,6446 5,6446 5,6446 0,0470 0 1 1 1 1 EQU CCS AD TC AD IND EX CAF TS CCS TC TC TC CAF AD TC TC EQU CCS TS TC CAF AD TS CAF AD TS CCS TC TC TC TS TC DS CAF AD * DSPCOUNT ONE *+2 ONE A INRELTAB INREL CLPASS CLPASHI *+2 *+1 ZERO INREL LEGALTST CLEAR1 * INREL INREL LEGALTST DOUBLK+2 REQRET REQRET ZERO INREL MIXTEMP VERBREG *+3 *+2 *+1 VERBREG BANKCALL UPDATVB ZERO MIXTEMP ; was CA MIXTEMP in Block II ; +3 to - number, backs data requests ; was ADS REQRET in Block II
; do not change DSPCOUNT because may lat e r ; fail LEGALTST ; must set INREL, even for HIPASS ; ; ; ; + +0, if CCLPASS is +0 or -, it is PASS0 was CA INREL in Block II
; was CA INREL in Block II ; temp storage for INREL ; was DIM VERBREG in Block II
12453
5,0453 5
0,0434 1 CLEAR1
TS EQU TC XCH AD TS TC
; restore INREL
; was INCR CLPASS in Block II ; only if CLPASS is + or +0 ; set for higher pass
;----------------- --------------------------------------------------------; CLR5 ; blanks 5 char di splay word by calling _5BLANK, but avoids TC GETINREL. ; Returns when don e. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 316. ;----------------- --------------------------------------------------------CLR5 12461 12462 12463 5,0461 3 5,0462 5 5,0463 0 0,0001 0 0,0547 1 5,6476 1 EQU XCH TS TC * Q LXCH_LPRET _5BLANK+3
; was LXCH Q in block II ; save return address in faux LP ; uses _5BLANK, but avoids its TC GETINR E L
;----------------- --------------------------------------------------------; LEGALTST ; Returns if LEGAL , calls ENDOFJOB if illegal. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 316. ;----------------- --------------------------------------------------------LEGALTST 12464 12465 12466 12467 12470 12471 5,0464 5,0465 5,0466 5,0467 5,0470 5,0471 6 1 0 0 0 0 1,2047 0,0000 0,0001 5,6271 1,2723 0,0001 0 0 0 0 0 0 EQU AD CCS TC TC TC TC * NEG2 A Q CCSHOLE ENDOFJOB Q
;----------------- --------------------------------------------------------; _5BLANK ; blanks 5 char di splay word in R1,R2,or R3. It also zeroes XREG, YREG or ; ZREG. Place any + DSPCOUNT number for pertinent RC into DSPCOUNT. ; DSPCOUNT is left set to left most DSP numb for RC just blanked. ; Returns when don e. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 316. ;----------------- --------------------------------------------------------12472 5,0472 5 0,0466 0 _5BLANK 12473 12474 12475 12476 12477 12500 12501 12502 12503 12504 12505 12506 12507 12510 12511 12512 12513 12514 5,0473 3 5,0474 5 5,0475 5,0476 5,0477 5,0500 5,0501 5,0502 5,0503 5,0504 5,0505 5,0506 5,0507 5,0510 5,0511 5,0512 5,0513 5,0514 0 3 2 5 2 5 5 2 4 7 7 5 2 3 5 0 0,0001 0 0,0547 1 5,6241 1,2050 0,0434 0,0470 0,0434 0,0473 0,0421 0,0434 1,2072 0,0467 5,6537 0,0467 0,0434 5,6527 0,0440 5,7161 0 0 0 1 0 1 0 0 1 0 1 1 0 1 1 0 _5BLANK1 12515 12516 12517 12520 12521 12522 12523 5,0515 5,0516 5,0517 5,0520 2 3 5 0 0,0434 5,6532 0,0466 5,6540 0 0 0 0 TS EQU XCH TS TC CAF IND EX TS IND EX TS TS IND EX CS MAS K MAS K TS IND EX CAF TS TC EQU IND EX CAF TS TC CS AD TS DSPCOUNT * Q LXCH_LPRET GETINREL ZERO INREL VERBREG INREL XREGLP-2 CODE INREL BIT7 DECBRNCH BRNCHCON DECBRNCH INREL SINBLANK-2 COUNT DSPIN * INREL DOUBLK-2 DSPCOUNT _2BLANK TWO DSPCOUNT DSPCOUNT ; needed for BLANKSUB
; zero X, Y, Z reg
0 2 3 5 0
0 0 0 0 1
TC IND EX CAF TS TC
SINBLANK 12531 12532 12533 5,0531 5,0532 5,0533 00016 0 00005 1 00004 0 DOUBLK 12534 12535 12536 12537 5,0534 5,0535 5,0536 5,0537 00015 0 00011 1 00003 1 77774 0 BRNCHCON
EQU DS DS DS EQU DS DS DS DS
; DEC 14
; DEC 13 ; DEC 9
;----------------- --------------------------------------------------------; _2BLANK ; blanks 2 char, p lace DSP number of left char of the pair into DSPCOUNT. ; This number is l eft in DSPCOUNT. Returns when done. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 317. ;----------------- ---------------------------------------------------------
_2BLANK 12540 12541 12542 12543 12544 12545 12546 12547 12550 12551 12552 12553 12554 12555 12556 12557 12560 12561 12562 12563 5,0540 3 5,0541 5 5,0542 5,0543 5,0544 5,0545 3 6 5 4 0,0001 0 0,0602 0 1,2050 0,0466 0,0021 5,6563 0 0 1 0
EQU XCH TS CAF AD TS CS INH INT IND EX XCH CCS TC TC TC TC XCH AD TS REL INT TC DS
5,0546 2 5,0547 2 5,0550 3 5,0551 5,0552 5,0553 5,0554 5,0555 5,0556 5,0557 5,0560 5,0561 1 0 0 0 0 3 6 5 2
0,0000 0 0,0021 0 0,0512 1 0,0000 5,6556 5,6555 5,6555 5,6557 0,0505 1,2051 0,0505 0,0000 0 1 1 1 0 1 1 1 1
SR DSPTAB A *+4 *+2 *+1 *+2 NOUT ONE NOUT ; ; ; ; ; was >0 +0, <0, -0, BZMF *+2 in Block II if old contents -, NOUT OK if old contents -, NOUT OK if old contents -, NOUT OK
5,0562 0 5,0563
SAVEQ %4000
BANK40_2
EQU
ORG BANK41_1 ; COLOSSUS pp. 318-329 INC L bank41_1.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bank41_1.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 318-329. ;================= ========================================================= ;----------------- --------------------------------------------------------; ENTER -- PROCESS ENTER KEY ; Enter pass 0 is the execute function. Higher order enters are to load ; data. The sign o f REQRET determines the pass, + for pass 0, - for higher ; passes. ; Machine CADR to be specified (MCTBS) nouns desire an ECADR to be loaded ; when used with l oad verbs, monitor verbs, or display verbs (except ; verb = fixed mem ory display, which requires a FCADR). ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 318. ;----------------- --------------------------------------------------------14000 14001 6,0000 0 6,0001 0 6,7505 0 NVSUBR 6,6723 1 LOADLV1 TC TC NVSUB1 LOADLV ; standard lead-ins, don't move
ENTER 14002 14003 14004 14005 14006 14007 14010 14011 6,0002 6,0003 6,0004 6,0005 6,0006 6,0007 6,0010 6,0011 3 5 3 5 1 0 0 0 1,2050 0,0504 2,4553 0,0433 0,0502 6,6040 6,6040 6,6012 0 0 0 0 1 0 0 1
; not first pass t hru ENTER, so enter data word ENTPASHI 14012 14013 14014 14015 14016 14017 14020 14021 14022 14023 14024 14025 14026 14027 14030 14031 6,0012 3 6,0013 6 6,0014 6,0015 6,0016 6,0017 6,0020 6,0021 6,0022 6,0023 6,0024 6,0025 6,0026 6,0027 6,0030 6,0031 1 0 0 0 0 3 7 1 0 0 1 0 0 0 6,6036 1 0,0502 0 0,0000 6,6021 6,6020 6,6021 6,6032 1,2053 0,0467 0,0000 6,6026 6,6032 0,0466 6,6341 6,6341 6,6032 0 1 0 1 0 0 0 0 0 0 1 1 1 0 ACCEPTWD 14032 14033 14034 14035 6,0032 6,0033 6,0034 6,0035 4 5 0 0 0,0502 0,0502 2,4770 0,0502 1 0 0 0 ENTEXIT 14036 14037 6,0036 6,0037 15357 1 MMADREF 00034 0 LOWVERB EQU CAF AD CCS TC TC TC TC CAF MAS K CCS TC TC CCS TC TC TC EQU CS TS TC TC EQU DS DS * MMADREF REQRET A *+4 *+2 *+2 ACCEPTWD THREE DECBRNCH A *+2 ACCEPTWD DSPCOUNT GODSPALM GODSPALM *+1 * REQRET REQRET FLASHOFF REQRET ENTRET MMCHANG+1 28 ; assumes TC REGMM at MMCHANG ; lower verb that avoids nount test.
; if L/2 char in for MM code, alarm ; ; ; ; ; ; ; ; ; ; and recycle (decide at MMCHANG+1) >0 +0 <0 -0, was BZF ACCEPTWD in Block II if DEC, alarm if L/5 char in for data, but leave REQRET - and flash on, so operator can supply missing numerical characters and continue. octal, any number of char OK.
; less than 5 char DEC(DSPCOUNT is +) ; less than 5 char DEC(DSPCOUNT is +) ; 5 char in (DSPCOUNT is -)
; first pass thru ENTER, so execute VERB/NOUN ENTPAS0 14040 14041 14042 14043 6,0040 6,0041 6,0042 6,0043 3 5 4 5 1,2050 0,0467 2,4675 0,0466 0 1 0 0 ; test VERB TESTVB 14044 14045 14046 14047 14050 14051 14052 14053 6,0044 4 6,0045 5 6,0046 6 6,0047 6,0050 6,0051 6,0052 6,0053 1 0 0 0 0 0,0470 0 0,0530 1 6,6037 0 0,0000 6,6054 6,6053 6,6053 6,6151 0 0 1 1 1 ; test NOUN TESTNN ; ; ; ; 14054 14055 14056 14057 14060 14061 6,0054 3 6,0055 0 6,0056 2 6,0057 0 6,0060 0 6,0061 0 6,6124 0 1,3526 0 0,0435 1 6,6057 0 6,6062 0 6,6237 1 EQU * EQU CS TS AD CCS TC TC TC TC * VERBREG VERBSAVE LOWVERB A *+4 *+2 *+1 VERBFAN EQU CAF TS CS TS * ZERO DECBRNCH VD1 DSPCOUNT
; noun verb sub enters here ; block further num char, so that stray ; char do not get into verb or nount lig h t s .
; if verb is G/E LOWVB, skip noun test ; save verb for possible recycle. ; LOWVERB - VB ; ; ; ; ; was >0 +0, <0, -0, BZMF VERBFAN in Block II VERB G/E LOWVERB VERB G/E LOWVERB VERB G/E LOWVERB
set MIXBR and pu t the noun address into NNADTEM MIXBR is an enum erated type: 1 = normal nouns 2 = mixed nouns CAF TC IND EX TC TC TC LODNNLOC DXCHJUMP MIXBR *+0 *+2 MIXNOUN ; was DCA LODNNLOC, DXCH Z in Block II ; bank jump to noun table read rtne ; computed GOTO
; returns here for normal noun ; returns here for mixed noun
; normal noun, so test noun address table entry (NNADTEM) 14062 14063 14064 14065 6,0062 6,0063 6,0064 6,0065 1 0 0 0 0,0443 6,6147 6,6341 6,6073 0 0 1 0 CCS TC TC TC NNADTEM VERBFAN-2 GODSPALM REQADD ; ; ; ; normal normal if + not in use if +0 specify machine CADR if -
; NNADTEM was -0, so just increment noun address (in NOUNCADR) and ; set the result i n NOUNADD 14066 14067 14070 14071 14072 6,0066 3 6,0067 6 6,0070 5 6,0071 0 6,0072 0 0,0506 1 1,2051 1 0,0506 1 2,4625 1 6,6132 1 XCH AD TS TC TC NOUNCADR ONE NOUNCADR SETNADD INTMCTBS+3 ; augment machine CADR if -0 ; was INCR NOUNCADR in Block II ; set NOUNADD
; NNADTEM was -, s o noun address needs to be specified (loaded). REQADD 14073 14074 14075 14076 14077 14100 14101 14102 14103 14104 14105 14106 14107 14110 14111 14112 14113 14114 14115 14116 6,0073 6,0074 6,0075 6,0076 6,0077 6,0100 6,0101 6,0102 6,0103 3 5 4 6 1 0 0 0 0 1,2062 0,0504 2,4553 0,0433 0,0000 6,6104 6,6103 6,6104 6,6105 1 0 1 0 0 1 0 1 0 EQU CAF TS CS AD CCS TC TC TC TC TC TC CCS TC CS TS CCS TC TC TC TC * BIT15 CLPASS ENDINST ENTEXIT A *+4 *+2 *+2 *+2 INTMCTBS REQDATZ DECBRNCH ALMCYCLE VD1 DSPCOUNT CADRSTOR *+3 USEADD *+1 FLASHON ; external mach CADR to be specified ; ; ; ; alarm and recycle if decimal used for MCTBS octal used OK block num char in
; set CLPASS for pass0 only ; test if reach here from internal or ; from external ; ; ; ; ; was BZF *+2 in Block II >0 +0 <0 -0, external mach CADR to be specified
6,0104 0 6,0105 0 6,0106 6,0107 6,0110 6,0111 6,0112 6,0113 6,0114 6,0115 6,0116 1 0 4 5 1 0 0 0 0
6,6127 0 6,6274 0 0,0467 2,4474 2,4675 0,0466 0,0531 6,6116 6,6117 6,6116 2,4760 0 1 0 0 1 1 0 1 1
; noun address has now been loaded into the Z register. Copy it into ; NOUNCADR and NOU NADD and then jump to the VERBFAN. USEADD 14117 14120 14121 14122 14123 14124 14125 6,0117 3 6,0120 0 6,0121 3 6,0122 0 6,0123 0 6,0124 6,0125 0,0474 0 2,4616 1 6,6124 0 1,3526 0 6,6151 1 16114 1 LODNNLOC 00000 1 EQU XCH TC CAF TC TC DS DS * ZREG SETNCADR LODNNLOC DXCHJUMP VERBFAN LODNNTAB 0 ; *** uses 2 words in Block II ***
; ECADR into NOUNCADR, set EB, NOUNADD ; was DCA LODNNLOC, DXCH Z in Block II ; bank jump to noun table read rtne
14126
6,0126
77772 0 NEG5 ; ; ; ; ;
DS
-5
If external (key board input), noun address is in register A. If internal (S/W input), noun address is in MPAC+2. Store the noun a ddress into NOUNCADR and NOUNADD. If the verb is O5. go direct ly to the VERBFAN; for all other verbs, display the noun address in R3 and then go to the VERBFAN. EQU *
INTMCTBS
; entry point for internal: 14127 14130 6,0127 3 6,0130 6 1,2050 0 0,0132 1 CAF AD ZERO MPAC+2 ; was CA MPAC+2 in Block II ; internal mach CADR to be specified
; entry point for external (keyboard input): 14131 14132 14133 6,0131 0 6,0132 4 6,0133 6 2,4616 1 1,2055 1 0,0470 1 TC CS AD SETNCADR FIVE VERBREG ; store addr (A) into NOUNCADR and NOUNA D D ; NVSUB call left CADR in MAPC+2 for mac h ; CADR to be specified.
14134 14135 14136 14137 14140 14141 14142 14143 14144 14145 14146
1 0 0 0 0
0 0 1 0 1
A *+4 *+2 *+2 VERBFAN R3D1 DSPCOUNT ZERO NOUNCADR DSPOCTWD VERBFAN
; ; ; ; ;
was BZF VERBFAN in Block II >0 +0 <0 -0, don't display CADR if verb = 05
; NNADTEM was + (n ormal), so just use the noun address straight from the ; noun table (curr ently in A). The CCS instruction used to test the ; address also dec remented it, so we add one to restore the correct address. 14147 14150 6,0147 6 6,0150 0 1,2051 1 2,4616 1 AD TC ONE SETNCADR
; noun address is currently in NOUNCADR and NOUNADD. VERBFAN 14151 14152 14153 14154 14155 14156 14157 14160 14161 14162 14163 6,0151 4 6,0152 6 6,0153 6,0154 6,0155 6,0156 6,0157 6,0160 6,0161 6,0162 6,0163 1 6 0 0 5 0 0 6,6163 1 0,0470 1 0,0000 1,2051 6,6157 6,6164 0,0130 2,5003 1,3653 20000 0 1 1 1 0 1 1 0 EQU CS AD CCS AD TC TC TS TC TC DS DS EQU IND EX CAF TC EQU CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R * LST2CON VERBREG A ONE *+2 VBFANDIR MPAC RELDSP POSTJUMP GOEXTVB 40 * VERBREG VERBTAB BANKJUMP * GODSPALM DSPA DSPB DSPC DSPAB DSPABC DECDSP DSPDPDEC GODSPALM GODSPALM GODSPALM MONITOR MONITOR MONITOR MONITOR MONITOR MONITOR MONITOR GODSPALM GODSPALM GODSPALM ALOAD BLOAD CLOAD ABLOAD ABCLOAD GODSPALM DSPFMEM GODSPALM GODSPALM VBRQEXEC VBRQWAIT VBRESEQ VBPROC VBTERM VBTSTLTS SLAP1 MMCHANG GODSPALM GODSPALM
; verb-LST2CON
; ver G/ LST2CON ; verb L/ LST2CON ; release display syst ; go to GOEXTVB with VB-40 in MPAC
14167 14170 14171 14172 14173 14174 14175 14176 14177 14200 14201 14202 14203 14204 14205 14206 14207 14210 14211 14212 14213 14214 14215 14216 14217 14220 14221 14222 14223 14224 14225 14226 14227 14230 14231 14232 14233 14234 14235 14236
6,0167 6,0170 6,0171 6,0172 6,0173 6,0174 6,0175 6,0176 6,0177 6,0200 6,0201 6,0202 6,0203 6,0204 6,0205 6,0206 6,0207 6,0210 6,0211 6,0212 6,0213 6,0214 6,0215 6,0216 6,0217 6,0220 6,0221 6,0222 6,0223 6,0224 6,0225 6,0226 6,0227 6,0230 6,0231 6,0232 6,0233 6,0234 6,0235 6,0236
14341 14355 14363 14370 14350 14343 14510 12704 14341 14341 14341 15146 15146 15146 15146 15146 15146 15146 14341 14341 14341 14663 14673 14707 14635 14600 14341 15301 14341 14341 15420 15446 13325 13315 13323 15572 02126 15356 14341 14341
1 1 1 0 1 0 0 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1 0 0 1 1 1 0 0 0 1 1
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
VB00 VB01 VB02 VB03 VB04 VB05 VB06 VB07 VB08 VB09 VB10 VB11 VB12 VB13 VB14 VB15 VB16 VB17 VB18 VB19 VB20 VB21 VB22 VB23 VB24 VB25 VB26 VB27 VB28 VB29 VB30 VB31 VB32 VB33 VB34 VB35 VB36 VB37 VB38 VB39
Illegal display oct comp 1 (R1) display oct comp 2 (R1) display oct comp 3 (R1) display oct comp 1,2 (R1,R2) display oct comp 1,2,3 (R1,R2,R3) decimal display DP decimal display (R1,R2) spare spare spare monitor oct comp 1 (R1) monitor oct comp 2 (R2) monitor oct comp 3 (R3) monitor oct comp 1,2 (R1,R2) monitor oct comp 1,2,3 (R1,R2,R3) monitor decimal monitor DP decimal (R1,R2) spare spare spare load comp 1 (R1) load comp 2 (R2) load comp 3 (R3) load comp 1,2 (R1,R2) load comp 1,2,3 (R1,R2,R3) spare fixed memory display spare spare request executive request waitlist resequence proceed (without data) terminate test lights fresh start change major mode spare spare
;----------------- --------------------------------------------------------; MIXNOUN ; NNADTAB contains a relative address, IDADDREL(in low 10 bits), referring ; to where 3 conse cutive addresses are stored (in IDADDTAB). ; MIXNOUN gets dat a and stores in MIXTEMP, +1, +2. It sets NOUNADD for ; MIXTEMP. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 322. ;----------------- --------------------------------------------------------MIXNOUN 14237 6,0237 0 6,6341 1 EQU TC * GODSPALM
;----------------- --------------------------------------------------------; DPTEST ; enter with SF ro utine code number (SF ROUT) in A. Returns to L+1 if no DP. ; Returns to L+2 i f DP. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 322. Also, see p. 263. ;----------------- --------------------------------------------------------DPTEST 14240 14241 14242 14243 14244 14245 14246 14247 14250 14251 14252 14253 14254 14255 14256 14257 14260 14261 6,0240 5 6,0241 3 6,0242 5 6,0243 6,0244 6,0245 6,0246 6,0247 6,0250 6,0251 6,0252 6,0253 6,0254 6,0255 6,0256 6,0257 6,0260 6,0261 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,0552 0 0,0001 0 0,0553 1 0,0552 6,6245 0,0553 0,0553 0,0553 0,0553 6,6262 6,6262 0,0553 6,6262 0,0553 0,0553 6,6262 0,0553 0,0553 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 DPTEST1 14262 14263 6,0262 2 6,0263 0 0,0553 0 0,0001 0 EQU TS XCH TS IND EX TC TC TC TC TC TC TC TC TC TC TC TC TC TC EQU IND EX TC * DPTEST_A Q DPTEST_Q DPTEST_A *+1 DPTEST_Q DPTEST_Q DPTEST_Q DPTEST_Q DPTEST1 DPTEST1 DPTEST_Q DPTEST1 DPTEST_Q DPTEST_Q DPTEST1 DPTEST_Q DPTEST_Q * DPTEST_Q 1
; ; ; ; ; ; ; ; ; ; ; ; ;
octal only, no DP straight fractional, no DP CDU degrees (XXX.XX), no DP arithmetic SF, no DP DP1OUT DP2OUT Y OPTICS DEGREES, no DP DP3OUT HMS, no DP MS, no DP DP4OUT arith1, no DP 2INTOUT, no DP to get hi part in MPAC
; return to L+2
;----------------- --------------------------------------------------------; REQDATX, REQDATY , REQDATZ ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 323. ;----------------- --------------------------------------------------------REQDATX 14264 14265 14266 14267 6,0264 3 6,0265 5 6,0266 3 6,0267 0 0,0001 0 0,0554 0 2,4635 0 6,6277 0 REQDATY 14270 14271 14272 14273 6,0270 3 6,0271 5 6,0272 3 6,0273 0 0,0001 0 0,0554 0 2,4636 0 6,6277 0 REQDATZ 14274 14275 14276 14277 14300 14301 14302 14303 14304 6,0274 3 6,0275 5 6,0276 3 6,0277 6,0300 6,0301 6,0302 6,0303 5 4 5 0 0,0001 0 0,0554 0 2,4637 1 0,0466 0,0554 0,0502 1,3565 12473 0 REQCOM 1 0 1 1 EQU XCH TS CAF TC EQU XCH TS CAF TC EQU XCH TS CAF TS CS TS TC DS TC * Q REQ_Q R1D1 REQCOM * Q REQ_Q R2D1 REQCOM * Q REQ_Q R3D1 DSPCOUNT REQ_Q REQRET BANKCALL _5BLANK FLASHON
6,0304 0
2,4760 1
EQU TC
* ENTEXIT
;----------------- --------------------------------------------------------; UPDATNN, UPDATVB ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 323. ;----------------- --------------------------------------------------------14306 14307 14310 14311 14312 14313 14314 14315 14316 14317 6,0306 5 6,0307 3 6,0310 5 6,0311 3 6,0312 0 6,0313 6,0314 6,0315 6,0316 6,0317 1 6 0 0 0 0,0471 0 UPDATNN 0,0001 0 0,0414 0 6,6124 0 1,3526 0 0,0443 1,2051 6,6320 6,6321 6,6321 0 1 0 1 1 PUTADD 14320 14321 14322 14323 14324 14325 6,0320 0 6,0321 3 6,0322 5 6,0323 3 6,0324 6 6,0325 0 2,4616 1 2,4676 1 0,0466 0 1,2050 0 0,0471 0 6,6335 1 TS EQU XCH TS CAF TC CCS AD TC TC TC EQU TC CAF TS CAF AD TC NOUNREG * Q UPDATRET LODNNLOC DXCHJUMP NNADTEM ONE PUTADD PUTADD+1 PUTADD+1 * SETNCADR ND1 DSPCOUNT ZERO NOUNREG UPDAT1 ; was CA NOUNREG in Block II ; was DCA LODNNLOC, DXCH Z in Block II ; bank jump to noun table read rtne
; ; ; ;
normal normal MCTBS don't change NOUNADD MCTBI don't change NOUNADD
VERBREG * Q UPDATRET VD1 DSPCOUNT ZERO VERBREG * POSTJUMP GOVNUPDT UPDATRET ; was CA VERBREG in Block II
;----------------- --------------------------------------------------------; GOALMCYC, GODSPA LM ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 324. ;----------------- --------------------------------------------------------14340 6,0340 0 2,4474 1 GOALMCYC TC ALMCYCLE ; needed because bankjump cant handle F/ F
14341 14342
6,0341 0 6,0342
TC DS
POSTJUMP DSPALARM
;----------------- --------------------------------------------------------; DISPLAY VERBS ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 326. ;----------------- --------------------------------------------------------DSPABC 14343 14344 14345 14346 14347 6,0343 6,0344 6,0345 6,0346 6,0347 4 0 2 4 3 1,2052 6,6414 0,0442 0,0002 0,0427 0 0 1 1 0 DSPAB 14350 14351 14352 14353 6,0350 6,0351 6,0352 6,0353 4 0 2 4 1,2051 6,6414 0,0442 0,0001 0 0 1 1 EQU CS TC IND EX CS XCH EQU CS TC IND EX CS * TWO COMPTEST NOUNADD 2 BUF+2 * ONE COMPTEST NOUNADD 1
14354
6,0354 3
0,0426 1 DSPA
XCH EQU TC TC IND EX CS EQU XCH TC EQU CS TC IND EX CS TC EQU CS TC IND EX CS TC EQU CS AD CCS TC TC TC EQU TS IND EX CAF TS IND EX CS TC XCH TC
BUF+1 * DECTEST TSTFORDP NOUNADD 0 * BUF DSPCOM2 * ONE DCOMPTST NOUNADD 1 DSPCOM1 * TWO DCOMPTST NOUNADD 2 DSPCOM1 * TWO VERBREG A DSPCOM3 ENTEXIT *+1 * DISTEM A R1D1 DSPCOUNT DISTEM BUF DSPOCTWD DISTEM DSPCOM2+2
0 0 2 4
0 1 1 0 DSPCOM1
14361 14362
6,0361 3 6,0362 0
4 0 2 4 0
0 0 1 1 0 DSPC
4 0 2 4 0
0 0 1 1 0 DSPCOM2
4 6 1 0 0 0
0 1 0 0 0 0 DSPCOM3
; A B C AB ABC ; -1 -0 +1 +2 +3 ; +0 +0 +0 +1 +2
IN A IN A AFTER CCS
5 2 3 5 2 4 0 3 0
0 0 0 0 1 0 1 0 1
;----------------- --------------------------------------------------------; COMPTEST ; alarms if compon ent number of verb (load or oct display) is ; greater than the highest component number of noun. ; ; DCOMPTST ; alarms if decima l only bit (bit 4 of comp code number) = 1. ; If not, it perfo rms regular COMPTEST. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 326. ;----------------- --------------------------------------------------------COMPTEST 14414 14415 14416 6,0414 5 6,0415 3 6,0416 5 0,0420 1 0,0001 0 0,0547 1 COMPTST1 14417 14420 14421 14422 14423 14424 14425 14426 6,0417 6,0420 6,0421 6,0422 6,0423 6,0424 6,0425 6,0426 0 0 7 6 1 0 0 0 6,6501 2,4647 1,2053 0,0420 0,0000 0,0547 5,6271 6,6341 0 0 1 1 0 1 0 1 NDOMPTST 14427 6,0427 0 0,0547 1 DCOMPTST 14430 14431 14432 14433 14434 6,0430 5 6,0431 3 6,0432 5 6,0433 0 6,0434 0 0,0420 1 0,0001 0 0,0547 1 6,6435 0 6,6417 0 EQU TS XCH TS EQU TC TC MAS K AD CCS TC TC TC EQU TC EQU TS XCH TS TC TC * SFTEMP1 Q LXCH_LPRET * GETCOMP LEFT5 THREE SFTEMP1 A LXCH_LPRET CCSHOLE GODSPALM * LXCH_LPRET * SFTEMP1 Q LXCH_LPRET DECTEST COMPTST1
; noun comp ; noun comp - verb comp ; noun comp G/ verb comp; return ; noun comp L/ verb comp
;----------------- ---------------------------------------------------------
; DECTEST ; alarms if dec on ly bit = 1 (bit 4 of comp code number1). Returns if not. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 327. ;----------------- --------------------------------------------------------DECTEST 14435 14436 14437 14440 14441 14442 14443 6,0435 3 6,0436 5 6,0437 0 6,0440 7 6,0441 1 6,0442 0 6,0443 0 0,0001 0 0,0132 1 6,6501 0 1,2063 1 0,0000 0 6,6341 1 0,0132 1 EQU XCH TS TC MAS K CCS TC TC * Q MPAC+2 GETCOMP BIT14 A GODSPALM MPAC+2
;----------------- --------------------------------------------------------; DCTSTCYC ; alarms and recyc les if dec only bit = 1 (bit 4 of comp code number). ; Returns if not. Used by load verbs. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 327. ;----------------- --------------------------------------------------------DCTSTCYC 14444 14445 14446 14447 14450 14451 14452 6,0444 3 6,0445 5 6,0446 0 6,0447 7 6,0450 1 6,0451 0 6,0452 0 0,0001 0 0,0547 1 6,6501 0 1,2063 1 0,0000 0 2,4474 1 0,0547 1 EQU XCH TS TC MAS K CCS TC TC * Q LXCH_LPRET GETCOMP BIT14 A ALMCYCLE LXCH_LPRET
;----------------- --------------------------------------------------------; NOUNTEST ; alarms if no-loa d bit (bit 5 of comp code number) = 1 ; if not, it retur ns. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 327. ;----------------- --------------------------------------------------------NOUNTEST 14453 14454 14455 14456 14457 14460 14461 6,0453 3 6,0454 5 6,0455 0 6,0456 6,0457 6,0460 6,0461 1 0 0 0 0,0001 0 0,0547 1 6,6501 0 0,0000 0,0547 0,0547 6,6341 0 1 1 1 EQU XCH TS TC CCS TC TC TC * Q LXCH_LPRET GETCOMP A LXCH_LPRET LXCH_LPRET GODSPALM
;----------------- --------------------------------------------------------; TSTFORDP ; test for DP. If so, get minor part only. ; The Block II ver sion had some code that checked for a -1 in NNADTEM ; which meant use an I/O channel instead of memory. This was removed ; for the Block I. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 327. ;----------------- ---------------------------------------------------------
TSTFORDP 14462 14463 14464 14465 14466 14467 14470 14471 14472 14473 14474 14475 6,0462 3 6,0463 5 6,0464 6,0465 6,0466 6,0467 2 0 0 0 0,0001 0 0,0547 1 0,0435 6,6465 6,6470 0,0547 1 0 1 1
* Q LXCH_LPRET MIXBR * *+2 LXCH_LPRET SFRUTNOR DPTEST LXCH_LPRET NOUNADD ONE NOUNADD
; no DP ; was INCR NOUNADD in Block II ; DP E+1 into NOUNADD for minor part
14476
6,0476 0
0,0547 1
TC
LXCH_LPRET
;----------------- --------------------------------------------------------; GETCOMP ; ; noun address is in NNADTEM ; noun type is in NNTYPTEM ; ; MIXBR is an enum erated type: ; 1 = normal nouns ; 2 = mixed nouns ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 328. ;----------------- --------------------------------------------------------14477 14500 6,0477 6,0500 00444 0 COMPICK 00443 1 GETCOMP 14501 14502 14503 14504 14505 14506 14507 6,0501 2 6,0502 3 6,0503 6,0504 6,0505 6,0506 2 4 4 7 0,0435 1 6,6476 1 0,0000 0,0000 0,0000 2,4666 0 0 0 1 DS DS EQU IND EX CAF IND EX CS COM MAS K TC NNTYPTEM NNADTEM * MIXBR COMPICK-1 A 0 HI5 Q
C(NNADTEM)
6,0507 0
0,0001 0
;----------------- --------------------------------------------------------; DECDSP -- DECIMA L DISPLAY ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 328. ;----------------- --------------------------------------------------------DECDSP 14510 14511 14512 14513 6,0510 6,0511 6,0512 6,0513 0 0 7 5 6,6501 2,4647 1,2053 0,0414 0 0 1 0 DSPDCGET 14514 14515 14516 14517 14520 14521 14522 14523 6,0514 6,0515 6,0516 6,0517 6,0520 6,0521 6,0522 6,0523 5 6 2 4 2 3 1 0 0,0417 0,0442 0,0000 0,0000 0,0417 0,0472 0,0417 6,6514 0 0 0 0 1 0 1 1 DSPDCPUT 14524 14525 14526 14527 14530 14531 14532 14533 14534 14535 14536 14537 14540 14541 14542 14543 14544 14545 6,0524 6,0525 6,0526 6,0527 6,0530 6,0531 6,0532 6,0533 6,0534 6,0535 6,0536 3 5 5 2 3 5 2 4 5 0 5 1,2050 0,0131 0,0132 0,0414 2,4635 0,0466 0,0414 0,0472 0,0130 6,7003 0,0420 0 1 1 1 0 0 1 1 0 0 1 EQU TC TC MAS K TS EQU TS AD IND EX CS IND EX XCH CCS TC EQU CAF TS TS IND EX CAF TS IND EX CS TS TC TS CAF TC IND EX TC TC TC TC EQU TC TC DS EQU TC DS CCS TC TC TS * GETCOMP LEFT5 THREE DECOUNT * DECTEM NOUNADD A 0 DECTEM XREG DECTEM DSPDCGET * ZERO MPAC+1 MPAC+2 DECOUNT R1D1 DSPCOUNT DECOUNT XREG MPAC SFCONUM SFTEMP1 GTSFOUTL DXCHJUMP MIXBR *+0 DSPSFNOR SFRUTMIX DECDSP3 * SFRUTNOR DECDSP3 GTSFOUT * BANKCALL DSPDECWD DECOUNT *+2 ENTEXIT DECOUNT
; was DCA GTSFOUTL, DXCH Z in Block II ; bank jump to SF constant table read rt n e
0 1 0 0 5
1 1 1 1 0 0
14557
6,0557 0
6,6524 1 DECDSP3
TC EQU IND EX CAF TC EQU CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R
; more to display
14563 14564 14565 14566 14567 14570 14571 14572 14573 14574 14575 14576 14577
6,0563 6,0564 6,0565 6,0566 6,0567 6,0570 6,0571 6,0572 6,0573 6,0574 6,0575 6,0576 6,0577
13265 14551 12564 12644 00000 00000 00000 00000 16000 00000 00000 00000 00000
1 0 0 1 1 1 1 1 0 1 1 1 1
; ; ; ; ; ; ; ; ; ; ; ; ;
0, alarm if dec display with octal onl y n o u n 1 2 3 4 ********** 5 ********** 6 ********** 7 ********** 8 9 ********** 10 ********* 11 ********* 12 *********
BANK41_2
EQU
ORG BANK40_2 ; COLOSSUS pp. 330-332 INC L bank40_2.asm ;================= ========================================================= ; SCALE FACTOR ROU TINES (file:bank40_2.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 330-332. ;================= ========================================================= DEGOUTSF 12564 12565 12566 12567 12570 12571 5,0564 5,0565 5,0566 5,0567 5,0570 5,0571 3 5 0 0 0 0 1,2050 0,0132 5,6603 5,6571 5,6572 5,6616 0 1 1 1 1 0 SETAUG 12572 12573 12574 12575 12576 12577 12600 12601 12602 5,0572 5,0573 5,0574 5,0575 5,0576 5,0577 5,0600 5,0601 3 2 6 3 3 2 6 3 1,2050 0,0132 5,6640 0,0420 1,2050 0,0132 5,6641 0,0421 0 0 0 1 0 0 1 0 EQU CAF TS TC TC TC TC EQU CAF IND EX AD XCH CAF IND EX AD XCH TC FIXRANGE 12603 12604 12605 12606 12607 12610 12611 12612 12613 12614 12615 5,0603 3 5,0604 5 5,0605 5,0606 5,0607 5,0610 5,0611 5,0612 5,0613 5,0614 5,0615 1 0 0 0 4 7 5 2 0 0,0001 0 0,0563 1 0,0130 0,0563 0,0563 5,6611 1,2062 0,0130 0,0130 0,0563 0,0001 1 1 1 1 0 1 0 0 0 DEGCOM 12616 5,0616 Block II 12617 5,0617 12620 5,0620 12621 5,0621 12622 12623 12624 12625 12626 12627 12630 5,0622 5,0623 5,0624 5,0625 3 2 6 3 3 2 6 3 1,2050 0 0,0132 0 5,6641 1 0,0131 1 1,2050 0,0132 5,6640 0,0130 0 0 0 0 EQU XCH TS CCS TC TC TC CS MAS K TS IND EX TC EQU CAF IND EX AD XCH CAF IND EX AD XCH TC XCH AD * ZERO MPAC+2 FIXRANGE *+2 SETAUG DEGCOM * ZERO MPAC+2 DEGTAB SFTEMP1 ZERO MPAC+2 DEGTAB+1 SFTEMP1+1 Q * Q FR_RETQ MPAC FR_RETQ FR_RETQ *+1 BIT15 MPAC MPAC FR_RETQ 1 * ZERO MPAC+2 DEGTAB+1 MPAC+1 ZERO MPAC+2 DEGTAB MPAC SHORTMP SFTEMP1+1 MPAC+1 ; was DXCH SFTEMP1, DAS MPAC in Block II ; ; ; ; if MPAC if MPAC masking was TCF is +, return is -, return out the sign *+1 in Block to L+1 to L+2 after bit II
; set index for full scale ; no augment needed (SFTEMP1 and 2 are 0 ) ; set augmenter according to C(MPAC+2)
; loads SFTEMP1 and SFTEMP2 with the ; DP augmenter constant ; was DCA DEGTAB, DXCH SFTEMP1 in Block I I
5,0602 0
0,0001 0
; was INDEX MPAC+2, DCA DEGTAB, DXCH MPA C i n ; loads multiplier, does SHORTMP, and ; adds augmenter ; adjusted angle in A
TS CAF AD AD TS CAF
12637
5,0637 0
5,6651 0 DEGTAB
TC EQU DS DS DS DS
1 1 0 1
; ; ; ;
Hi Lo Hi Lo
of of of of
ARTOUTSF 12644 12645 12646 12647 12650 12651 12652 5,0644 5,0645 5,0646 5,0647 3 3 3 3 0,0421 0,0131 0,0420 0,0130 0 1 1 0
; was DXCH SFTEMP1, DXCH MPAC in Block I I ; assumes point at left of DP SFCON
;----------------- --------------------------------------------------------; READLO ; Picks up fresh d ata for both HI and LO and leaves it in MPAC, MPAC+1. ; This is needed f or time display. It zeroes MPAC+2, but does not force ; TPAGREE. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 332. ;----------------- --------------------------------------------------------READLO 12653 12654 12655 12656 12657 12660 12661 12662 12663 12664 5,0653 3 5,0654 5 5,0655 2 5,0656 0 5,0657 0 5,0660 5,0661 5,0662 5,0663 5,0664 3 2 6 7 0 0,0001 0 0,0441 0 0,0435 1 5,6656 1 5,6701 1 1,2050 0,0414 0,0445 2,4672 2,4633 0 1 1 1 0 EQU XCH TS IND EX TC TC CAF IND EX AD MAS K TC * Q TEM4 MIXBR * RDLONOR ZERO DECOUNT IDAD1TEM LOW11 SETEBANK ; MIXBR=1, so normal noun ; ; ; ; ; MIXBR=2, so mixed noun was INDEX DECOUNT, CA IDAD1TEM in Bloc k I I get IDADDTAB entry for comp K of noun E bank set EB, leave E address in A
; ; ; ;
Dereference noun address to move components of noun into MPAC, MPAC+1 mixed normal C(E SUBK) C(E) C((E SUBK)+1) C(E+1) EQU TS CAF IND EX AD TS CAF IND EX AD TS CAF TS TC CAF AD TC EQU ORG INC L * ADDRWD1 ZERO ADDRWD1 0 MPAC ZERO ADDRWD1 1 MPAC+1 ZERO MPAC+2 TEM4 ZERO NOUNADD READLO1 * BANK42_1 bank42_1.asm ; COLOSSUS pp. 333-336 ; return ; was CA NOUNADD in Block II
READLO1 12665 12666 12667 12670 12671 12672 12673 12674 12675 12676 12677 12700 12701 12702 12703 5,0665 5 5,0666 5,0667 5,0670 5,0671 5,0672 5,0673 5,0674 5,0675 3 2 6 5 3 2 6 5 0,0576 0 1,2050 0,0576 0,0000 0,0130 1,2050 0,0576 0,0001 0,0131 0 1 1 0 0 1 0 1
; temp store addr for immediate use belo w ; was INDEX A, DCA Q, DXCH MPAC in Block I I
;================= ========================================================= ; DISPLAY ROUTINES (file:bank42_1.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 333-336. ;================= ========================================================= ;----------------- --------------------------------------------------------; HMSOUT -- OUTPUT SCALE FACTOR ROUTINE ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 333. ;----------------- --------------------------------------------------------HMSOUT 16000 16001 16002 16003 16004 16005 16006 16007 16010 16011 16012 16013 16014 16015 16016 16017 16020 16021 16022 16023 16024 7,0000 0 7,0001 7,0002 0 7,0003 0 7,0004 0 7,0005 7,0006 3 7,0007 5 7,0010 0 7,0011 7,0012 7,0013 7,0014 7,0015 7,0016 7,0017 7,0020 0 3 3 5 3 3 0 1,3565 1 12653 1 2,4150 1 7,6053 1 EQU TC DS * BANKCALL READLO
TC TPAGREE ; make DP data agree TC SEPSECNR ; leave frac sec/60 in MPAC, MPAC+1, lea v e ; whole min in bit 13 of LOWTEMOUT and above 2,4374 0 TC DMP ; use only fract sec/60 mod 60 06043 0 ADR ES SECON2 ; mult by .06 2,4637 1 0,0466 0 1,3565 1 13064 1 7,6074 7,6045 0,0130 0,0476 7,6046 0,0131 2,4740 1 0 0 1 0 1 0 ; mult by .0006 CAF TS TC DS TC CAF XCH TS CAF XCH TC CAF TS TC DS R3D1 DSPCOUNT BANKCALL DSPDECWD SEPMIN MINCON2 MPAC HITEMOUT MINCON2+1 MPAC+1 PRSHRTMP R2D1 DSPCOUNT BANKCALL DSPDECWD ; gives CENT1-SEC/10EXP5 mod 60
; ; ; ;
remove rest of seconds leave fract min/60 in MPAC+1, leave whole hours in MPAC save whole hours
; use only fract min/60 mod 60 ; if C(A) = -0, SHORTMP fails to give -0 . ; gives min/10EXP5 mod 60
16025 16026 16027 16030 16031 16032 16033 16034 16035 16036 16037 16040 16041 16042 16043 16044 16045 16046 16047 16050 16051 16052
3 5 3 5
0 0 0 1
CAF TS CAF TS
HRCON1 MPAC HRCON1+1 MPAC+1 ZERO HITEMOUT PRSHRTMP R1D1 DSPCOUNT BANKCALL DSPDECWD ENTEXIT %25660 %31742 %01727 %01217 %00011 %32445 %02104 %10422 %05174 %13261
; minutes, seconds have been removed ; was CA HITEMOUT in Block II ; use whole hours ; if C(A) = -0, SHORTMP fails to give -0 . ; gives hours/10EXP5
7,0031 3 7,0032 6 7,0033 0 7,0034 3 7,0035 5 7,0036 0 7,0037 7,0040 0 7,0041 7,0042 7,0043 7,0044 7,0045 7,0046 7,0047 7,0050 7,0051 7,0052
CAF AD TC ; mult by .16384 2,4635 0 CAF 0,0466 0 TS 1,3565 1 13064 1 0,0433 0 25660 0 SECON1 31742 1 01727 1 SECON2 01217 1 00011 1 MINCON2 32445 0 02104 0 MINCON1 10422 1 05174 0 HRCON1 13261 0 TC DS TC DS DS DS DS DS DS DS DS DS DS
; 2EXP12/6000
; .16384 decimal
; ************* mi ssing stuff **************** SEPSECNR 16053 16054 16055 16056 7,0053 3 7,0054 5 7,0055 0 7,0056 0,0001 0 0,0441 0 2,4374 0 06041 1 EQU XCH TS TC ADR ES * Q SEPSCRET DMP SECON1
16057 16060 16061 16062 16063 16064 16065 16066 16067 16070 16071 16072 16073
7,0057 3 7,0060 6 7,0061 3 7,0062 3 7,0063 6 7,0064 3 7,0065 0 7,0066 0 7,0067 7,0070 7,0071 7,0072 3 3 3 3
1,2050 0 0,0130 0 0,0476 1 1,2050 0 0,0131 1 0,0477 0 2,4721 1 2,4721 1 1,2050 0,0132 0,0131 0,0130 0 1 1 0
ZERO MPAC HITEMOUT ZERO MPAC+1 HITEMOUT+1 TPSL1 TPSL1 ZERO MPAC+2 MPAC+1 MPAC SEPSCRET
; was DCA MPAC, DXCH HITEMOUT in Block I I ; save minutes and hours
7,0073 0
0,0441 0
SEPMIN 16074 16075 16076 16077 16100 16101 16102 16103 16104 16105 7,0074 3 7,0075 5 7,0076 3 7,0077 6 7,0100 7,0101 7,0102 7,0103 2 4 2 4 0,0001 0 0,0441 0 1,2050 0 0,0477 0 0,0000 1,2076 0,0000 1,2064 1 0 1 0
; removes rest of seconds ; ; ; ; leaves leaves SR 12, SR 2?, fract min/60 in MPAC+1 whole hours in MPAC throw away LP take from LP. = SL 12
BIT3 BIT13
7,0104 3 7,0105 5
0,0003 1 0,0131 1
XCH LP TS MPAC+1 ; forces bits 12-1 to 1 if -. CAF AD TS TC ADR ES TC ZERO HITEMOUT MPAC DMP MINCON1 SEPMNRET
; mult by 1/15 ; gives fract min/60 in MPAC+1 ; gives whole hours in MPAC
BANK42_2
EQU
ORG BANK40_3 ; COLOSSUS pp. 336 INC L bank40_3.asm ;================= ========================================================= ; WORD DISPLAY ROU TINES (file:bank40_3.asm) ; ; AGC Block II COL OSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 336. ;================= ========================================================= ;----------------- --------------------------------------------------------; DSPDPDEC ; This is a specia l purpose verb for displaying a double precision AGC ; word as 10 decim al digits on the AGC display panel. It can be used with ; any noun, except mixed nouns. It displays the contents of the register ; NOUNADD is point ing to. If used with nouns which are inherently not DP ; such as the CDU counters, the display will be garbage. ; Display is in R1 and R2 only with the sign in R1. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 353. ;----------------- --------------------------------------------------------DSPDPDEC 12704 12705 12706 12707 12710 12711 12712 12713 12714 12715 12716 12717 12720 12721 5,0704 5,0705 5,0706 5,0707 5,0710 5,0711 5,0712 5,0713 5,0714 5,0715 5,0716 5,0717 2 0 0 0 3 2 6 5 3 2 6 5 0,0435 5,6705 5,6710 5,7267 1,2050 0,0442 0,0000 0,0130 1,2050 0,0442 0,0001 0,0131 1 0 1 0 0 1 1 0 0 1 0 1 EQU IND EX TC TC TC CAF IND EX AD TS CAF IND EX AD TS CAF TS * MIXBR *+0 *+2 DSPALARM ZERO NOUNADD 0 MPAC ZERO NOUNADD 1 MPAC+1 R1D1 DSPCOUNT
; normal noun
5,0720 3 5,0721 5
2,4635 0 0,0466 0
CAF TS TC TC TC
BANK40_4
EQU
ORG BANK41_2 ; COLOSSUS pp. 337-342 INC L bank41_2.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bank41_2.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 337-342. ;================= ========================================================= ;================= ========================================================= ; PINBALL GAME LOA D VERBS (file:bank41_2.asm) ; ; If alarm conditi on is detected during execute, check fail light is ; turned on and EN DOFJOB. If alarm condition is detected during enter ; of data, check f ail is turned on and it recycles to execute of ; original load ve rb. Recycle caused by 1) decimal machine CADR, ; 2) mixture of oc tal/decimal data, 3) octal data into decimal only ; noun, 4) decimal data into octal only noun, 5) data too large for ; scale, 6) fewer than two data words loaded for HRS, MIN, SEC noun. ; For #2-6, alarm and recycle occur at final enter of set; for #1, ; alarm and recycl e occur at enter of CADR. ; ; AGC Block II COL OSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 337-343. ;================= ========================================================= ABCLOAD 14600 14601 14602 14603 14604 14605 14606 14607 14610 14611 14612 14613 6,0600 4 6,0601 0 6,0602 0 6,0603 3 6,0604 0 6,0605 0 6,0606 3 6,0607 0 6,0610 0 6,0611 3 6,0612 0 6,0613 0 1,2052 0 6,6414 0 6,6453 0 6,6733 0 6,6326 0 6,6264 1 6,6734 1 6,6326 0 6,6270 1 6,6735 0 6,6326 0 6,6274 0 PUTXYZ 14614 14615 14616 14617 14620 14621 14622 14623 14624 14625 14626 14627 14630 14631 14632 14633 6,0614 4 6,0615 0 6,0616 3 6,0617 0 6,0620 6,0621 6,0622 6,0623 6,0624 6,0625 6,0626 6,0627 6,0630 6,0631 6,0632 6,0633 3 0 2 5 3 0 2 5 3 0 2 5 1,2056 1 6,6736 0 6,6124 0 1,3526 0 1,2050 6,7031 0,0442 0,0000 1,2051 6,7031 0,0442 0,0001 1,2052 6,7031 0,0442 0,0002 0 1 1 1 1 1 1 0 1 1 1 0 EQU CS TC TC CAF TC TC CAF TC TC CAF TC TC EQU CS TC CAF TC CAF TC IND EX TS CAF TC IND EX TS CAF TC IND EX TS * TWO COMPTEST NOUNTEST VBSP1LD UPDATVB-1 REQDATX VBSP2LD UPDATVB-1 REQDATY VBSP3LD UPDATVB-1 REQDATZ * SIX ALLDC_OC LODNNLOC DXCHJUMP ZERO PUTCOM NOUNADD 0 ONE PUTCOM NOUNADD 1 TWO PUTCOM NOUNADD 2
; test that the 3 data words loaded are ; all dec or all oct ; was DCA LODNNLOC, DXCH Z in Block II ; bank jump to noun table read rtne ; X comp
; Y comp
; Z comp
; *************** missing stuff ***************** ; Omitted a bunch of code from here that does special stuff if the noun=7. ; (a noun that ope rates on I/O channels and flagbits) 14634 6,0634 0 6,6723 1 TC LOADLV
ABLOAD
EQU
1,2051 0 6,6414 0 6,6453 0 6,6733 0 6,6326 0 6,6264 1 6,6734 1 6,6326 0 6,6270 1 PUTXY
CS TC TC CAF TC TC CAF TC TC EQU CS TC CAF TC CAF TC IND EX TS CAF TC IND EX TS TC ALOAD EQU TC CAF TC CAF TC IND EX TS TC BLOAD EQU CS TC CAF TS TC CAF TC CAF TC IND EX TS TC EQU CS TC CAF TS TC CAF TC CAF TC IND EX TS TC EQU CAF TS CS TS CS TS TC DS DS DS DS EQU TS
ONE COMPTEST NOUNTEST VBSP1LD UPDATVB-1 REQDATX VBSP2LD UPDATVB-1 REQDATY * FIVE ALLDC_OC LODNNLOC DXCHJUMP ZERO PUTCOM NOUNADD 0 ONE PUTCOM NOUNADD 1 LOADLV * REQDATX LODNNLOC DXCHJUMP ZERO PUTCOM NOUNADD 0 LOADLV * ONE COMPTEST BIT15 CLPASS REQDATY LODNNLOC DXCHJUMP ONE PUTCOM NOUNADD 1 LOADLV * TWO COMPTEST BIT15 CLPASS REQDATZ LODNNLOC DXCHJUMP TWO PUTCOM NOUNADD 2 LOADLV * ZERO DECBRNCH ZERO LOADSTAT VD1 DSPCOUNT POSTJUMP RECALTST 21 22 23 * DECOUNT
14646 14647 14650 14651 14652 14653 14654 14655 14656 14657 14660 14661 14662
6,0646 4 6,0647 0 6,0650 3 6,0651 0 6,0652 6,0653 6,0654 6,0655 6,0656 6,0657 6,0660 6,0661 3 0 2 5 3 0 2 5
1,2055 1 6,6736 0 6,6124 0 1,3526 0 1,2050 6,7031 0,0442 0,0000 1,2051 6,7031 0,0442 0,0001 0 1 1 1 1 1 1 0
; test that the 2 data words loaded are ; all dec or all oct ; was DCA LODNNLOC, DXCH Z in Block II ; bank jump to noun table read rtne ; X comp
; Y comp
6,0662 0
6,6723 1
; was DCA LODNNLOC, DXCH Z in Block II ; bank jump to noun table read rtne ; X comp
14673 14674 14675 14676 14677 14700 14701 14702 14703 14704 14705 14706
6,0673 6,0674 6,0675 6,0676 6,0677 6,0700 6,0701 6,0702 6,0703 6,0704 6,0705 6,0706
4 0 3 5 0 3 0 3 0 2 5 0
1,2051 6,6414 1,2062 0,0504 6,6270 6,6124 1,3526 1,2051 6,7031 0,0442 0,0001 6,6723
0 0 1 0 1 0 0 1 1 1 0 1 CLOAD
; was DCA LODNNLOC, DXCH Z in Block II ; bank jump to noun table read rtne
14707 14710 14711 14712 14713 14714 14715 14716 14717 14720 14721 14722
6,0707 6,0710 6,0711 6,0712 6,0713 6,0714 6,0715 6,0716 6,0717 6,0720 6,0721 6,0722
4 0 3 5 0 3 0 3 0 2 5 0
1,2052 6,6414 1,2062 0,0504 6,6274 6,6124 1,3526 1,2052 6,7031 0,0442 0,0002 6,6723
0 0 1 0 0 0 0 1 1 1 0 1 LOADLV
; was DCA LODNNLOC, DXCH Z in Block II ; bank jump to noun table read rtne
14723 14724 14725 14726 14727 14730 14731 14732 14733 14734 14735
6,0723 6,0724 6,0725 6,0726 6,0727 6,0730 6,0731 6,0732 6,0733 6,0734 6,0735
3 5 4 5 4 5 0
0 1 1 1 0 0 1 0
; ; ; ;
to block numerical chars and clears after a completed load after completed load, go to RECALTST to see if there is RECALL from ENDIDLE
14736
6,0736 5
0,0414 0
14737 14740 14741 14742 14743 14744 14745 14746 14747 14750 14751 14752 14753 14754 14755 14756 14757 14760 14761
6,0737 3 6,0740 5 6,0741 6,0742 6,0743 6,0744 6,0745 6,0746 6,0747 6,0750 6,0751 6,0752 6,0753 6,0754 6,0755 4 5 4 4 1 0 0 6 1 0 0 0 0
0,0001 0 0,0556 1 0,0467 0,0021 0,0021 0,0021 0,0000 6,6750 0,0556 0,0414 0 1 0 0 0 0 1 0
XCH TS
Q ALLDC_OC_Q
; (needed to handle TCF conversion below ) ; save return address ; all dec or all oct; alarms if not
CS DECBRNCH TS SR CS SR CS SR CCS A TC *+2 TC ALLDC_OC_Q AD DECOUNT ; (but it has been decremented by CCS) 0,0000 0 CCS A 6,6756 0 TC *+4 6,6755 0 TC *+2 6,6756 0 TC *+2 6,6757 1 TC *+2 2,4474 1 0,0556 1 0,0001 0 0,0001 0 GOQ TC XCH TS TC ALMCYCLE ALLDC_OC_Q Q Q
; ; ; ; ; ; ; ; ; ;
shifted right 2 dec comp bits in low 3 some ones in low 3 (was TCF in Block I I ) all zeros, all oct, OK so return dec comp = 7 for 3comp, =6 for 2comp must match 6 for 3comp, 5 for 2comp >0 +0 <0 -0, was BZF *+2 in Block II
; alarm and recycle (does not return) ; restore return address ; all required are dec, OK
;----------------- --------------------------------------------------------; SFRUTNOR ; gets SF routine number for normal case. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 340. ;----------------- --------------------------------------------------------SFRUTNOR 14762 14763 14764 14765 14766 14767 6,0762 6,0763 6,0764 6,0765 6,0766 6,0767 3 5 3 7 0 0 0,0001 0,0411 2,4665 0,0444 2,4640 0,0411 0 0 0 1 1 0 EQU XCH TS CAF MAS K TC TC * Q EXITEM MID5 NNTYPTEM RIGHT5 EXITEM
; SF routine number in A
;----------------- --------------------------------------------------------; SFRUTMIX ; gets SF routine number for mixed case. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 340. ;----------------- --------------------------------------------------------SFRUTMIX 14770 14771 14772 14773 14774 14775 14776 14777 15000 15001 6,0770 3 6,0771 5 6,0772 2 6,0773 3 6,0774 5 6,0775 2 6,0776 3 6,0777 7 6,1000 2 6,1001 0 0,0001 0 0,0411 0 0,0414 1 6,7022 0 0,0557 0 0,0414 1 2,4664 1 0,0450 1 0,0557 1 0,0000 1 EQU XCH TS IND EX CAF TS IND EX CAF MAS K IND EX TC * Q EXITEM DECOUNT DISPLACE SFRUTMIX_L DECOUNT LOW5 RUTMXTEM SFRUTMIX_L 0
; do TC GOQ (DECOU NT=0), do TC RIGHT5 (DECOUNT=1), do TC LEFT5 (DECOUNT=2) 15002 6,1002 0 0,0411 0 SFRET1 TC EXITEM ; SF routine number in A
SFCONUM 15003 15004 15005 15006 15007 15010 15011 15012 15013 15014 15015 15016 15017 6,1003 6,1004 6,1005 6,1006 6,1007 6,1010 6,1011 6,1012 6,1013 6,1014 6,1015 6,1016 6,1017 3 5 2 0 0 2 3 5 2 3 7 2 0 0,0001 0,0411 0,0435 6,7006 6,7025 0,0414 6,7022 0,0560 0,0414 2,4664 0,0444 0,0560 0,0000 0 0 1 0 1 1 0 1 1 1 1 0 1
* Q EXITEM MIXBR *+0 CONUMNOR DECOUNT DISPLACE SFCONUM_L DECOUNT LOW5 NNTYPTEM SFCONUM_L 0
15020 15021
6,1020 6 6,1021 0
DOU BLE TC
DISPLACE 15022 15023 15024 6,1022 0 6,1023 0 6,1024 0 6,6761 1 2,4640 1 2,4647 0 CONUMNOR 15025 15026 15027 15030 6,1025 6,1026 6,1027 6,1030 3 7 6 0 2,4664 0,0444 0,0000 0,0411 1 1 1 0 PUTCOM 15031 15032 15033 15034 15035 15036 15037 15040 15041 15042 15043 15044 15045 15046 6,1031 6,1032 6,1033 6,1034 6,1035 6,1036 6,1037 6,1040 6,1041 6,1042 6,1043 6,1044 6,1045 6,1046 5 3 5 3 5 2 3 5 2 3 5 2 0 0 0,0414 0,0001 0,0412 1,2050 0,0136 0,0414 0,0475 0,0131 0,0414 0,0472 0,0130 0,0435 6,7045 6,7077 0 0 0 0 0 1 1 1 1 0 0 1 1 0
EQU TC TC TC EQU CAF MAS K DOU BLE TC EQU TS XCH TS CAF TS IND EX XCH TS IND EX XCH TS IND EX TC TC
* GOQ RIGHT5 LEFT5 * LOW5 NNTYPTEM EXITEM * DECOUNT Q DECRET ZERO MPAC+6 DECOUNT XREGLP MPAC+1 DECOUNT XREG MPAC MIXBR * PUTNORM
; normal noun always gets low 5 of ; NNTYPTAB for SF CONUM ; 2X (SF constant number) in A
; normal noun
; if mixnoun, plac e address for component K into NOUNADD, set EBANK bits. 15047 15050 15051 15052 15053 15054 15055 15056 15057 15060 15061 15062 15063 15064 6,1047 6,1050 6,1051 6,1052 6,1053 6,1054 6,1055 6,1056 6,1057 6,1060 6,1061 6,1062 6,1063 6,1064 2 3 6 7 0 2 6 5 1 0 0 0 0 0 0,0414 1,2050 0,0445 2,4672 2,4616 0,0000 0,0414 0,0442 0,0467 6,7114 6,6444 6,6770 6,6240 6,7111 1 0 1 1 1 1 0 0 0 1 0 1 1 1 IND EX DECOUNT ; CAF ZERO ; AD IDAD1TEM ; MAS K LOW11 ; TC SETNCADR ; EXT END ; SU DECOUNT ; TS NOUNADD CCS DECBRNCH TC PUTDECSF ; TC DCTSTCYC ; TC SFRUTMIX ; TC DPTEST ; TC PUTCOM2 ; ; test for DP scal e for oct load. If so, ; +0 into major pa rt. Set NOUNADD for ; loading octal wo rd into minor part. PUTDPCOM 15065 15066 15067 15070 15071 15072 15073 15074 15075 15076 6,1065 6,1066 6,1067 6,1070 3 6 6 5 1,2050 0,0442 1,2051 0,0442 0 0 1 0 EQU CAF AD AD TS AD TS CAF IND EX TS TC PUTNORM 15077 15100 15101 15102 15103 15104 15105 15106 15107 15110 6,1077 6,1100 6,1101 6,1102 6,1103 6,1104 6,1105 6,1106 6,1107 6,1110 0 1 0 0 0 0 0 3 5 0 2,4625 0,0467 6,7114 6,6444 6,6762 6,6240 6,7111 1,2050 0,0414 6,7065 1 0 1 0 1 1 1 0 0 0 PUTNORM_1 PUTCOM2 15111 15112 15113 6,1111 3 6,1112 0 6,1113 0,0130 0 0,0412 0 16176 0 GTSFINLC EQU TC CCS TC TC TC TC TC CAF TS TC EQU EQU XCH TC DS * ZERO NOUNADD ONE NOUNADD DECOUNT DECOUNT ZERO DECOUNT -1 PUTCOM2 * SETNADD DECBRNCH PUTDECSF DCTSTCYC SFRUTNOR DPTEST PUTNORM_1 ZERO DECOUNT PUTDPCOM * * MPAC DECRET GTSFIN set IDADDTAB entry for component K of noun was CA IDAD1TEM in Block II (ECADR) SUBK for current comp of noun ECADR into NOUNCADR, sets EB, NOUNADD C(NOUNADD) in A upon return place (ESUBK)-K into NOUNADD
+ dec +0 octal test if dec only bit = 1. If so, alarm and recycle. If not, continue. no DP
0,0414 0 0,0414 0
; (ESUBK)+1 or E+1 into DECOUNT ; was ADS DECOUNT in Block II ; NOUNADD set for minor part ; zero major part (ESUBK or E1)
; ECADR from NOUNCADR, sets EB, NOUNADD ; ; ; ; ; +DEC +0 octal test if dec only bit = 1. If so, alarm and recycle. If not, continue. no DP
; PUTDECSF ; Finds MIXBR and DECOUNT still set from PUTCOM PUTDECSF 15114 15115 15116 15117 15120 15121 15122 15123 15124 15125 15126 15127 15130 15131 15132 15133 15134 15135 15136 15137 15140 15141 15142 15143 15144 15145 6,1114 0 6,1115 5 6,1116 3 6,1117 0 6,1120 6,1121 6,1122 6,1123 6,1124 6,1125 2 0 0 0 0 0 6,7003 0 0,0420 1 6,7113 0 1,3526 0 0,0435 6,7121 6,7125 6,6770 6,7126 6,6762 0,0000 6,7131 1,3712 14340 13011 12727 12776 00000 00000 00000 00000 00000 00000 00000 00000 00000 1 1 0 1 0 1 EQU TC TS * SFCONUM SFTEMP1
CAF GTSFINLC TC DXCHJUMP ; loads SFTEMP1, S FTEMP2 IND EX MIXBR TC * TC PUTSFNOR TC SFRUTMIX TC PUTDCSF2 PUTSFNOR TC SFRUTNOR IND EX CAF TC CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R CAD R A SFINTABR BANKJUMP GOALMCYC BINROUND DEGINSF ARTHINSF 0 0 0 0 0 0 0 0 0
; was DCA GTSFINLC, DXCH Z in Block II ; bank jump to SF const table read rtne
6,1126 2 6,1127 3 6,1130 0 6,1131 6,1132 6,1133 6,1134 6,1135 6,1136 6,1137 6,1140 6,1141 6,1142 6,1143 6,1144 6,1145
0 PUTDCSF2 0 0 0 SFINTABR 0 0 1 1 1 1 1 1 1 1 1 1
; ; ; ; ; ; ; ; ; ; ; ; ; ;
switch banks for expansion room 0, alarm and recycle if dec load 1 2 3 4 ********** 5 ********** 6 ********** 7 ********** 8 ********** 9 ********** 10 ********* 11 ********* 12 *********
; BUNCH OF TABLE E NTRIES GO HERE!!!!! ; ************ NEE D TO ADD THE REST *************
BANK41_3
EQU
ORG BANK40_4 ; COLOSSUS pp. 343-346 INC L bank40_4.asm ;================= ========================================================= ; SCALE FACTOR ROU TINES (file:bank40_4.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 343-346. ;================= ========================================================= DEGINSF 0 0 0 0 0 1 1 1 1 1 DEGINSF2 1 1 1 0 0 0 0 1 SIGNFIX 0 1 1 0 1 1 0 0 0 ENDSCALE 12762 12763 12764 12765 5,0762 0 5,0763 5,0764 4 5,0765 0 1,3653 1 15111 1 1,2106 0 NEG180 5,6761 1 EQU TC ADR ES CCS CAF TC CS AD TC TC TC TC TC CCS TC TC COM TS CCS TC TC CCS TC TC TC XCH MAS K TS EQU TC CAD R CS TC * DMP DEGCON1 MPAC+1 BIT11 *+2 BIT11 MPAC+1 _2ROUND+2 TPSL1 TPSL1 TESTOFUF TPSL1 MPAC SIGNFIX SIGNFIX MPAC MPAC+6 SGNTO1 ENDSCALE MPAC CCSHOLE NEG180 *+1 MPAC POSMAX MPAC * POSTJUMP PUTCOM2 POSMAX ENDSCALE-1
12727 12730 12731 12732 12733 12734 12735 12736 12737 12740 12741 12742 12743 12744 12745 12746 12747 12750 12751 12752 12753 12754 12755 12756 12757 12760 12761
5,0727 5,0730 5,0731 5,0732 5,0733 5,0734 5,0735 5,0736 5,0737 5,0740 5,0741 5,0742 5,0743 5,0744 5,0745 5,0746 5,0747 5,0750 5,0751 5,0752 5,0753 5,0754 5,0755 5,0756 5,0757 5,0760 5,0761
0 1 3 0 4 6 0 0 0 0 0 1 0 0 4 5 1 0 0 1 0 0 0 3 7 5
2,4374 06772 0,0131 1,2066 5,6735 1,2066 0,0131 5,7016 2,4721 2,4721 5,7025 2,4721 0,0130 5,6750 5,6750 0,0000 0,0130 0,0136 5,6766 5,6762 0,0130 5,6271 5,6764 5,6757 0,0130 1,2106 0,0130
; ; ; ; ;
SF routine for dec degrees mult by 5.5 5(10)X2EXP-3 this rounds off MPAC+1 before shift left 3, and causes 360.00 to OF/UF when shifted left and alarm
; left 1 ; left 2 ; returns if no OF/UF (left 3) ; ; ; ; if if if -f +, go to SIGNFIX +0, go to SIGNFIX -, use -MAGNITUDE + 1 -0; use +0
SGNTO1 12766 12767 12770 12771 12772 12773 12774 12775 5,0766 5,0767 5,0770 5,0771 5,0772 5,0773 5,0774 5,0775 4 7 4 0 0,0130 1,2106 0,0000 5,6761 1 0 0 1
EQU CS MAS K CS TC DS DS DS DS
; if OV force sign to 1
; ************ mis sing stuff *************** ARTHINSF 12776 12777 13000 13001 13002 13003 13004 13005 13006 13007 13010 5,0776 5,0777 5,1000 5,1001 5,1002 5,1003 5,1004 5,1005 5,1006 5,1007 0 3 3 3 1 0 0 0 0 2,4374 00420 0,0132 0,0131 0,0130 0,0000 5,7010 5,7007 5,7010 5,7011 0 1 1 1 0 0 1 1 1 0 EQU TC ADR ES XCH XCH XCH CCS TC TC TC TC TC BINROUND 13011 13012 13013 5,1011 0 5,1012 0 5,1013 0 5,7014 0 5,7025 1 5,6762 1 EQU TC TC TC * DMP SFTEMP1 MPAC+2 MPAC+1 MPAC A *+4 *+2 *+2 BINROUND ALMCYCLE * _2ROUND TESTOFUF ENDSCALE
; ; ; ;
scales MPAC, +1 by SFTEMP1, SFTEMP2 assumes point between HI and LO parts of SFCON, shifts results left by 14. (by taking results from MPAC+1, MPAC+2 )
; ; ; ; ;
5,1010 0
2,4474 1
; ************ mis sing stuff *************** _2ROUND 1 1 1 0 0 0 0 0 0 _2RNDEND TESTOFUF 13025 13026 13027 13030 5,1025 5,1026 5,1027 5,1030 1 0 0 0 0,0136 2,4474 0,0001 2,4474 1 1 0 1 BANK40_5 EQU XCH DOU BLE TS TC AD TS TC TS TC EQU CCS TC TC TC EQU ORG EQU * MPAC+1 MPAC+1 Q MPAC MPAC Q MPAC+6 Q * MPAC+6 ALMCYCLE Q ALMCYCLE * BANK42_2 *
3 6 5 0 6 5 0 5 0
; returns if no OF/UF ; OF, alarm and recycle ; UF, alarm and recycle
BANK42_3
ORG BANK41_3 INC L bank41_3.asm ; COLOSSUS pp. 349-351 ;================= ========================================================= ; DISPLAY ROUTINES (file:bank41_3.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 349-351. ;================= ========================================================= ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; MONITOR allows o ther keyboard activity. It is ended by verb TERMINATE verb PROCEED WIT HOUT DATA, verb RESEQUENCE, another monitor, or any NVSUB call that passes DSPLOCK (provided that the operator has somehow allowed the endi ng of a monitor which he has initiated through the keyboard. MONITOR action i s suspended, but not ended, by any keyboard action, except error lig ht reset. It begins again when KEY RELEASE is performed. MONITOR saves th e noun and appropriate display verb in MONSAVE. It saves NOUNCADR in MONS AVE1, if noun = machine CADR to be specified. Bit 15 of MONSAVE1 is the kill monitor signal (killer bit). Bit 14 of MONSAVE1 indicates the cu rrent monitor was externally initiated (external monitor bit). It is turn ed off by RELDSP and KILMONON. MONSAVE indicate s if MONITOR is on (+=ON, +0=OFF) If MONSAVE is +, monitor enters no request, but turns killer bit off. If MONSAVE is +0 , monitor enters request and turns killer bit off. NVSUB (if extern al monitor bit is off), VB=PROCEED WITHOUT DATA,
; ; ; ; ; ;
VB=RESEQUENCE, a nd VB=TERMINATE turn kill monitor bit on. If killer bit is on, MONREQ enters no further requests, zeroes MONSAVE and MONSAVE1 (tu rning off killer bit and external monitor bit). MONITOR doesn't test for MATBS since NVSUB can handle internal MATBS now.
MONITOR 15146 15147 6,1146 4 6,1147 7 6,7155 0 0,0506 0 MONIT1 15150 15151 15152 15153 15154 15155 15156 15157 15160 15161 15162 15163 6,1150 5 6,1151 6,1152 6,1153 6,1154 4 6 1 0 0,0131 1 0,0433 2,4553 0,0000 6,7164 1 0 0 0
* BIT15_14 NOUNCADR * MPAC+1 ENTEXIT ENDINST A MONIT2 %60000 MONIT2 BIT14 MPAC+1 MPAC+1 ZERO MONSAVE2 * LOW7 VERBREG LEFT5 CYL CYL CYL NOUNREG MPAC ZERO DSPLOCK CADRSTOR *+2 RELDSP1 MONSAVE *+4 ONE WAITLIST MONREQ MPAC+1 MONSAVE+1 MPAC MONSAVE ; externally initiated monitor ; was ADS MPAC+1 in Block II ; set bit 14 for MONSAVE1
; temp storage
15164 15165 15166 15167 15170 15171 15172 15173 15174 15175 15176 15177 15200 15201 15202 15203 15204 15205 15206 15207 15210 15211 15212
6,1164 6,1165 6,1166 6,1167 6,1170 6,1171 6,1172 6,1173 6,1174 6,1175 6,1176 6,1177 6,1200 6,1201 6,1202 6,1203
3 7 0 5 4 3 6 5 3 5 1 0 0 2 1 0
1,2101 0,0470 2,4647 0,0022 0,0022 0,0022 0,0471 0,0130 1,2050 0,0501 0,0531 6,7201 2,5026 0,0000 0,0507 6,7207
0 0 0 1 0 1 0 0 0 0 1 0 0 0 1 0
EQU CAF MAS K TC TS CS XCH AD TS CAF TS CCS TC TC INH INT CCS TC CAF TC CAD R XCH XCH XCH XCH
; temp storage ; ; ; ; +0 into DSPLOCK so monitor can run turn off KR lite if CADRSTOR and DSPLI S T are both empty. (Lite comes on if new monitor is keyed in over old monitor.)
; place monitor verb and noun into MONSA V E ; zero the kill monitor bit
15213 15214
6,1213 2 6,1214 0
REL INT TC EQU TC CCS TC TC TC TC CAF TC CAD R CAF TC CAD R TC KILLMON EQU CAF TS TS TC DS
; set up external monitor bit ENTRET * LODSAMPT MONSAVE1 *+4 *+3 KILLMON KILLMON MONDEL WAITLIST MONREQ CHRPRIO NOVAC MONDO TASKOVER * ZERO MONSAVE MONSAVE1 TASKOVER %144
15215 15216 15217 15220 15221 15222 15223 15224 15225 15226 15227 15230 15231
0 1 0 0 0 0
0 1 0 0 0 0
; ; ; ; ; ;
called by waitlist (see COLOSSUS p. 37 4 ) time is snatched in RUPT for NOUN 65 if killer bit = 0, enter requests if killer bit = 0, enter requests if killer bit = 1, no requests if killer bit = 1, no requests
3 5 5 0
0 0 0 0
; zero MONSAVE and turn killer bit off ; turn off kill monitor bit ; turn off external monitor bit ; for 1 sec monitor intervals
00144 0 MONDEL
MONDO 15237 15240 15241 15242 15243 15244 15245 15246 15247 15250 15251 15252 15253 15254 15255 15256 15257 15260 15261 15262 15263 15264 15265 15266 15267 15270 15271 15272 15273 6,1237 6,1240 6,1241 6,1242 6,1243 6,1244 6,1245 6,1246 6,1247 6,1250 6,1251 6,1252 6,1253 6,1254 6,1255 6,1256 6,1257 6,1260 6,1261 6,1262 6,1263 6,1264 6,1265 6,1266 6,1267 6,1270 6,1271 6,1272 6,1273 1 0 0 0 0 1 0 3 7 0 3 7 6 5 4 4 4 4 4 4 3 7 5 3 5 4 7 5 0 0,0510 6,7244 6,7244 1,2723 1,2723 0,0501 6,7276 1,2101 0,0507 6,6306 2,4473 0,0507 6,7274 0,0020 0,0020 0,0020 0,0020 0,0020 0,0020 0,0020 0,0020 1,2101 0,0470 6,7275 0,0433 6,7155 0,0510 0,0132 6,6054 1 1 1 0 0 1 0 0 1 1 0 1 1 0 1 1 1 1 1 1 0 1 1 0 0 0 1 1 0 ENDMONDO
EQU CCS TC TC TC TC CCS TC CAF MAS K TC CAF MAS K AD TS CS CS CS CS CS CS XCH MAS K TS CAF TS CS MAS K TS TC
* MONSAVE1 *+4 *+3 ENDOFJOB ENDOFJOB DSPLOCK MONBUSY LOW7 MONSAVE UPDATNN-1 MID7 MONSAVE MONREF CYR CYR CYR CYR CYR CYR CYR CYR LOW7 VERBREG MONBACK ENTRET BIT15_14 MONSAVE1 MPAC+2 TESTNN
; ; ; ; ;
called by EXEC if killer bit = 0, continue if killer bit = 0, continue in case TERMINATE came since last MONR E Q in case TERMINATE came since last MONR E Q
; NVSUB is busy
; place noun into NOUNREG and display it ; change monitor verb to display verb ; -DEC10, starting in bit5 ; shift right 7, was TS EDOP, CA EDOP in B I I
; COLOSSUS switche s to fixed/fixed memory and inserts PASTEVB here-; Probably, becaus e their assembler couldn't handle forward references. 15274 15275 15276 15277 6,1274 6,1275 6,1276 0 6,1277 0 75377 0 MONREF 04435 1 MONBACK 2,4713 0 MONBUSY 1,2723 0 DS CAD R TC TC TC EQU %75377 PASTEVB RELDSPON ENDOFJOB Q * ; -dec10, starting in bit8
; ************************** FIX
ORG BANKFF_1 INC L bankff_1.asm ; COLOSSUS pp. 351 ;================= ========================================================= ; DISPLAY ROUTINES (file:bankff_1.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 351. ;================= ========================================================= PASTEVB 04435 04436 04437 04440 04441 04442 04443 04444 04445 04446 04447 04450 4435 3 4436 7 4437 5 4440 4441 4442 4443 4444 1 0 0 0 0 2,4473 0 0,0511 0 0,0571 1 0,0000 2,4443 2,4444 2,4445 2,4447 0 0 1 0 1 EQU CAF MAS K TS CCS TC TC TC TC XCH TC CAF AD PASTEOPT 04451 04452 04453 04454 04455 04456 04457 04460 04461 04462 04463 4451 4452 4453 4454 4455 4456 4457 4460 4461 5 4 4 4 4 4 4 3 7 0,0020 0,0020 0,0020 0,0020 0,0020 0,0020 0,0020 0,0020 1,2101 0 1 1 1 1 1 1 0 1 EQU TS CS CS CS CS CS CS XCH MAS K TC CAD R * MID7 MONSAVE2 PASTE_TMP A *+2 *+2 *+2 *+3 PASTE_TMP PASTEOPT ZERO MONSAVE * CYR CYR CYR CYR CYR CYR CYR CYR LOW7 BANKCALL UPDATVB-1
; ; ; ; ;
; paste please verb for NVMONOPT ; was CA MONSAVE in BII ; paste monitor verb - paste option is 0
; place monitor verb or please verb into ; VERBREG and display it.
4462 0 4463
1,3565 1 14326 0
1,2050 0 0,0502 0 1,2050 0 0,0511 1 2,4565 0 2,4472 1 1,2723 0 ENDPASTE 37600 0 MID7 BANKFF_2
ORG BANK41_4 INC L bank41_4.asm ; COLOSSUS pp. 352 ;================= ========================================================= ; DISPLAY ROUTINES (file:bank41_4.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 352. ;================= ========================================================= ;----------------- --------------------------------------------------------; DSPFMEM -- DISPL AY FIXED MEMORY ; Used to display (in octal) any fixed register. It is used with NOUN = ; machine CADR to be specified. The FCADR of the desired location is then ; punched in. It h andles F/F (FCADR 4000-7777) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 352. ;----------------- --------------------------------------------------------DSPFMEM 15301 15302 15303 15304 15305 15306 15307 6,1301 3 6,1302 5 6,1303 3 6,1304 6 6,1305 0 6,1306 0 6,1307 0 2,4635 0 0,0466 0 1,2050 0 0,0506 1 1,3742 0 6,7310 1 1,2723 0 ENDSPF BANK41_5 EQU CAF TS CAF AD TC TC TC EQU * R1D1 DSPCOUNT ZERO NOUNCADR DATACALL DSPOCTWD ENDOFJOB *
; was CA NOUNCADR, TC SUPDACAL in Block I I ; original FCADR loaded still in NOUNCAD R ; call with FCADR in A
ORG BANK40_5 ; COLOSSUS pp. 353-355 INC L bank40_5.asm ;================= ========================================================= ; WORD DISPLAY ROU TINES (file:bank40_5.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 353-355. ;================= ========================================================= DSPSIGN 13031 13032 13033 13034 13035 13036 13037 13040 13041 13042 13043 13044 13045 5,1031 3 5,1032 5 5,1033 1 5,1034 0 5,1035 0 5,1036 5,1037 5,1040 5,1041 5,1042 5,1043 6 5 0 4 5 0 0,0001 0 0,0441 0 0,0130 1 5,7044 0 5,7044 0 1,2051 0,0130 5,6353 0,0131 0,0131 0,0441 1 0 1 0 1 0 EQU XCH TS CCS TC TC AD TS TC CS TS TC TC TC * Q DSPWDRET MPAC *+8 *+7 ONE MPAC M_ON MPAC+1 MPAC+1 DSPWDRET P_ON DSPWDRET
5,1044 0 5,1045 0
5,6332 0 0,0441 0
;----------------- --------------------------------------------------------; DSPRND ; Round up decimal fraction by 5 EXP -6. This was entirely coded in ; Block II instruc tions, so I translated it to the functional ; equivalent in Bl ock I code. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 353. ;----------------- --------------------------------------------------------DSPRND 13046 13047 5,1046 3 5,1047 6 5,7117 1 0,0131 1 EQU CAF AD * DECROUND MPAC+1
13050 13051 13052 13053 13054 13055 13056 13057 13060 13061
5,1050 5,1051 5,1052 5,1053 5,1054 5,1055 5,1056 5,1057 5,1060 5,1061
5 3 6 5 0 3 5 3 5 0
0,0131 1,2050 0,0130 0,0130 0,0001 5,7063 0,0131 5,7062 0,0130 0,0001
1 0 0 0 0 0 1 1 0 0 DPOSMAX
MPAC+1 ZERO MPAC MPAC Q DPOSMAX+1 MPAC+1 DPOSMAX MPAC Q * %37777 %34000
; skip on overflow ; otherwise, make interword carry=0 ; skip on overflow ; return ; number overflows, so set to max
13062 13063
5,1062 5,1063
37777 1 34000 0
;----------------- --------------------------------------------------------; DSPDECTWD -- DIS PLAY DECIMAL WORD ; Converts C(MPAC, MPAC+1) into a sign and 5 char decimal starting in loc ; specified in DSP COUNT. it rounds by 5 exp 6. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 353. ;----------------- --------------------------------------------------------DSPDECWD 13064 13065 13066 13067 13070 5,1064 3 5,1065 5 5,1066 0 5,1067 0 5,1070 3 0,0001 0 0,0412 0 5,7031 1 5,7046 1 1,2054 1 DSPDCWD1 13071 13072 13073 5,1071 5 5,1072 3 5,1073 0 0,0434 1 2,4700 1 2,4353 0 TRACE1 13074 13075 13076 13077 13100 13101 13102 13103 13104 5,1074 5,1075 5,1076 5,1077 5,1100 5,1101 5,1102 5,1103 5,1104 2 3 7 5 3 3 3 5 3 0,0130 1,3772 2,4664 0,0421 1,2050 0,0132 0,0131 0,0130 0,0466 1 0 0 0 0 1 1 0 0 TRACE1S 13105 13106 13107 13110 13111 13112 13113 13114 13115 13116 13117 5,1105 5,1106 5,1107 5,1110 5,1111 5,1112 5 1 5 0 1 0 0,0440 0,0000 0,0466 5,7161 0,0434 5,7071 1 0 0 0 0 0 EQU XCH TS TC TC CAF EQU TS CAF TC EQU IND EX CAF MAS K TS CAF XCH XCH TS XCH EQU TS CCS TS TC CCS TC CS TS TC DS DS * Q WDRET DSPSIGN DSPRND FOUR * WDCNT BINCON SHORTMP * MPAC RELTAB LOW5 CODE ZERO MPAC+2 MPAC+1 MPAC DSPCOUNT * COUNT A DSPCOUNT DSPIN WDCNT DSPDCWD1 VD1 DSPCOUNT WDRET %00000 %02476
;----------------- --------------------------------------------------------; DSPDECNR ; Converts C(MPAC, MPAC+1) into a sign and 5 char decimal starting in loc ; specified in DSP COUNT. It does not round. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 354. ;----------------- --------------------------------------------------------DSPDECNR 13120 13121 13122 13123 5,1120 5,1121 5,1122 5,1123 3 5 0 0 0,0001 0,0412 5,7031 5,7070 0 0 1 1 EQU XCH TS TC TC * Q WDRET DSPSIGN DSPDCWD1-1
;----------------- --------------------------------------------------------; DSPDC2NR ; Converts C(MPAC, MPAC+1) into a sign and 2 char decimal starting in loc ; specified by DSP COUNT. It does not round. ;
; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 354. ;----------------- --------------------------------------------------------DSPDC2NR 13124 13125 13126 13127 13130 5,1124 5,1125 5,1126 5,1127 5,1130 3 5 0 3 0 0,0001 0,0412 5,7031 1,2051 5,7071 0 0 1 1 0 EQU XCH TS TC CAF TC * Q WDRET DSPSIGN ONE DSPDCWD1
;----------------- --------------------------------------------------------; DSP2DEC ; Converts C(MPAC) and C(MPAC+1) into a sign and 10 char decimal starting ; in the loc speci fied in DSPCOUNT. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 354. ;----------------- --------------------------------------------------------DSP2DEC 0 0 0 0 0 1 1 1 1 0 0 END2DEC EQU XCH TS CAF TS CAF TC CAF TC TC CAF TC * Q WDRET ZERO CODE THREE _11DSPIN FOUR _11DSPIN DSPSIGN R2D1 DSPDCWD1
13131 13132 13133 13134 13135 13136 13137 13140 13141 13142 13143
5,1131 5,1132 5,1133 5,1134 5,1135 5,1136 5,1137 5,1140 5,1141 5,1142 5,1143
3 5 3 5 3 0 3 0 0 3 0
0,0001 0,0412 1,2050 0,0421 1,2053 5,7253 1,2054 5,7253 5,7031 2,4636 5,7071
;----------------- --------------------------------------------------------; DSPDECVN ; Displays C(A) up on entry as a 2 char decimal beginning in the ; loc specified in DSPCOUNT. ; C(A) should be i n form N x 2EXP-14. This is scaled to form N/100 before ; display conversi on. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 353. ;----------------- --------------------------------------------------------DSPDECVN 13144 13145 13146 13147 13150 13151 13152 13153 13154 13155 5,1144 2 5,1145 4 5,1146 3 5,1147 5 5,1150 5,1151 5,1152 5,1153 5,1154 5,1155 3 5 3 5 0 0,0000 1 5,7155 0 0,0003 1 0,0130 0 1,2050 0,0131 0,0001 0,0412 5,7127 0 1 0 0 1 EQU EXT END MP XCH TS CAF TS XCH TS TC DS EQU TC TC DS EQU * VNDSPCON LP MPAC ZERO MPAC+1 Q WDRET DSPDC2NR+3 %00244 * DSPDECVN POSTJUMP UPDAT1+2 * ; mult by .01 ; was LXCH MPAC in Block II ; take results from LP (mult by 2EXP14)
ORG BANK41_5 ; COLOSSUS pp. 355-356 INC L bank41_5.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bank41_5.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 355-356. ;================= ========================================================= ;----------------- --------------------------------------------------------; DSPOCTWD -- DISP LAY OCTAL WORD ; Displays C(A) up on entry as a 5 char octal starting in the DSP char ; specified in DSP COUNT. It stops after 5 char have been displayed. ; ; ; DSP2BIT -- DISPL AY 2 OCTAL CHARS ; Displays C(A) up on entry as a 2 char oct beginning in the DSP ; loc specified in DSPCOUNT by pre-cycling right C(A) and using ; the logic of the 5 char octal display. ;
; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 355/356. ;----------------- --------------------------------------------------------DSPOCTWD 15310 15311 15312 15313 15314 15315 15316 6,1310 5 6,1311 3 6,1312 5 6,1313 3 6,1314 6 6,1315 5 6,1316 3 0,0022 1 0,0001 0 0,0412 0 1,2063 0 0,0466 0 0,0466 0 1,2054 1 WDAGAIN 15317 15320 15321 15322 15323 15324 15325 15326 15327 15330 15331 15332 15333 15334 15335 15336 6,1317 6,1320 6,1321 6,1322 6,1323 6,1324 6,1325 6,1326 6,1327 6,1330 6,1331 6,1332 6,1333 6,1334 6,1335 6,1336 5 4 4 4 4 7 2 3 7 5 3 5 1 5 0 0,0434 0,0022 0,0022 0,0022 0,0000 1,2057 0,0000 1,3772 2,4664 0,0421 0,0466 0,0440 0,0000 0,0466 1,3653 13261 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 OCTBACK 15337 15340 6,1337 1 6,1340 0 0,0434 0 6,7317 0 DSPLW 15341 15342 15343 6,1341 4 6,1342 5 6,1343 0 2,4675 0 0,0466 0 0,0412 0 DSPMSK DSP2BIT 15344 15345 15346 15347 15350 15351 15352 15353 15354 15355 6,1344 6,1345 6,1346 6,1347 6,1350 6,1351 6,1352 6,1353 6,1354 6,1355 5 3 5 3 5 4 4 3 5 0 0,0020 0,0001 0,0412 1,2051 0,0434 0,0020 0,0020 0,0020 0,0022 6,7324 0 0 0 1 1 1 1 0 1 0 EQU TS XCH TS CAF AD TS CAF EQU TS CS CS CS CS MAS K IND EX CAF MAS K TS XCH TS CCS TS TC DS EQU CCS TC EQU CS TS TC EQU EQU TS XCH TS CAF TS CS CS XCH TS TC * CYL Q WDRET BIT14 DSPCOUNT DSPCOUNT FOUR * WDCNT CYL CYL CYL A DSPMSK A RELTAB LOW5 CODE DSPCOUNT COUNT A DSPCOUNT POSTJUMP DSPOCTIN * WDCNT WDAGAIN * VD1 DSPCOUNT WDRET SEVEN * CYR Q WDRET ONE WDCNT CYR CYR CYR CYL WDAGAIN+5
; must use the same return as DSP2BIT ; to blank signs ; was ADS DSPCOUNT in block II
BANK41_6
EQU
ORG BANK40_6 ; COLOSSUS pp. 356-358 INC L bank40_6.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bank40_6.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 356-358. ;================= ========================================================= ;----------------- --------------------------------------------------------; DSPIN -- DISPLAY RELAY CODE ; ; For DSPIN, place 0-25 oct into COUNT to select the character (same as DSPCOUN T ) , ; 5 bit relay code into CODE. Both are destroyed. If bit 14 of COUNT is 1, sign i s ; blanked with lef t char. ; For DSPIN11, pla ce 0,1 into CODE, 2 into COUNT, rel address of DSPTAB entry ; into DSREL. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 356. ;----------------- --------------------------------------------------------DSPIN 13161 13162 5,1161 3 5,1162 5 0,0001 0 0,0411 0 EQU XCH TS * Q DSEXIT
; cant use L for RETURN, since many of t h e ; routines calling DSPIN use L as RETURN
; Set DSREL to ind ex into DSPTAB; the index corresponds to the display characte r ; referenced by CO UNT (which is derived from DSPCOUNT) 13163 13164 13165 13166 13167 5,1163 5,1164 5,1165 5,1166 5,1167 3 7 5 3 5 2,4664 0,0440 0,0021 0,0021 0,0436 1 0 1 1 0 CAF MAS K TS XCH TS LOW5 COUNT SR SR DSREL
; divides by 2
; Check COUNT (der ived from DSPCOUNT) to find whether the character to be ; displayed is in the right (Bits 5-1) or left (Bits 10-6) bits of the ; DSPTAB word. 13170 13171 13172 13173 13174 5,1170 5,1171 5,1172 5,1173 5,1174 3 7 1 0 0 1,2100 0,0440 0,0000 5,7175 5,7205 1 0 0 0 1 CAF MAS K CCS TC TC BIT1 COUNT A *+2 DSPIN1-1
; Character to be displayed should be in the left bits (Bit 10-6), so ; shift it left in to bits 10-6. 13175 13176 13177 5,1175 3 5,1176 0 5,1177 5 0,0421 0 2,4656 0 0,0421 0 ; ; ; ; ; 13200 13201 13202 13203 13204 13205 5,1200 5,1201 5,1202 5,1203 5,1204 3 7 1 3 6 1,2063 0,0440 0,0000 1,2052 1,2051 0 0 0 1 1 XCH TC TS CODE SLEFT5 CODE
Set COUNT as an enumerated type; tells how to mask the new character into the relay w ord. 0 = mask new cha racter into right side of relayword (bits 5-1) 1 = mask into le ft side (bits 10-6) and leave old sign (bit 11) alone. 2 = mask into le ft side (bits 10-6) and blank sign bit (bit 11) CAF MAS K CCS CAF AD TS BIT14 COUNT A TWO ONE COUNT
5,1205 5
0,0440 1
; New display char acter in CODE has been bit-shifted into the correct (left ; or right) bit po sition. All other bits are zeroed. DSPIN1 13206 5,1206 2 0,0000 0 ; ; ; ; 13207 13210 13211 13212 13213 13214 5,1207 5,1210 5,1211 5,1212 5,1213 2 1 0 0 6 0,0436 0,0512 5,7213 5,7245 1,2051 1 0 0 0 1 EQU INH INT *
Get the existing display word from DSPTAB. Words that have already been displayed will b e positive; words yet to be displayed will be negative. Use CCS to load the absolute value of the display word. Since CCS decrements it, we need to a dd 1 to restore the value. IND EX CCS TC TC AD TS DSREL DSPTAB *+2 DSLV ONE DSMAG
; >0, old word already displayed ; +0, illegal DSPCOUNT (was TC CCSHOLE) ; <0, old word not displayed yet ; store the old relay word
5,1214 5
0,0437 1
; Now, mask off th e portion of the old relay word corresponding to the ; new character. S ubtract the new character from the old to see whether ; they are the sam e. 13215 13216 13217 13220 5,1215 5,1216 5,1217 5,1220 2 7 2 6 0,0440 5,7247 0,0000 0,0421 0 0 1 0 IND EX MAS K EXT END SU COUNT DSMSK CODE
; Old code same as new code? If so, we don't need to redisplay it. 13221 13222 13223 13224 13225 5,1221 5,1222 5,1223 5,1224 5,1225 1 0 0 0 0 0,0000 5,7226 5,7245 5,7226 5,7245 0 0 0 0 0 CCS TC TC TC TC ; New code is diff erent. DFRNT 13226 13227 13230 13231 5,1226 5,1227 5,1230 5,1231 2 4 7 6 0,0440 5,7247 0,0437 0,0421 0 0 0 0 EQU IND EX CS MAS K AD * COUNT DSMSK DSMAG CODE ; different ; mask with 77740, 76037, 75777, or 7403 7 A DFRNT DSLV DFRNT DSLV ; ; ; ; ; was BZF DSLV in Block II >0 +0, same, so return <0 -0, same, so return
; Store new DSPTAB word and get the old (previous) word. If the old word is ; negative, it had not been displayed yet, so NOUT (the count of undisplayed
; words) has alrea dy been incremented for this DSPTAB word. If the old word ; is positive, it has already been displayed, so we need to increment NOUT ; to tell DSPOUT t o display the new word. 13232 13233 13234 13235 13236 13237 13240 13241 13242 II) 13243 13244 13245 13246 5,1232 4 5,1233 2 5,1234 3 5,1235 5,1236 5,1237 5,1240 5,1241 1 0 0 0 0 0,0000 0 0,0436 1 0,0512 1 0,0000 5,7242 5,7241 5,7241 5,7245 0 1 1 1 0 CS IND EX XCH CCS TC TC TC TC XCH AD TS REL INT TC A DSREL DSPTAB A *+4 *+2 *+1 DSLV NOUT ONE NOUT ; ; ; ; ; was >0 +0, <0, -0, BZMF DSLV in Block II DSPTAB entry was DSPTAB entry was DSPTAB entry was -
DSEXIT
; return
DSMSK 13247 13250 13251 13252 5,1247 5,1250 5,1251 5,1252 00037 01740 02000 03740 0 0 0 1
EQU DS DS DS DS
; ; ; ;
; For 11DSPIN, put rel address of DSPTAB entry into A, 1 in BIT11 or 0 in ; BIT11 of CODE. I changed the name to _11DSPIN because my assembler doesn't ; like labels that start with a digit. _11DSPIN 13253 13254 13255 13256 13257 13260 5,1253 5,1254 5,1255 5,1256 5,1257 5,1260 5 3 5 3 5 0 0,0436 1,2052 0,0440 0,0001 0,0411 5,7206 0 1 1 0 0 1 DSPOCTIN 0 0 0 1 ENDSPOCT EQU TS CAF TS XCH TS TC EQU TC CAF TC DS * DSREL TWO COUNT Q DSEXIT DSPIN1 * DSPIN *+2 BANKJUMP OCTBACK
; ; ; ;
DSPALARM finds T C NVSUBEND in ENTRET for NVSUB initiated routines. Abort with 01501 . DSPALARM finds T C ENDOFJOB in ENTRET for keyboard initiated routines. do TC ENTRET. EQU CS TS EQU CS AD CCS TC TC TC TC CS AD CCS TC TC TC TC TC TC * VD1 DSPCOUNT * NVSBENDL ENTEXIT A *+4 *+2 *+2 CHARALRM+2 MONADR ENTEXIT A *+4 *+2 *+2 *+2 *+2 KILMONON * FALTON ENDOFJOB POODOO %01501 PASTEVB NVSUBEND ; ; ; ; ; was BZF CHARALRM+2 in Block II >0 +0 <0 -0
PREDSPAL 13265 13266 5,1265 4 5,1266 5 2,4675 0 0,0466 0 DSPALARM 13267 13270 13271 13272 13273 13274 13275 13276 13277 13300 13301 13302 13303 13304 13305 13306 5,1267 4 5,1270 6 5,1271 5,1272 5,1273 5,1274 5,1275 1 0 0 0 0 5,7314 1 0,0433 0 0,0000 5,7276 5,7275 5,7276 5,7311 0 0 0 0 0
; ; ; ; ;
5,1305 0 5,1306 0
EQU TC TC TC DS DS TC
BANK40_7
EQU
ORG BANKFF_2 ; COLOSSUS pp. 358 INC L bankff_2.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bankff_2.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 358. ;================= ========================================================= ;----------------- --------------------------------------------------------; ALMCYCLE ; Turns on check f ail light, redisplays the original verb that was executed, ; and recycles to execute the original verb/noun combination that was last ; executed. Used f or bad data during load verbs and by MCTBS. Also by MMCHANG ; if 2 numerical c hars were not punched in for MM code. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 358. ;----------------- --------------------------------------------------------ALMCYCLE 0 0 0 1 0 1 0 ENDALM BANKFF_3 EQU TC CS TS TC DS TC DS EQU * FALTON VERBSAVE REQRET BANKCALL UPDATVB-1 POSTJUMP ENTER *
0 4 5 0 0
; ; ; ; ;
turn on check fail light get original verb that was executed set for ENTPAS0 puts original verb into VERBREG and displays it in verb lights
ORG BANK41_6 ; COLOSSUS pp. 359-360 INC L bank41_6.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bank41_6.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 359-360. ;================= ========================================================= ;----------------- --------------------------------------------------------; MMCHANG -- MAJOR MODE CHANGE ; Uses noun displa y until ENTER; then it uses MODE display. It goes to ; MODROUT with the new MM code in A, but not displayed in MM lights. ; It demands 2 num erical characters be punched in for new MM code. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 359. ;----------------- --------------------------------------------------------EQU TC ; if this moves at all, ; MMADREF at ENTPA SHI 1,2074 0 CAF 0,0466 0 AD 6,7404 0 0,0000 6,7366 6,7365 6,7366 6,7367 0 0 0 0 1 CCS TC TC TC TC TC CAF XCH TS CAF TS TC DS CS TS CAF AD TC DS MODROUTR EQU MMCHANG * REQMM must change BIT5 DSPCOUNT A *+4 *+2 *+2 *+2 ALMCYCLE ZERO NOUNREG MPAC ND1 DSPCOUNT BANKCALL _2BLANK VD1 DSPCOUNT ZERO MPAC POSTJUMP MODROUTR V37 ; block num char in
15356
6,1356 0
15357 15360 15361 15362 15363 15364 15365 15366 15367 15370 15371 15372 15373 15374 15375 15376 15377 15400 15401 15402 15403
; OCT 20 = ND2 ; DSPCOUNT must = -ND2 ; ; ; ; ; was BZF *+2 in Block II >0 +0 <0 -0
6,1366 0 6,1367 3 6,1370 3 6,1371 5 6,1372 3 6,1373 5 6,1374 0 6,1375 6,1376 4 6,1377 5 6,1400 3 6,1401 6 6,1402 0 6,1403
2,4474 1 1,2050 0 0,0471 0 0,0130 0 2,4676 1 0,0466 0 1,3565 1 12540 0 2,4675 0 0,0466 0 1,2050 0,0130 1,3653 10000 0 0 1 0
REQMM 15404 15405 15406 15407 15410 15411 15412 15413 15414 15415 15416 15417 6,1404 6,1405 6,1406 6,1407 6,1410 6,1411 6,1412 6,1413 6,1414 6,1415 6,1416 6,1417 4 5 3 5 3 5 0 0 3 5 0 0,0001 0,0502 2,4676 0,0466 1,2050 0,0471 1,3565 12540 2,4760 1,2051 0,0467 0,0433 1 0 1 0 0 0 1 0 1 1 1 0
* Q REQRET ND1 DSPCOUNT ZERO NOUNREG BANKCALL _2BLANK FLASHON ONE DECBRNCH ENTEXIT
;----------------- --------------------------------------------------------; VBRQEXEC -- REQU EST EXECUTIVE ; ; Enters request t o EXEC for any address with any priority. It does ENDOFJOB ; after entering r equest. Display syst is released. It assumes NOUN 26 has been ; preloaded with: ; COMPONENT 1 -- p riority (bits 10-14), bit1=0 for NOVAC, bit1=1 for FINDVAC ; COMPONENT 2 -- j ob CADR (14 bit; was 12 bit in Block II) ; COMPONENT 3 -- n ot used (was BBCON in Block II) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 360. ;----------------- --------------------------------------------------------VBRQEXEC 15420 15421 15422 15423 15424 6,1420 6,1421 6,1422 6,1423 6,1424 3 7 1 0 3 1,2100 0,0534 0,0000 6,7444 2,4667 1 1 0 1 1 ; ; ; ; ; EQU CAF MAS K CCS TC CAF * BIT1 DSPTEM1 A SETVAC TCNOVAC
sets up to call NOVAC or FINDVAC thru MPAC as follows: MPAC = TC NOVAC MPAC+1 = job CADR MPAC+2 = TC ENDOFJOB MPAC+3 = temp store for job PRIO EQU TS CS MAS K TS EQU TC CAF AD TS CAF AD TS CAF AD INH INT TC * MPAC BIT1 DSPTEM1 MPAC+3 * RELDSP ZERO ENDINST MPAC+2 ZERO DSPTEM1+1 MPAC+1 ZERO MPAC+3 MPAC * TCFINDVAC REQEX1
REQEX1 15425 15426 15427 15430 6,1425 6,1426 6,1427 6,1430 5 4 7 5 0,0130 1,2100 0,0534 0,0133 0 0 1 0 REQUESTC 15431 15432 15433 15434 15435 15436 15437 15440 15441 15442 15443 6,1431 6,1432 6,1433 6,1434 0 3 6 5 2,5003 1,2050 2,4553 0,0132 1 0 0 1
; was CA ENDINST in Block II ; TC ENDOFJOB into MPAC+2 (was +3) ; set BBCON for Block II dropped ; job adres into MPAC+1
15444 15445
6,1444 3 6,1445 0
2,4671 0 6,7425 0
EQU CAF TC
;----------------- --------------------------------------------------------; VBRQWAIT -- REQU EST WAITLIST ; ; Enters request t o WAITLIST for any address with any delay. It does ENDOFJOB ; after entering r equest. Display syst is released. It assumes NOUN 26 has been ; preloaded with: ; COMPONENT 1 -- d elay (low bits) ; COMPONENT 2 -- t ask CADR (14 bit; was 12 bit in Block II) ; COMPONENT 3 -- n ot used (was BBCON in Block II) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 360. ;----------------- --------------------------------------------------------VBRQWAIT 15446 15447 6,1446 3 6,1447 5 2,4670 1 0,0130 0 EQU CAF TS * TCWAIT MPAC
CAF AD TC
; REQUESTC will pu t task address in MPAC+1, TC ENDOFJOB in MPAC+2. ; It will take the time delay out of MPAC+3 and leave it in A, INHINT ; and TC MPAC. BANK41_7 EQU *
ORG BANK40_7 ; COLOSSUS pp. 360-362 INC L bank40_7.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bank40_7.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 360-362. ;================= ========================================================= ;----------------- --------------------------------------------------------; VBPROC -- PROCEE D WITHOUT DATA ; VBTERM -- TERMIN ATE ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 360. ;----------------- --------------------------------------------------------VBPROC 13315 13316 13317 13320 13321 13322 5,1315 5,1316 5,1317 5,1320 5,1321 5,1322 3 5 0 0 0 0 1,2051 0,0503 2,4536 2,5003 2,4770 5,7413 1 1 0 1 0 0 VBTERM 13323 13324 5,1323 4 5,1324 0 1,2051 0 5,7316 1 EQU CAF TS TC TC TC TC EQU CS TC * ONE LOADSTAT KILMONON RELDSP FLASHOFF RECALTST * ONE VBPROC+1
;----------------- --------------------------------------------------------; VBRESEQ ; Wakes ENDIDLE at same line as final enter of load (L+3). Main use is ; intended as resp onse to internally initiated flashing displays in ENDIDLE. ; Should not be us ed with load verbs, please perform, or please mark verbs ; because they alr eady use L+3 in another context. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 361. ;----------------- --------------------------------------------------------VBRESEQ 13325 13326 5,1325 4 5,1326 0 1,2050 1 5,7316 1 EQU CS TC * ZERO VBPROC+1
; flash is turned off by proceed without data, terminate, ; resequence, end of load.
;----------------- --------------------------------------------------------; VBRELDSP ; This routine alw ays turns off the UPACT light and always clears ; DSPLOCK. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 362. ;----------------- --------------------------------------------------------VBRELDSP EQU *
; some code here t o turn off the UPACT light is omitted 13327 13330 13331 13332 13333 13334 13335 13336 13337 13340 13341 5,1327 5,1330 5,1331 5,1332 5,1333 5,1334 5,1335 5,1336 5,1337 5,1340 5,1341 1 3 7 1 0 0 1 0 0 0 0,0412 1,2063 0,0510 0,0000 5,7342 2,5003 0,0531 5,7340 1,2723 1,3653 05067 1 0 1 0 0 1 TSTLTS4 1 1 0 1 0 UNSUSPEN 13342 13343 5,1342 3 5,1343 5 1,2050 0 0,0501 0 CCS CAF MAS K CCS TC TC CCS TC TC TC CAD R EQU CAF TS _2122REG BIT14 MONSAVE1 A UNSUSPEN RELDSP CADRSTOR *+2 ENDOFJOB POSTJUMP PINBRNCH * ZERO DSPLOCK ; old DSPLOCK ; external monitor bit (EMB) ; old DSPLOCK and EMB both 1, unsuspend ; not unsuspending external monitor, ; release display system and ; do reestablish if CADRSTOR is full
1 0 0 0
1 0 0 0
CCS TC TC TC
; turn key release light off if both ; CADRSTOR and DSPLIST are empty
BANK40_8
EQU
ORG BANKFF_3 ; COLOSSUS pp. 363-364 INC L bankff_3.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bankff_3.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 363-364. ;================= ========================================================= ; COLOSSUS p. 364 - comments are taken from the Block I flow charts with some ; additional annot ations by me.
NVSUB 04503 04504 04505 4503 5 4504 3 4505 5 0,0565 1 1,2050 0 0,0564 0
EQU TS CAF TS
; more gymnastics for Block II conversio n ; was LXCH 7 in Block II ; zero NVMONOPT options
; save C(A). C(A) should be holding the noun/verb code; C(L) should ; be holding NVMON OPT options. In this Block I version, the NVMONOPT ; options should b e placed in NVSUB_L before calling NVMONOPT. 04506 4506 3 0,0565 1 NVMONOPT 04507 4507 5 0,0420 1 XCH EQU TS NVSUB_A * NVTEMP
; Test DSPLOCK (+N Z=busy; +0=display system available) ; Display is block ed by DSPLOCK=1 or external monitor bit set (bit 14) 04510 04511 04512 04513 04514 4510 4511 4512 4513 4514 3 7 6 1 0 1,2063 0,0510 0,0501 0,0000 0,0001 0 1 0 0 0 CAF MAS K AD CCS TC BIT14 MONSAVE1 DSPLOCK A Q
; Store calling li ne +2 in NVQTEM 04515 04516 04517 4515 3 4516 6 4517 5 1,2051 1 0,0001 0 NVSBCOM 0,0526 0 CAF AD TS ONE Q NVQTEM ; dsp syst available ; 2+calling loc into NVQTEM
; Force bit 15 of MONSAVE to 1, turn off bit 14. 04520 04521 04522 04523 4520 3 4521 3 4522 5 4523 0 0,0564 0 0,0511 1 0,0564 0 2,4536 0 XCH XCH TS TC NVSUB_L MONSAVE2 NVSUB_L KILMONON ; was LXCH MONSAVE2 in Block II ; store NVMONOPT options ; replaces LXCH by working through A ins t e a d ; turn on kill monitor bit
; Store calling ba nk in NVBNKTEM ; ** this was chan ged quite a bit from Block II ** NVSUBCOM 04524 04525 04526 04527 04530 04531 4524 3 4525 6 4526 5 4527 0 4530 4531 1,2050 0 0,0015 0 0,0527 1 1,3624 1 14000 1 15505 0 NVSRRBNK EQU CAF AD TS TC CAD R CAD R * ZERO BANK NVBNKTEM MYBANKCALL NVSUBR NVSUB1 ; go to NVSUB1 thru standard loc
; Restore calling bank and TC NVQTEM ; ** this was chan ged quite a bit from Block II ** NVSUBEND 04532 04533 04534 04535 4532 4533 4534 4535 3 6 5 0 1,2050 0,0527 0,0015 0,0526 0 1 0 0 BANKFF_4 EQU CAF AD TS TC EQU * ZERO NVBNKTEM BANK NVQTEM *
; DISPLAY ROUTINES (file:bank41_7.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 365-366. ;================= =========================================================
; BLANKDSP blanks display according to option number in NVTEMP as follows: ; -4 full blank, - 3 leave mode, -2 leave mode and verb, -1 blank R-S only BLANKDSP 15453 15454 15455 15456 15457 15460 15461 15462 15463 15464 15465 15466 15467 15470 15471 15472 15473 15474 15475 15476 15477 15500 6,1453 6,1454 6,1455 6,1456 6,1457 6,1460 6 2 5 4 2 3 1,2057 0,0000 0,0421 1,2065 0,0421 0,0512 1 0 0 1 1 1 EQU AD INH INT TS CS IND EX XCH CCS TC TC CCS TC REL INT IND EX TC TC TS TS TS CS TS TC TC INCR_NOUT 15501 15502 15503 15504 6,1501 6,1502 6,1503 6,1504 3 6 5 0 0,0505 1,2051 0,0505 6,7463 1 1 1 1 NVSUB1 15505 15506 15507 15510 15511 15512 15513 15514 15515 15516 15517 15520 15521 15522 15523 15524 15525 15526 15527 15530 15531 15532 6,1505 3 6,1506 5 6,1507 6,1510 6,1511 6,1512 6,1513 1 0 0 0 0 6,7542 0 0,0433 0 0,0420 6,7514 6,6341 6,7453 6,6341 0 0 1 1 1 EQU XCH AD TS TC EQU CAF TS CCS TC TC TC TC * SEVEN CODE BIT12 CODE DSPTAB A INCR_NOUT *+1 CODE BLANKDSP+2 NVTEMP *+5 *+1 VERBREG NOUNREG CLPASS VD1 DSPCOUNT FLASHOFF ENTSET-2 * NOUT ONE NOUT INCR_NOUT_RET * ENTSET ENTRET NVTEMP *+4 GODSPALM BLANKDSP GODSPALM ; protect against invisible flash ; zeroes REQRET
6,1461 1 6,1462 0 6,1463 0 6,1464 6,1465 6,1466 6,1467 6,1470 6,1471 6,1472 6,1473 6,1474 1 0 2 2 0 0 5 5 5
0,0000 0 6,7501 1 6,7464 0 INCR_NOUT_RET 0,0421 6,7455 0,0000 0,0420 6,7475 6,7472 0,0470 0,0471 0,0504 1 1 1 0 0 1 1 0 0
; ; ; ;
was INCR NOUT in Block II have to make it a separate routine because it was nested inside a CCS.
; in bank ; set return to NVSUBEND ; what now ; normal NVSUB call (execute VN or paste ) ; blank display as specified
6,1514 3 6,1515 7 6,1516 5 6,1517 3 6,1520 6 6,1521 6,1522 6,1523 6,1524 6,1525 6,1526 6,1527 6,1530 6,1531 6,1532 5 4 4 4 4 4 4 3 7 5
1,2101 0 0,0420 0 0,0133 0 ; 1,2050 0 0,0420 1 0,0020 0,0020 0,0020 0,0020 0,0020 0,0020 0,0020 0,0020 1,2101 0,0134 0 1 1 1 1 1 1 0 1 1 ;
CAF LOW7 MAS K NVTEMP TS MPAC+3 u ses MPAC, +1, +2 CAF ZERO AD NVTEMP TS CYR CS CYR CS CYR CS CYR CS CYR CS CYR CS CYR XCH CYR MAS K LOW7 TS MPAC+4 u ses MPAC, +1, +2 CCS TC CAF AD TC CAF TS TC MPAC+3 NVSUB2 ZERO MPAC+4 UPDATVB-1 ZERO REQRET NVSUBEND
; test noun (+NZ or +0) ; if noun not +0, DC on ; was CA MPAC+4 in Block II ; if noun = +0, display verb then return ; zero REQRET so that pasted verbs can ; be executed by operator
15543 15544 15545 15546 15547 15550 15551 15552 15553 15554 15555 15556 15557 15560 15561 15562 15563 15564 15565 15566 15567 15570 15571
MPAC+4 *+5 ZERO MPAC+3 UPDATNN-1 NVSUBEND ZERO MPAC+2 MPAC+5 ZERO MPAC+4 UPDATVB-1 ZERO MPAC+3 UPDATNN-1 ZERO LOADSTAT CLPASS REQRET ZERO MPAC+5 MPAC+2 ENTPAS0
; test verb (+NZ or +0) ; if verb not +0, go on ; was CA MPAC+3 in Block II ; if verb = +0, display noun, then retur n
6,1551 3 6,1552 6 6,1553 5 6,1554 3 6,1555 6 6,1556 0 6,1557 3 6,1560 6 6,1561 0 6,1562 6,1563 6,1564 6,1565 3 5 5 5
1,2050 0 0,0132 1 0,0135 0 1,2050 0 0,0134 1 6,6326 0 1,2050 0 0,0133 0 6,6306 1 1,2050 0,0503 0,0504 0,0502 0 1 0 0
; was CA MPAC+2 in Block II ; temp for mach CADR to be spec, (DSPDEC V N ; uses MPAC, +1, +2 ; was CA MPAC+4 in Block II ; if both noun and verb not +0, display ; was CA MPAC+3 in Block II ; both and go to ENTPAS0
; set for waiting for data condition ; set request for pass 0 ; was CA MPAC+5 in Block II ; restores mach CADR to be spec to MPAC+ 2 ; for use in INTMCTBS (in ENTPAS0)
; if internal mach CADR to be specified, MPAC+2 will be placed into ; NOUNCADR in ENTP AS0 (INTMCTBS)
BANK41_8
EQU
ORG BANKFF_4 ; COLOSSUS pp. 366-368 INC L bankff_4.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bankff_4.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 366-368. ;================= =========================================================
KILMONON 04536 04537 04540 4536 3 4537 5 4540 0 1,2062 1 0,0510 0 0,0001 0
EQU CAF TS TC
* BIT15 MONSAVE1 Q
; ; ; ;
force bit 15 of MONSAVE1 to 1. this is the kill monitor bit. turn off bit 14, the external monitor bit.
; COLOSSUS p. 367 ENDIDLE 04541 04542 04543 04544 04545 04546 04547 04550 04551 04552 04553 4541 3 4542 5 4543 0 4544 0 4545 4546 4547 4550 4551 4552 3 6 7 6 5 0 0,0001 0 0,0566 1 2,4554 1 2,4560 0 1,2050 0,0566 2,4674 0,0015 0,0531 1,2725 0 1 1 0 0 0 EQU XCH TS TC TC CAF AD MAS K AD TS TC TC EQU CCS TC TC TC EQU CCS TC TC TC DS * Q ENDIDLE_L ISCADR_P0 ISLIST_P0 ZERO ENDIDLE_L LOW10 BANK CADRSTOR JOBSLEEP ENDOFJOB * CADRSTOR DSPABORT Q DSPABORT * DSPLIST DSPABORT Q POODOO %1206
; was LXCH Q in Block II ; return address into L ; abort if CADRSTOR not= +0 ; abort if DSPLIST not= +0 ; ; ; ; was CA L in Block II don't set DSPLOCK to 1 so can use ENDIDLE with NVSUB initiated monitor. same strategy for CADR as MAKECADR
4553 0
1 0 0 0
1 0 0 0 ISLIST_P0 1 0 0 1 DSPABORT 1
1 0 0 0
; ; ; ; ;
BLANKSUB blanks any combination of R1, R2, R3. Call with blanking code in A. BIT1=1 blanks R1 , BIT2=1 blanks R2, BIT3=1 blanks R3. Any combination of thes e three bits is ac cepted. DSPCOUNT is rest ored to the state it was in before BLANKSUB was executed. EQU MAS K TS CAF MAS K AD CCS TC XCH AD TS CCS TC TC * SEVEN NVTEMP BIT14 MONSAVE1 DSPLOCK A Q Q ONE BLANKSUB_Q NVTEMP *+2 BLANKSUB_Q
BLANKSUB 04565 04566 04567 04570 04571 04572 04573 04574 04575 04576 04577 04600 04601 4565 4566 4567 4570 4571 4572 4573 4574 4575 4576 7 5 3 7 6 1 0 3 6 5 1,2057 0,0420 1,2063 0,0510 0,0501 0,0000 0,0001 0,0001 1,2051 0,0561 0 1 0 1 0 0 0 0 1 0
; ; ; ;
syst blocked. Return to 1+calling l o c INCR Q in Block II return for 2+calling location TC Q in Block II
; ; ; ; ; ; ; 04602 04603 04604 04605 04606 04607 04610 04611 04612 4602 3 4603 6 4604 3 4605 3 4606 6 4607 3 4610 3 4611 0 4612 1,2050 0 0,0561 0 0,0426 1 1,2050 0 0,0015 0 0,0425 1
the return addre ss+2 is now in BLANKSUB_Q. We need to call BLNKSUB1 in in "bank 40", so we'll have to save the bank register so that we can return to the ad dress in BLANKSUB_Q. The block II code had a bunch of tricky stuff inv olving the both bank bits and superbit. Block I doesn't need to worry ab out that, so we can substitute this simplified code. As in the Block II code, the return bank gets saved to BUF and the return address+2 gets s aved to BUF+1. CAF AD XCH CAF AD XCH CAF TC CAD R ZERO BLANKSUB_Q BUF+1 ZERO BANK BUF BSUB1ADDR DXCHJUMP BLNKSUB1
; this is my attem pt to implement the return from BLNKSUB1. In BII, it executes ; as part of the B LNKSUB1 routine: ; DXCH BUF ; TC SUPDXCHZ+ 1 ; to jump from the BLNKSUB1 bank to the calling bank. BS_SUPDXCHZ 04613 04614 04615 4613 3 4614 3 4615 0 0,0425 1 0,0015 0 0,0426 1 BANKFF_5 EQU XCH XCH TC EQU * BUF BANK BUF+1 *
; restore the calling bank bits ; return to calling loc+2 (set in BLANKS U B )
ORG BANK04_2 ; COLOSSUS pp. 369 INC L bank04_2.asm ;================= ========================================================= ; DSPMM - DISPLAY MODREG (file: bank04_2.asm) ; ; DSPMM does not d isplay MODREG directly. It puts EXEC request with ; prio=CHARPRIO fo r DSPMMJB and returns to caller. ; ; If MODREG contai ns -0, DSPMMJB blanks the MODE lights. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 369. ;================= =========================================================
3 5 2 3 0 2 0
DSPMM 0 0 0 0 1 1 1 0 ENDSPMM
BANK04_3
EQU
; DISPLAY ROUTINES (file:bank40_8.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 369-371. ;================= ========================================================= BLNKSUB1 13350 13351 13352 13353 13354 13355 13356 13357 13360 13361 13362 13363 13364 13365 13366 13367 13370 13371 13372 5,1350 3 5,1351 6 5,1352 5 5,1353 5,1354 5,1355 5,1356 5,1357 5,1360 5,1361 5,1362 5,1363 5,1364 5,1365 5,1366 3 0 3 0 3 0 3 0 3 0 3 0 1,2050 0 0,0466 0 0,0427 0 1,2100 5,7373 2,4635 5,6472 1,2077 5,7373 2,4636 5,6472 1,2076 5,7373 2,4637 5,6472 1 1 0 0 0 1 0 0 1 1 1 0 EQU CAF AD TS CAF TC CAF TC CAF TC CAF TC CAF TC CAF TC CAF AD TS TC * ZERO DSPCOUNT BUF+2 BIT1 TESTBIT R1D1 _5BLANK-1 BIT2 TESTBIT R2D1 _5BLANK-1 BIT3 TESTBIT R3D1 _5BLANK-1 ZERO BUF+2 DSPCOUNT BS_SUPDXCHZ
; was CA BUF+2 in Block II ; restore DSPCOUNT to state it had ; before BLANKSUB ; was DXCH BUF, TC SUPDXCHZ+1 in BII
TESTBIT 13373 13374 13375 13376 13377 5,1373 5,1374 5,1375 5,1376 5,1377 7 1 0 2 0 0,0420 0,0000 0,0001 0,0001 0,0002 0 0 0 1 0 DSPMMJB 13400 13401 13402 13403 13404 13405 13406 13407 13410 13411 13412 5,1400 5,1401 5,1402 5,1403 5,1404 5,1405 5,1406 5,1407 5,1410 5,1411 5,1412 3 3 5 1 6 0 0 0 3 5 0 2,4677 0,0466 0,0435 0,0500 1,2051 5,7144 5,7410 5,6540 0,0435 0,0466 1,2723 0 0 0 0 1 1 0 0 0 0 0
* NVTEMP A Q Q 2 * MD1 DSPCOUNT DSPMMTEM MODREG ONE DSPDECVN *+2 _2BLANK DSPMMTEM DSPCOUNT ENDOFJOB
; NVTEMP contains blanking code ; if current bit = 1, return to L+1 ; if current bit = 0, return to L+3
; ; ; ;
if MODREG is + or +0, display MODREG if MODREG is -NZ, do nothing if MODREG is -0, blank MM restore DSPCOUNT
;----------------- --------------------------------------------------------; RECALTST ; Entered directly after data is loaded (or resequence verb is executed), ; terminate verb i s executed, or proceed without data verb is executed. ; It wakes up job that did TC ENDIDLE. ; If CADRSTOR not = +0, it puts +0 into DSPLOCK, and turns off KEY RLSE ; light if DSPLIST is empty (leaves KEY RLSE light alone if not empty). ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 370. ;----------------- --------------------------------------------------------RECALTST 13413 13414 13415 5,1413 1 5,1414 0 5,1415 0 0,0531 1 5,7416 0 1,2723 0 RECAL1 13416 13417 13420 13421 13422 13423 13424 13425 13426 5,1416 5,1417 5,1420 5,1421 5,1422 5,1423 5,1424 5,1425 5,1426 3 3 2 0 1 0 0 0 3 1,2050 0,0531 0,0000 1,3003 0,0503 5,7450 1,2723 5,7446 1,2052 0 0 0 1 0 1 0 0 1 RECAL2 13427 13430 13431 13432 5,1427 5,1430 5,1431 5,1432 2 6 2 5 0,0300 0,0140 0,0300 0,0140 0 1 0 1 EQU CCS TC TC EQU CAF XCH INH INT TC CCS TC TC TC CAF EQU IND EX AD IND EX TS * CADRSTOR RECAL1 ENDOFJOB * ZERO CADRSTOR JOBWAKE LOADSTAT DOPROC ENDOFJOB DOTERM TWO * LOCCTR LOC LOCCTR LOC
; ; ; ;
+ proceed without data pathological case exit - terminate -0, data in or resequence
3 6 2 5 3 6 2 5
0 0 0 1 0 1 0 0
CAF AD IND EX TS CAF AD IND EX TS REL INT RECAL3 EQU TC TC EQU CAF TC EQU CAF TC EQU
; ; ; ;
save verb in MPAC, noun in MPAC+1 at time of response to ENDIDLE for possible later testing by job that has been waked up
5,1443 2
0,0000 1
13444 13445
5,1444 0 5,1445 0
13446 13447
5,1446 3 5,1447 0
13450 13451
5,1450 3 5,1451 0
ORG BANKFF_5 ; COLOSSUS pp. 372-376 INC L bankff_5.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bankff_5.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 372-376. ;================= ========================================================= ;----------------- --------------------------------------------------------; MISCELLANEOUS SE RVICE ROUTINES IN FIXED-FIXED ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 372. ;----------------- --------------------------------------------------------; SETNCADR ; Store the erasea ble memory address from A into NOUNCADR and NOUNADD. ; (changed from Bl ock II, because there is no bank addressing for block I) ; ; ; ; ; ; ; SETNADD Get the eraseabl e memory address from NOUNCADR and store it into NOUNADD. (changed from Bl ock II, because there is no bank addressing for block I) SETEBANK E CADR arrives i n A. E ADRES is "derived" and left in A. (changed from Bl ock II, because there is no bank addressing for block I) EQU XCH TS XCH TS MAS K TS TC SETNADD 04625 04626 04627 04630 04631 04632 4625 3 4626 5 4627 3 4630 3 4631 6 4632 0 0,0001 0 0,0555 1 0,0001 0 1,2050 0 0,0506 1 2,4622 0 SETEBANK 04633 04634 4633 7 4634 0 2,4674 1 0,0001 0 EQU XCH TS XCH CAF AD TC EQU MAS K TC * Q SETNCADR_Q Q NOUNCADR LOW10 NOUNADD SETNCADR_Q * Q SETNCADR_Q Q ZERO NOUNCADR SETNCADR+4 * LOW10 Q
SETNCADR 04616 04617 04620 04621 04622 04623 04624 4616 3 4617 5 4620 3 4621 4622 4623 4624 5 7 5 0 0,0001 0 0,0555 1 0,0001 0 0,0506 2,4674 0,0442 0,0555 1 1 0 1
; save return address ; restore A ; store ECADR ; put E ADRES into NOUNADD
; get NOUNCADR
DS DS DS EQU TS CS CS
; these 3 constants form a packed table ; don't separate ; must stay here
4 4 3 0
1 1 0 0 LEFT5
CS CS XCH TC EQU TS CS CS CS CS XCH TC EQU DOU BLE DOU BLE DOU BLE DOU BLE DOU BLE TC DS DS DS TC TC TC TC DS DS EQU DS DS DS DS DS DS
5 4 4 4 4 3 0
1 0 0 0 0 1 0 SLEFT5
04656 04657 04660 04661 04662 04663 04664 04665 04666 04667 04670 04671
6 6 6 6 6 0
1 1 1 1 1 0
Q %00037 %01740 %76000 NOVAC WAITLIST TASKOVER FINDVAC %30000 %3777 LOW11 %377 %01777 %23 %21 %25 10 ; EXEC priority of CHARIN ; these 3 constants form a packed table ; don't separate ; must stay here
00037 0 LOW5 01740 0 MID5 76000 0 HI5 1,3162 1 TCNOVAC 1,2232 0 TCWAIT ;TCTSKOVR 1,3161 1 TCFINDVAC ;CHRPRIO 03777 0 LOW11 B12M1 00377 1 LOW8 01777 1 LOW10 00023 0 VD1 00021 1 ND1 00025 0 MD1 00012 1 BINCON
; these 3 constants form a packed table ; don't separate ; must stay here
;**************** TURN ON/OFF OPERATOR ERROR LIGHT ******* p. 373 DSALMOUT FALTON 04701 04702 04703 04704 04705 4701 4702 4703 4704 4705 4 7 4 5 0 0,0011 2,4712 0,0000 0,0011 0,0001 0 0 0 1 0 FALTOF 04706 04707 04710 04711 04712 4706 4707 4710 4711 4712 4 7 5 0 1,2072 0,0011 0,0011 0,0001 1 0 1 0 EQU EQU CS MAS K COM TS TC EQU CS MAS K TS TC DS OUT1 * DSALMOUT FALTOR DSALMOUT Q * BIT7 DSALMOUT DSALMOUT Q %77677 ; channel 11 in Block II is OUT1 in Bloc k I
; inclusive OR bit 7 with 1 using ; Demorgan's theorem ; was bit 7 of channel 11 in Block II
77677 1 FALTOR
;**************** TURN ON KEY RELEASE LIGHT ******* p. 373 RELDSPON 04713 04714 04715 04716 04717 04720 4713 4714 4715 4716 4717 4720 4 7 4 5 0 0,0011 2,4720 0,0000 0,0011 0,0001 0 1 0 1 0 EQU CS MAS K COM TS TC DS * DSALMOUT RELDSPOR DSALMOUT Q %77757
; inclusive OR bit 5 with 1 using ; Demorgan's theorem ; was bit 5 of channel 11 in Block II
77757 1 RELDSPOR
; TPSL1 ; Shift triple wor d MPAC, MPAC+1, MPAC+2 left 1 bit TPSL1 04721 04722 04723 04724 04725 04726 04727 4721 4722 4723 4724 3 6 6 5 1,2050 0,0132 0,0132 0,0132 0 1 1 1 EQU CAF AD AD TS CAF AD AD * ZERO MPAC+2 MPAC+2 MPAC+2 ZERO MPAC+1 MPAC+1
TS CAF AD AD TS TC TS TC
; ; ; ; ; ; ;
PRSHRTMP if MPAC, +1 are each +NZ or +0 and C(A)=-0, SHORTMP wrongly gives +0. if MPAC, +1 are each -NZ or -0 and C(A)=+0, SHORTMP wrongly gives +0. PRSHRTMP fixes f irst case only, by merely testing C(A) and if it = -0, setting result t o -0. (Do not use PRSH RTMP unless MPAC, +1 are each +NZ or +0, as they are when they contai n the SF constants). EQU TS XCH TS CCS TC TC TC CS TS TS TS TC * MPTEMP Q PRSHRTMP_Q MPTEMP DOSHRTMP DOSHRTMP DOSHRTMP ZERO MPAC MPAC+1 MPAC+2 PRSHRTMP_Q * ZERO MPTEMP SHORTMP PRSHRTMP_Q
PRSHRTMP 04740 04741 04742 04743 04744 04745 04746 04747 04750 04751 04752 04753 4740 5 4741 3 4742 5 4743 4744 4745 4746 4747 4750 4751 4752 4753 1 0 0 0 4 5 5 5 0 0,0432 1 0,0001 0 0,0600 1 0,0432 2,4754 2,4754 2,4754 1,2050 0,0130 0,0131 0,0132 0,0600 0 0 0 0 1 0 1 1 1 DOSHRTMP 04754 04755 04756 04757 4754 4755 4756 4757 3 6 0 0 1,2050 0,0432 2,4353 0,0600 0 1 0 1
; ; ; ;
+, do regular SHORTMP +0, do regular SHORTMP -, do regular SHORTMP -0, force result to -0 and return
EQU CAF AD TC TC
;**************** TURN ON/OFF V/N FLASH ******* p. 374 ; this is handled by setting a bit in channel 11 in Block II. ; In Block I, it h as to be set through the display table, so I ; borrowed this me thod from SGNCOM (the DSKY +/- sign routine) ; Uses MYBANKCALL because BANKCALL is not reentrant and I dont ; understand its u sage in COLOSSUS well enough to be certain ; that FLASHON/FLA SHOFF isn't being called somewhere through ; BANKCALL. FLASHON 04760 04761 04762 04763 04764 04765 04766 04767 4760 3 4761 5 4762 4763 4764 4765 4766 3 5 3 0 0,0001 0 0,0570 0 1,2066 0,0421 2,5000 1,3624 13253 0 0 1 1 1 EQU XCH TS CAF TS CAF TC CAD R TC FLASHOFF 04770 04771 04772 04773 04774 04775 04776 04777 05000 4770 3 4771 5 4772 4773 4774 4775 4776 3 5 3 0 0,0001 0 0,0570 0 1,2050 0,0421 2,5000 1,3624 13253 0 0 1 1 1 EQU XCH TS CAF TS CAF TC CAD R TC DS * Q FLASHRET BIT11 CODE FLSHTAB MYBANKCALL _11DSPIN FLASHRET * Q FLASHRET ZERO CODE FLSHTAB MYBANKCALL _11DSPIN FLASHRET %11 ; V/N flash
4767 0
0,0570 0
4777 0 5000
EQU TC CAD R
* POSTJUMP NVSUBSY1
BANKFF_5a
EQU
ORG BANK40_8a ; COLOSSUS pp. 376 INC L bank40_8a.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bank40_8a.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 376. ;================= ========================================================= ;----------------- --------------------------------------------------------; MISCELLANEOUS SE RVICE ROUTINES IN FIXED-FIXED ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 376. ;----------------- --------------------------------------------------------NVSUBSY1 0 1 0 0 0 0 0 0 ENDNVBSY BANK40_9 EQU TS TC TC TC CAF AD TS TC EQU * NBSUBSY1_L ISCADR_P0 ISLIST_P0 RELDSPON ZERO NBSUBSY1_L DSPLIST JOBSLEEP *
5 0 0 0 3 6 5 0
; save CADR ; abort if CADRSTOR not = +0 ; abort if DSPLIST not = +0 ; was CA L in Block II
ORG BANKFF_5a ; COLOSSUS pp. 376-378 INC L bankff_5a.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bankff_5a.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 376-378. ;================= ========================================================= ;----------------- --------------------------------------------------------; MISCELLANEOUS SE RVICE ROUTINES IN FIXED-FIXED ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 376. ;----------------- --------------------------------------------------------; RELDSP ; used by VBPROC, VBTERM, VBRQEXEC, VBRQWAIT, VBRELDSP, EXTENDED VERB ; DISPATCHER, VBRE SEQ, and RECALTST. ; RELDSP1 ; used by monitor set up, VBRELDSP RELDSP 05003 05004 05005 05006 05007 05010 05011 05012 05013 05014 05015 05016 5003 5004 5005 5006 5007 5010 5011 5012 5013 5014 5015 5016 3 5 4 2 7 5 1 0 0 3 3 0 0,0001 0,0441 1,2063 0,0000 0,0510 0,0510 0,0532 2,5014 2,5017 1,2050 0,0532 1,3003 0 0 1 0 1 0 1 1 1 0 0 1 RELDSP2 05017 05020 05021 05022 05023 05024 05025 5017 5020 5021 5022 2 4 7 5 0,0000 1,2074 0,0011 0,0011 1 1 0 1 EQU XCH TS CS INH INT MAS K TS CCS TC TC CAF XCH TC EQU REL INT CS MAS K TS CAF TS TC RELDSP1 * Q RELRET BIT14 MONSAVE1 MONSAVE1 DSPLIST *+2 RELDSP2 ZERO DSPLIST JOBWAKE * BIT5 DSALMOUT DSALMOUT ZERO DSPLOCK RELRET * Q ; set DSPLOCK to +0, No DSPLIST search RELRET ; turn KEY RLSE light off if DSPLIST is light alone if DSPLIST *+2 RELDSP2 ZERO ; turn off KEY RLSE light ; was WAND DSALMOUT in Block II
; list empty
05026 05027
5026 3 5027 5
1 0 0 3
EQU XCH TS ; empty. Leave KEY RLSE ; DSPLIST is not e mpty. 0,0532 1 CCS 2,5033 1 TC 2,5017 1 TC 1,2050 0 CAF 0,0001 0 0,0441 0
; + not empty, leave KEY RLSE light alon e ; +0, list empty, turn off KEY RLSE ligh t ; - not empty, leave KEY RLSE light alon e
05034 05035
5034 5 5035 0
0,0501 0 0,0441 0
TS TC
DSPLOCK RELRET
;----------------- --------------------------------------------------------; NEWMODEA ; ; The new major mo de is in register A. Store the major mode in MODREG and updat e ; the major mode d isplay. ; ; I couldn't find this in my COLOSSUS listing, so I borrowed it from UPDATVB-1 ; (but modified it to work with the major mode instead of the verb). ;----------------- --------------------------------------------------------NEWMODEA 05036 05037 05040 05041 05042 05043 05044 05045 05046 05047 5036 5 5037 3 5040 5 5041 3 5042 5 5043 3 5044 6 5045 0 5046 5047 0 0,0500 1 0,0001 0 0,0572 1 2,4677 0 0,0466 0 1,2050 0 0,0500 1 1,3565 1 13144 1 0,0572 1 EQU TS XCH TS CAF TS CAF AD TC CAD R TC * MODREG Q NEWMODEA_Q MD1 DSPCOUNT ZERO MODREG BANKCALL DSPDECVN NEWMODEA_Q ; return
;----------------- -------------------------------------------------------; POODOO - Program alarm. ; ; Turn on program alarm light and store alarm code in FAILREG. The alarm code ; is retrieved fro m the address pointed to by Q. The most recent code is stored ; in FAILREG. Olde r codes are scrolled to FAILREG+1,+2. Older CADRs are ; scrolled down. ; ; This was missing from my COLOSSUS listing, so I had to guess at the ; implementation, based upon calling references in COLOSSUS, and textual ; descriptions of normal noun 9 which retrieves alarm codes. ;----------------- --------------------------------------------------------
POODOO 05050 05051 05052 05053 05054 05055 05056 05057 05060 05061 05062 05063 05064 05065 05066 5050 5051 5052 5053 5054 5055 5056 5057 5060 5061 5062 5063 5064 5065 5066 3 5 4 7 4 5 3 5 3 5 2 3 5 0 0,0001 0,0130 0,0011 2,5066 0,0000 0,0011 0,0461 0,0462 0,0460 0,0461 0,0130 0,0000 0,0460 1,2723 0 0 0 0 0 1 1 1 0 1 1 1 0 0
* Q MPAC DSALMOUT NOTPALT DSALMOUT FAILREG+1 FAILREG+2 FAILREG FAILREG+1 MPAC 0 FAILREG ENDOFJOB %77377
; inclusive OR bit 9 with 1 using ; Demorgan's theorem ; turn on PROG ALM light ; scroll previous codes down
77377 1 NOTPALT
;----------------- -------------------------------------------------------; PINBRNCH ; ; This is supposed to restore the DSKY display to its former state in the ; event of error. According to COLOSSUS, it works if you use "Margaret's" ; code. I don't ha ve that portion of the listing, so I just terminate ; the job, which s eems to be an acceptable work-around, even though the ; old display is n ot restored. ;----------------- -------------------------------------------------------05067 5067 0 1,2723 0 PINBRNCH TC ENDOFJOB
BANKFF_6
EQU
ORG BANK41_8 ; COLOSSUS pp. 379-380 INC L bank41_8.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bank41_8.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 379-380. ;================= =========================================================
; heavily modified from the original Block II code... 15573 15574 15575 15576 15577 15600 15601 15602 15603 15604 15605 15606 15607 15610 15611 15612 15613 15614 15615 15616 15617 15620 6,1573 6,1574 6,1575 6,1576 4 7 4 5 0,0011 6,7623 0,0000 0,0011 0 0 0 1 CS MAS K COM TS CAF TS CS IND EX TS CCS TC CS TS TS TS CAF TS TC CAF TC CAD R DSALMOUT TSTCON1 DSALMOUT TEN ERCNT FULLDSP ERCNT DSPTAB ERCNT TSTLTS1 FULLDSP1 DSPTAB+1 DSPTAB+4 DSPTAB+6 ELEVEN NOUT FLASHON SHOLTS WAITLIST TSTLTS2 ; turn on lights ; inclusive OR light bits with 1's using ; Demorgan's theorem
6,1577 3 6,1600 6,1601 6,1602 6,1603 6,1604 6,1605 6,1606 6,1607 6,1610 6,1611 5 4 2 5 1 0 4 5 5 5
1,2060 0 0,0414 6,7621 0,0414 0,0512 0,0414 6,7600 6,7622 0,0513 0,0516 0,0520 0 TSTLTS1 1 1 1 1 0 1 0 0 0
TC ENDOFJOB ; DSPLOCK is left busy (from keyboard ; action) until TS TLTS3 to ensure that ; lights test will be seen.
15621 15622
6,1621 6,1622
DS DS
%05675 %07675
; 1's Comp of UPTE L=bit3, KEY REL=bit5, oper err=bit7, PROG ALM=bit 9 15623 15624 6,1623 6,1624 77253 0 TSTCON1 00764 1 SHOLTS TSTLTS2 15625 15626 15627 15630 6,1625 3 6,1626 0 6,1627 6,1630 0 2,4131 1,3162 15631 1,2413 0 1 1 0 TSTLTS3 15631 15632 15633 15634 15635 15636 15637 15640 15641 15642 15643 6,1631 6,1632 6,1633 6,1634 2 3 7 5 0,0000 6,7623 0,0011 0,0011 0 1 0 1 DS DS EQU CAF TC CAD R TC EQU INH INT CAF MAS K TS REL INT TC CAD R TC TC TC CAD R EQU BANKCALL DSPMM KILMONON FLASHOFF POSTJUMP TSTLTS4 * ; redisplay C(MODREG) ; ; ; ; turn on kill monitor bit turn off V/N flash does RELDSP and goes to PINBRNCH if ENDIDLE is awaiting operator response %77253 %764 * CHRPRIO NOVAC TSTLTS3 TASKOVER * TSTCON1 DSALMOUT DSALMOUT ; turn off lights ; 5 sec
; called by WAITLIST
ORG BANK40_9 ; COLOSSUS pp. 381-382 INC L bank40_9.asm ;================= ========================================================= ; DISPLAY ROUTINES (file:bank40_9.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 381-382. ;================= ========================================================= ;----------------- --------------------------------------------------------; ERROR - Error li ght reset. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 381. ;----------------- ---------------------------------------------------------
EQU XCH TS
* _2122REG DSPLOCK
; restore original C(DSPLOCK), thus erro r ; light reset leaves DSPLOCK unchanged
; omitted some stu ff in COLOSSUS here 13464 13465 13466 13467 13470 13471 13472 13473 13474 13475 13476 13477 13500 13501 13502 13503 13504 13505 13506 13507 13510 13511 13512 13513 13514 13515 13516 13517 5,1464 4 5,1465 7 5,1466 5 5,1467 5,1470 5,1471 5,1472 5,1473 5,1474 5,1475 5,1476 3 5 2 2 1 6 0 6 5,7520 0 0,0011 0 0,0011 1 2,4700 0,0414 0,0000 0,0414 0,0512 1,2051 5,7502 1,2051 1 TSTAB 0 0 1 0 1 1 1 CS MAS K TS CAF TS INH INT IND EX CCS AD TC AD CS MAS K TC CS MAS K CS IND EX TS REL INT CCS TC CAF TS TS TS TC DS ERCON DSALMOUT DSALMOUT BINCON ERCNT ERCNT DSPTAB ONE ERPLUS ONE A NOTBIT12 ERCOM A NOTBIT12 A ERCNT DSPTAB ERCNT TSTAB+1 ZERO FAILREG FAILREG+1 FAILREG+2 ENDOFJOB %73777 ; clear the error codes for PROG ALM ; turn off UPTL, OPER ERR, PROG ALM
5,1477 4 5,1500 7 5,1501 0 5,1502 4 5,1503 7 5,1504 4 5,1505 5,1506 5,1507 5,1510 5,1511 5,1512 5,1513 5,1514 5,1515 2 5 2 1 0 3 5 5 5
0,0000 0 ERMINUS 5,7517 1 5,7505 0 0,0000 0 ERPLUS 5,7517 1 0,0000 0 0,0414 0,0512 0,0000 0,0414 5,7470 1,2050 0,0460 0,0461 0,0462 1 ERCOM 1 1 1 0 0 0 1 1
5,1516 0 5,1517
13520
5,1520
DS EQU
%504 *
; end of PINBALL r outines ; PINBALL NOUN tab les ORG BANK42_3 INC L bank42_3.asm ; COLOSSUS pp. 263-279 ;================= ========================================================= ; PINBALL NOUN TAB LES (file:bank42_3.asm) ; ; The following ro utines are for reading the noun tables and the scale ; factor (SF) tabl es (which are in a separate bank from the rest of ; PINBALL). These reading routines are in the same bank as the tables. ; They are called by DXCH Z (translated to DXCHJUMP for Block I). ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 263-279. ;================= ========================================================= ;----------------- --------------------------------------------------------; Noun table info from COLOSSUS, p.325 ; ; noun code < 40 : normal noun case ; noun code >= 40: mixed noun case ;----------------- --------------------------------------------------------; NNADTAB: ; for normal noun case, NNADTAB contains one CADR for each noun. ; +entry = noun CADR ; +0 = noun not used. ; -entry = machine CADR (E or F) to be specified. ; -1 = channel to be specified (not used for Block I); ; -0 = augment of last machine CADR supplied. ; for mixed noun c ase, NNADTAB contains one indirect address (IDADDREL) ; in low 10 bits, and the component code number in the high 5 bits. ; Examples: ; NNADTAB ; NNADTAB ; NNADTAB ; NNADTAB
= = = =
; ; ; ;
CADR for octal address 42 noun not used specify machine address augment last address
;----------------- --------------------------------------------------------; NNTYPETAB (norma l case): ; a packed table o f the form: MMMMM NNNNN PPPPP ; for the normal c ase: ; MMMMM (bits 15-11): COMPONENT CODE NUMBER (p.263) ; 00000 = 1 component ; 00001 = 2 component ; 00010 = 3 component ; X1XXX = bit4=1, decimal only ; 1XXXX = bit5=1, no load ; ; NNNNN (bits 10-6): SF ROUTINE CODE NUMBER (p.263) ; 00000 = octal only ; 00001 = straight fractional (decimal) ; 00010 = CDU degrees (XXX.XX) ; 00011 = arithmetic SF ; 00100 = arith DP1, OUT(mult by 2EXP14 at end), IN(straight ) ; 00101 = arith DP2, OUT(straight), IN(SL 7 at end) ; 00110 = Y optics degrees (XX.XXX max at 89.999) ; 00111 = arith DP3, OUT(SL 7 at end) IN(straight ) ; 01000 = whole hours in R1, whole minutes (mod 60) in R2, ; seconds (mod 60) 0XX.XX in R3 *** alarms if used wit h octal ; ; ; PPPPP (bits 5-1): SF CONSTANT CODE NUMBER (p.263) 00000 = whole, use arith
= = = = =
; ; ; ; ;
1 2 3 1 3
comp, octal only comp, octal only comp, octal only comp ,straight fractional comp ,straight fractional
;----------------- --------------------------------------------------------; NNTYPETAB (mixed case): ; a packed table o f the form: MMMMM NNNNN PPPPP ; for the mixed ca se ; MMMMM (bits ; NNNNN (bits ; PPPPP (bits (3 component): 15-11) = SF constant3 code number. 10-6) = SF constant2 code number. 5-1) = SF constant1 code number.
; for the mixed ca se (2 component): ; NNNNN (bits 10-6) = SF constant2 code number. ; PPPPP (bits 5-1) = SF constant1 code number. ; for the mixed ca se (1 component): ; PPPPP (bits 5-1) = SF constant1 code number. ;----------------- --------------------------------------------------------; IDADDTAB (mixed case only): ; there is also an indirect address table for mixed case only. ; Each entry conta ins one ECADR. IDADDREL is the relative address of ; the first of the se entries. ; There is one ent ry in this table for each component of a mixed noun. ; They are listed in order of ascending K. ;----------------- --------------------------------------------------------; RUTMXTAB (mixed case only): ; there is also a scale factor routine number table for mixed case only. ; There is one ent ry per mixed noun. The form is: QQQQQ RRRRR SSSSS ; for the 3 compon ent case ; QQQQQ (bits 15-11) = SF routine3 code number. ; RRRRR (bits 10-6) = SF routine2 code number. ; SSSSS (bits 5-1) = SF routine1 code number. ; for the 2 compon ent case ; RRRRR (bits 10-6) = SF routine2 code number. ; SSSSS (bits 5-1) = SF routine1 code number.
; ; ; ; ;
In octal display and load (oct or dec) verbs, exclude use of verbs whose component number is greater than the number of components in noun. (All machine add ress to be specified nouns are 3 component) In multi-compone nt load verbs, no mixing of octal and decimal data component words is allowed; alarm if violation.
; In decimal loads of data, 5 numerical chars must be keyed in before ; each enter; if n ot, alarm.
;----------------- ---------------------------------------------------------
; LODNNTAB ; loads NNADTEM wi th the NNADTAB entry, NNTYPTEM with the NNTYPTAB ; entry. If the no un is mixed, IDAD1TEM is loaded with the first IDADTAB ; entry, IDAD2TEM the second IDADTAB entry, IDAD3TEM the third IDADTAB ; entry, RUTMXTEM with the RUTMXTAB entry. MIXBR is set for mixed=2 ; or normal=1 noun . ; ; NOTE: in BlockII , NNADTEM = -1 means use an I/O channel instead of a ; memory address ( channel specified in NOUNCADR). Block I does not have ; I/O channels. ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 265. ;----------------- --------------------------------------------------------LODNNTAB 16114 16115 16116 16117 16120 16121 16122 16123 16124 16125 16126 16127 16130 16131 7,0114 5 7,0115 2 7,0116 3 7,0117 5 7,0120 2 7,0121 3 7,0122 5 7,0123 7,0124 7,0125 7,0126 7,0127 7,0130 7,0131 4 6 1 0 0 0 0 0,0562 0 0,0471 1 7,6210 1 0,0443 1 0,0471 1 7,6354 0 0,0444 0 0,0471 7,6161 0,0000 7,6132 7,6131 7,6131 7,6135 1 1 0 1 1 1 0 EQU TS IND EX CAF TS IND EX CAF TS CS AD CCS TC TC TC TC * GTSF_RET NOUNREG NNADTAB NNADTEM NOUNREG NNTYPTAB NNTYPTEM NOUNREG MIXCON A *+4 *+2 *+1 LODMIXNN
; ; ; ; ;
BZMF LODMIXNN in Block II noun number G/E first mixed noun noun number G/E first mixed noun noun number G/E first mixed noun
CAF TS TC EQU CAF TS IND EX CAF TS CAF MAS K TS IND EX CAF TS IND EX CAF TS IND EX CAF TS LODNLV EQU CAF AD TC DS
ONE MIXBR LODNLV * TWO MIXBR NOUNREG RUTMXTAB-40 RUTMXTEM LOW10 NNADTEM Q A IDADDTAB IDAD1TEM Q IDADDTAB+1 IDAD2TEM Q IDADDTAB+2 IDAD3TEM * ZERO GTSF_RET DXCHJUMP %50
16135 16136 16137 16140 16141 16142 16143 16144 16145 16146 16147 16150 16151 16152 16153 16154 16155
7,0135 3 7,0136 5 7,0137 2 7,0140 3 7,0141 5 7,0142 3 7,0143 7 7,0144 5 7,0145 2 7,0146 3 7,0147 5 7,0150 2 7,0151 3 7,0152 5 7,0153 2 7,0154 3 7,0155 5
1,2052 1 0,0435 0 0,0471 1 7,7054 1 0,0450 0 2,4674 0 0,0443 0 0,0001 0 0,0000 0 7,6640 0 0,0445 1 0,0001 1 7,6641 1 0,0446 1 0,0001 1 7,6642 1 0,0447 0
; temp
;----------------- --------------------------------------------------------; GTSFOUT ; On entry, SFTEMP 1 contains SFCONUM X 2. ; Loads SFTEMP1, S FTEMP2 with the DP SFOUTAB entries ; ; GTSFIN ; On entry, SFTEMP 1 contains SFCONUM X 2. ; Loads SFTEMP1, S FTEMP2 with the DP SFINTAB entries ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 266. ;----------------- --------------------------------------------------------GTSFOUT 16162 7,0162 5 0,0562 0 EQU TS * GTSF_RET
XCH TS IND EX CAF TS IND EX CAF TS EQU CAF AD TC EQU TS XCH TS IND EX CAF TS IND EX CAF TS TC
SFTEMP1 Q Q SFOUTAB SFTEMP1 Q SFOUTAB+1 SFTEMP2 * ZERO GTSF_RET DXCHJUMP * GTSF_RET SFTEMP1 Q Q SFINTAB SFTEMP1 Q SFINTAB+1 SFTEMP2 SFCOM
; temp
16176 16177 16200 16201 16202 16203 16204 16205 16206 16207
7,0176 5 7,0177 3 7,0200 5 7,0201 2 7,0202 3 7,0203 5 7,0204 2 7,0205 3 7,0206 5 7,0207 0
0,0562 0 0,0420 1 0,0001 0 0,0001 1 7,6520 0 0,0420 1 0,0001 1 7,6521 1 0,0421 0 7,6173 1
; temp
;----------------- --------------------------------------------------------; NOUN ADDRESS TAB LE (NNADTAB) ; Indexed by noun number (0-39 decimal for normal nouns). ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 266. ;----------------- --------------------------------------------------------NNADTAB 16210 16211 16212 16213 16214 16215 16216 16217 16220 16221 16222 16223 16224 16225 16226 16227 16230 16231 16232 16233 16234 16235 16236 16237 16240 16241 16242 16243 16244 16245 16246 16247 16250 16251 16252 16253 16254 16255 16256 16257 7,0210 7,0211 7,0212 7,0213 7,0214 7,0215 7,0216 7,0217 7,0220 7,0221 7,0222 7,0223 7,0224 7,0225 7,0226 7,0227 7,0230 7,0231 7,0232 7,0233 7,0234 7,0235 7,0236 7,0237 7,0240 7,0241 7,0242 7,0243 7,0244 7,0245 7,0246 7,0247 7,0250 7,0251 7,0252 7,0253 7,0254 7,0255 7,0256 7,0257 00000 40000 40000 40000 00036 00000 00000 00000 00000 00460 00000 00000 00000 00000 00000 77777 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00534 00000 00000 00000 00000 00000 00000 00000 00000 00000 00035 00000 00000 00000 1 0 0 0 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 EQU DS DS DS DS DS DS DS DS DS ECA DR DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS ECA DR DS DS DS DS DS DS DS DS DS ECA DR DS DS DS ; end of normal no uns ; start of mixed n ouns 16260 16261 7,0260 7,0261 00000 1 00000 1 DS DS %0 %0 ; 40 - spare ; 41 - spare * %0 %40000 %40000 %40000 %00036 %0 %0 %0 %0 FAILREG %0 %0 %0 %0 %0 %77777 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 DSPTEM1 %0 %0 %0 %0 %0 %0 %0 %0 %0 TIME2 %0 %0 %0 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; NN 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 NORMAL NOUNS not in use specify machine address (fraction a l ) specify machine address (whole) specify machine address (degrees) spare *********** TEST, CHANGE TO Z E R O spare spare spare spare alarm codes spare spare spare spare spare increment machine address spare spare spare spare spare spare spare spare spare spare prio/delay, adres, BBCON spare spare spare spare spare spare spare spare spare time of AGC clock (hrs, min, sec) spare spare spare
16262 16263 16264 16265 16266 16267 16270 16271 16272 16273 16274 16275 16276 16277 16300 16301 16302 16303 16304 16305 16306 16307 16310 16311 16312 16313 16314 16315 16316 16317 16320 16321 16322 16323 16324 16325 16326 16327 16330 16331 16332 16333 16334 16335 16336 16337 16340 16341 16342 16343 16344 16345 16346 16347 16350 16351 16352 16353
7,0262 7,0263 7,0264 7,0265 7,0266 7,0267 7,0270 7,0271 7,0272 7,0273 7,0274 7,0275 7,0276 7,0277 7,0300 7,0301 7,0302 7,0303 7,0304 7,0305 7,0306 7,0307 7,0310 7,0311 7,0312 7,0313 7,0314 7,0315 7,0316 7,0317 7,0320 7,0321 7,0322 7,0323 7,0324 7,0325 7,0326 7,0327 7,0330 7,0331 7,0332 7,0333 7,0334 7,0335 7,0336 7,0337 7,0340 7,0341 7,0342 7,0343 7,0344 7,0345 7,0346 7,0347 7,0350 7,0351 7,0352 7,0353
00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
%0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare
;----------------- --------------------------------------------------------; NOUN TYPE TABLE (NNTYPTAB) ; Indexed by noun number (0-39 decimal for normal nouns). ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 269. ;----------------- --------------------------------------------------------NNTYPTAB 16354 16355 16356 16357 16360 16361 16362 16363 16364 16365 16366 16367 16370 16371 16372 16373 16374 16375 7,0354 7,0355 7,0356 7,0357 7,0360 7,0361 7,0362 7,0363 7,0364 7,0365 7,0366 7,0367 7,0370 7,0371 7,0372 7,0373 7,0374 7,0375 00000 04040 04140 04102 00000 00000 00000 00000 00000 04000 00000 00000 00000 00000 00000 00000 00000 00000 1 1 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 EQU DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS * %0 %04040 %04140 %04102 %0 %0 %0 %0 %0 %04000 %0 %0 %0 %0 %0 %0 %0 %0 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; NN 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 NORMAL NOUNS not in use 3 component (fractional) 3 component (whole) 3 component (CDU degrees) spare spare spare spare spare 3 component, octal only spare spare spare spare spare 1 component, octal only spare spare
16376 16377 16400 16401 16402 16403 16404 16405 16406 16407 16410 16411 16412 16413 16414 16415 16416 16417 16420 16421 16422 16423
7,0376 7,0377 7,0400 7,0401 7,0402 7,0403 7,0404 7,0405 7,0406 7,0407 7,0410 7,0411 7,0412 7,0413 7,0414 7,0415 7,0416 7,0417 7,0420 7,0421 7,0422 7,0423
00000 00000 00000 00000 00000 00000 00000 00000 04000 00000 00000 00000 00000 00000 00000 00000 00000 00000 24400 00000 00000 00000
1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1
%0 %0 %0 %0 %0 %0 %0 %0 %04000 %0 %0 %0 %0 %0 %0 %0 %0 %0 %24400 %0 %0 %0
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
spare spare spare spare spare spare spare spare 3 component, octal only spare spare spare spare spare spare spare spare spare 3 component, HMS, (dec only) spare spare spare
16424 16425 16426 16427 16430 16431 16432 16433 16434 16435 16436 16437 16440 16441 16442 16443 16444 16445 16446 16447 16450 16451 16452 16453 16454 16455 16456 16457 16460 16461 16462 16463 16464 16465 16466 16467 16470 16471 16472 16473 16474 16475 16476 16477 16500 16501 16502 16503 16504 16505 16506 16507 16510 16511 16512 16513 16514 16515 16516 16517
7,0424 7,0425 7,0426 7,0427 7,0430 7,0431 7,0432 7,0433 7,0434 7,0435 7,0436 7,0437 7,0440 7,0441 7,0442 7,0443 7,0444 7,0445 7,0446 7,0447 7,0450 7,0451 7,0452 7,0453 7,0454 7,0455 7,0456 7,0457 7,0460 7,0461 7,0462 7,0463 7,0464 7,0465 7,0466 7,0467 7,0470 7,0471 7,0472 7,0473 7,0474 7,0475 7,0476 7,0477 7,0500 7,0501 7,0502 7,0503 7,0504 7,0505 7,0506 7,0507 7,0510 7,0511 7,0512 7,0513 7,0514 7,0515 7,0516 7,0517
00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
%0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare
;----------------- --------------------------------------------------------; SCALE FACTOR INP UT TABLE (SFINTAB) ; Indexed by SF co nstant code number x 2 PPPPP (0-19 decimal; 0-23 octal) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 272. ;----------------- --------------------------------------------------------SFINTAB 16520 16521 16522 16523 16524 16525 16526 16527 16530 16531 16532 16533 16534 16535 16536 16537 16540 16541 16542 16543 16544 16545 16546 16547 16550 16551 16552 16553 16554 16555 16556 16557 16560 16561 16562 16563 16564 16565 16566 16567 7,0520 7,0521 7,0522 7,0523 7,0524 7,0525 7,0526 7,0527 7,0530 7,0531 7,0532 7,0533 7,0534 7,0535 7,0536 7,0537 7,0540 7,0541 7,0542 7,0543 7,0544 7,0545 7,0546 7,0547 7,0550 7,0551 7,0552 7,0553 7,0554 7,0555 7,0556 7,0557 7,0560 7,0561 7,0562 7,0563 7,0564 7,0565 7,0566 7,0567 00006 1 03240 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 EQU DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS * %00006 %03240 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000
; 00 - whole, DP time (sec) ; 00 ; 01 - spare ; 01 ; 02 - CDU degrees, Y optics degrees ; 02 (SFCONs in DEGINSF, OPTDEGIN ; 03 ; 03 ; 04 ; 04 ; 05 ; 05 ; 06 ; 06 ; 07 ; 07 ; 10 ; 10 ; 11 ; 11 ; 12 ; 12 ; 13 ; 13 ; 14 ; 14 ; 15 ; 15 ; 16 ; 16 ; 17 ; 17 ; 20 ; 20 ; 21 ; 21 ; 22 ; 22 ; 23 ; 23
;----------------- --------------------------------------------------------; SCALE FACTOR OUT PUT TABLE (SFOUTAB) ; Indexed by SF co nstant code number x 2 PPPPP (0-19 decimal; 0-23 octal) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 273. ;----------------- --------------------------------------------------------SFOUTAB 16570 16571 16572 16573 16574 16575 7,0570 7,0571 7,0572 7,0573 7,0574 7,0575 05174 0 13261 0 00000 1 00000 1 00000 1 00000 1 EQU DS DS DS DS DS DS * %05174 %13261 %00000 %00000 %00000 %00000
; 00 - whole, DP time (sec) ; 00 ; 01 - spare ; 01 ; 02 - CDU degrees, Y optics degrees ; 02 (SFCONs in DEGOURSF, OPTDEGOUT
16576 16577 16600 16601 16602 16603 16604 16605 16606 16607 16610 16611 16612 16613 16614 16615 16616 16617 16620 16621 16622 16623 16624 16625 16626 16627 16630 16631 16632 16633 16634 16635 16636 16637
7,0576 7,0577 7,0600 7,0601 7,0602 7,0603 7,0604 7,0605 7,0606 7,0607 7,0610 7,0611 7,0612 7,0613 7,0614 7,0615 7,0616 7,0617 7,0620 7,0621 7,0622 7,0623 7,0624 7,0625 7,0626 7,0627 7,0630 7,0631 7,0632 7,0633 7,0634 7,0635 7,0636 7,0637
00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1
DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS
%00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000 %00000
; 03 ; 03 ; 04 ; 04 ; 05 ; 05 ; 06 ; 06 ; 07 ; 07 ; 10 ; 10 ; 11 ; 11 ; 12 ; 12 ; 13 ; 13 ; 14 ; 14 ; 15 ; 15 ; 16 ; 16 ; 17 ; 17 ; 20 ; 20 ; 21 ; 21 ; 22 ; 22 ; 23 ; 23
; SCALE FACTOR INP UT ROUTINE TABLE is on pp. 342, 343 of COLOSSUS ; SCALE FACTOR OUT PUT ROUTINE TABLE is on p. 329 of COLOSSUS ;----------------- --------------------------------------------------------; MIXED NOUN ADDRE SS TABLE (IDADDTAB) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 274. ;----------------- --------------------------------------------------------; ** currently, th e table is not populated ** IDADDTAB 16640 16641 16642 16643 16644 16645 16646 16647 16650 16651 16652 16653 16654 16655 16656 16657 7,0640 7,0641 7,0642 7,0643 7,0644 7,0645 7,0646 7,0647 7,0650 7,0651 7,0652 7,0653 7,0654 7,0655 7,0656 7,0657 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 EQU DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS * %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0
; 40 - spare component ; 40 - spare component ; 40 - spare component ; 41 - spare component ; 41 - spare component ; 41 - spare component ; 42 - spare component ; 42 - spare component ; 42 - spare component ; 43 - spare component ; 43 - spare component ; 43 - spare component ; 44 - spare component ; 44 - spare component ; 44 - spare component ; 45 - spare component
16660 16661 16662 16663 16664 16665 16666 16667 16670 16671 16672 16673 16674 16675 16676 16677 16700 16701 16702 16703 16704 16705 16706 16707 16710 16711 16712 16713 16714 16715 16716 16717 16720 16721 16722 16723 16724 16725 16726 16727 16730 16731 16732 16733 16734 16735 16736 16737 16740 16741 16742 16743 16744 16745 16746 16747 16750 16751 16752 16753 16754 16755 16756 16757 16760
7,0660 7,0661 7,0662 7,0663 7,0664 7,0665 7,0666 7,0667 7,0670 7,0671 7,0672 7,0673 7,0674 7,0675 7,0676 7,0677 7,0700 7,0701 7,0702 7,0703 7,0704 7,0705 7,0706 7,0707 7,0710 7,0711 7,0712 7,0713 7,0714 7,0715 7,0716 7,0717 7,0720 7,0721 7,0722 7,0723 7,0724 7,0725 7,0726 7,0727 7,0730 7,0731 7,0732 7,0733 7,0734 7,0735 7,0736 7,0737 7,0740 7,0741 7,0742 7,0743 7,0744 7,0745 7,0746 7,0747 7,0750 7,0751 7,0752 7,0753 7,0754 7,0755 7,0756 7,0757 7,0760
00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1
DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS
%0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0
; 45 - spare component ; 45 - spare component ; 46 - spare component ; 46 - spare component ; 46 - spare component ; 47 - spare component ; 47 - spare component ; 47 - spare component ; 48 - spare component ; 48 - spare component ; 48 - spare component ; 49 - spare component ; 49 - spare component ; 49 - spare component ; 50 - spare component ; 50 - spare component ; 50 - spare component ; 51 - spare component ; 51 - spare component ; 51 - spare component ; 52 - spare component ; 52 - spare component ; 52 - spare component ; 53 - spare component ; 53 - spare component ; 53 - spare component ; 54 - spare component ; 54 - spare component ; 54 - spare component ; 55 - spare component ; 55 - spare component ; 55 - spare component ; 56 - spare component ; 56 - spare component ; 56 - spare component ; 57 - spare component ; 57 - spare component ; 57 - spare component ; 58 - spare component ; 58 - spare component ; 58 - spare component ; 59 - spare component ; 59 - spare component ; 59 - spare component ; 60 - spare component ; 60 - spare component ; 60 - spare component ; 61 - spare component ; 61 - spare component ; 61 - spare component ; 62 - spare component ; 62 - spare component ; 62 - spare component ; 63 - spare component ; 63 - spare component ; 63 - spare component ; 64 - spare component ; 64 - spare component ; 64 - spare component ; 65 - spare component ; 65 - spare component ; 65 - spare component ; 66 - spare component ; 66 - spare component ; 66 - spare component
16761 16762 16763 16764 16765 16766 16767 16770 16771 16772 16773 16774 16775 16776 16777 17000 17001 17002 17003 17004 17005 17006 17007 17010 17011 17012 17013 17014 17015 17016 17017 17020 17021 17022 17023 17024 17025 17026 17027 17030 17031 17032 17033 17034 17035 17036 17037 17040 17041 17042 17043 17044 17045 17046 17047 17050 17051 17052 17053 17054 17055 17056 17057 17060 17061 17062
7,0761 7,0762 7,0763 7,0764 7,0765 7,0766 7,0767 7,0770 7,0771 7,0772 7,0773 7,0774 7,0775 7,0776 7,0777 7,1000 7,1001 7,1002 7,1003 7,1004 7,1005 7,1006 7,1007 7,1010 7,1011 7,1012 7,1013 7,1014 7,1015 7,1016 7,1017 7,1020 7,1021 7,1022 7,1023 7,1024 7,1025 7,1026 7,1027 7,1030 7,1031 7,1032 7,1033 7,1034 7,1035 7,1036 7,1037 7,1040 7,1041 7,1042 7,1043 7,1044 7,1045 7,1046 7,1047 7,1050 7,1051 7,1052 7,1053 7,1054 7,1055 7,1056 7,1057 7,1060 7,1061 7,1062
00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1
DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS
%0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0
; 67 - spare component ; 67 - spare component ; 67 - spare component ; 68 - spare component ; 68 - spare component ; 68 - spare component ; 69 - spare component ; 69 - spare component ; 69 - spare component ; 70 - spare component ; 70 - spare component ; 70 - spare component ; 71 - spare component ; 71 - spare component ; 71 - spare component ; 72 - spare component ; 72 - spare component ; 72 - spare component ; 73 - spare component ; 73 - spare component ; 73 - spare component ; 74 - spare component ; 74 - spare component ; 74 - spare component ; 75 - spare component ; 75 - spare component ; 75 - spare component ; 76 - spare component ; 76 - spare component ; 76 - spare component ; 77 - spare component ; 77 - spare component ; 77 - spare component ; 78 - spare component ; 78 - spare component ; 78 - spare component ; 79 - spare component ; 79 - spare component ; 79 - spare component ; 80 - spare component ; 80 - spare component ; 80 - spare component ; 81 - spare component ; 81 - spare component ; 81 - spare component ; 82 - spare component ; 82 - spare component ; 82 - spare component ; 83 - spare component ; 83 - spare component ; 83 - spare component ; 84 - spare component ; 84 - spare component ; 84 - spare component ; 85 - spare component ; 85 - spare component ; 85 - spare component ; 86 - spare component ; 86 - spare component ; 86 - spare component ; 87 - spare component ; 87 - spare component ; 87 - spare component ; 88 - spare component ; 88 - spare component ; 88 - spare component
17063 17064 17065 17066 17067 17070 17071 17072 17073 17074 17075 17076 17077 17100 17101 17102 17103 17104 17105 17106 17107 17110 17111 17112 17113 17114 17115 17116 17117 17120 17121 17122 17123
7,1063 7,1064 7,1065 7,1066 7,1067 7,1070 7,1071 7,1072 7,1073 7,1074 7,1075 7,1076 7,1077 7,1100 7,1101 7,1102 7,1103 7,1104 7,1105 7,1106 7,1107 7,1110 7,1111 7,1112 7,1113 7,1114 7,1115 7,1116 7,1117 7,1120 7,1121 7,1122 7,1123
00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1 00000 1
DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS
%0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0
; 89 - spare component ; 89 - spare component ; 89 - spare component ; 90 - spare component ; 90 - spare component ; 90 - spare component ; 91 - spare component ; 91 - spare component ; 91 - spare component ; 92 - spare component ; 92 - spare component ; 92 - spare component ; 93 - spare component ; 93 - spare component ; 93 - spare component ; 94 - spare component ; 94 - spare component ; 94 - spare component ; 95 - spare component ; 95 - spare component ; 95 - spare component ; 96 - spare component ; 96 - spare component ; 96 - spare component ; 97 - spare component ; 97 - spare component ; 97 - spare component ; 98 - spare component ; 98 - spare component ; 98 - spare component ; 99 - spare component ; 99 - spare component ; 99 - spare component
;----------------- --------------------------------------------------------; MIXED NOUN SCALE FACTOR ROUTINE TABLE (RUTMXTAB) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 278. ;----------------- --------------------------------------------------------; ** currently, th e table is not populated ** RUTMXTAB 17124 17125 17126 17127 17130 17131 17132 17133 17134 17135 17136 17137 17140 17141 17142 17143 17144 17145 17146 17147 17150 17151 17152 17153 17154 17155 17156 17157 17160 17161 17162 7,1124 7,1125 7,1126 7,1127 7,1130 7,1131 7,1132 7,1133 7,1134 7,1135 7,1136 7,1137 7,1140 7,1141 7,1142 7,1143 7,1144 7,1145 7,1146 7,1147 7,1150 7,1151 7,1152 7,1153 7,1154 7,1155 7,1156 7,1157 7,1160 7,1161 7,1162 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 EQU DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS * %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0 %0
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare
17163 17164 17165 17166 17167 17170 17171 17172 17173 17174 17175 17176 17177 17200 17201 17202 17203 17204 17205 17206 17207 17210 17211 17212 17213 17214 17215 17216 17217
7,1163 7,1164 7,1165 7,1166 7,1167 7,1170 7,1171 7,1172 7,1173 7,1174 7,1175 7,1176 7,1177 7,1200 7,1201 7,1202 7,1203 7,1204 7,1205 7,1206 7,1207 7,1210 7,1211 7,1212 7,1213 7,1214 7,1215 7,1216 7,1217
00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
71 - spare 72 - spare 73 - spare 74 - spare 75 - spare 76 - spare 77 - spare 78 - spare 79 - spare 80 - spare 81 - spare 82 - spare 83 - spare 84 - spare 85 - spare 86 - spare 87 - spare 88 - spare 89 - spare 90 - spare 91 - spare 92 - spare 93 - spare 94 - spare 95 - spare 96 - spare 97 - spare 98 - spare 99 - spare table
; extended verb ta bles ORG BANK43_1 INC L bank43_1.asm ; COLOSSUS pp. 230-232 ;================= ========================================================= ; DISPLAY ROUTINES (file:bank43_1.asm) ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, pp . 230. ;================= ========================================================= ;----------------- --------------------------------------------------------; GOEXTVB -- EXTEN DED VERBS ; ; Adapted from the AGC Block II COLOSSUS rev 249 assembly listing, ; Oct 28, 1968, p. 230. ;----------------- --------------------------------------------------------GOEXTVB 2 0 0 0 0 1 0 , 0 0 0 0 2 0,0130 1 2 0 0 0 1 1 0 , 0 0 0 1 0 10,6002 0 LST2FAN 20002 20003 20004 20005 20006 20007 20010 20011 20012 20013 20014 20015 20016 20017 20020 20021 20022 20023 20024 20025 20026 20027 20030 20031 20032 20033 20034 20035 20036 20037 20040 10,0002 10,0003 10,0004 10,0005 10,0006 10,0007 10,0010 10,0011 10,0012 10,0013 10,0014 10,0015 10,0016 10,0017 10,0020 10,0021 10,0022 10,0023 10,0024 10,0025 10,0026 10,0027 10,0030 10,0031 10,0032 10,0033 10,0034 10,0035 10,0036 10,0037 10,0040 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 EQU IND EX TC EQU TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC * MPAC LST2FAN * ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
VB40 VB41 VB42 VB43 VB44 VB45 VB46 VB47 VB48 VB49 VB50 VB51 VB52 VB53 VB54 VB55 VB56 VB57 VB58 VB59 VB60 VB61 VB62 VB63 VB64 VB65 VB66 VB67 VB68 VB69 VB70
spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare
20041 20042 20043 20044 20045 20046 20047 20050 20051 20052 20053 20054 20055 20056 20057 20060 20061 20062 20063 20064 20065 20066 20067 20070 20071 20072 20073 20074 20075
10,0041 10,0042 10,0043 10,0044 10,0045 10,0046 10,0047 10,0050 10,0051 10,0052 10,0053 10,0054 10,0055 10,0056 10,0057 10,0060 10,0061 10,0062 10,0063 10,0064 10,0065 10,0066 10,0067 10,0070 10,0071 10,0072 10,0073 10,0074 10,0075
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076 10,6076
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC TC
ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END ALM_END
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
VB71 VB72 VB73 VB74 VB75 VB76 VB77 VB78 VB79 VB80 VB81 VB82 VB83 VB84 VB85 VB86 VB87 VB88 VB89 VB90 VB91 VB92 VB93 VB94 VB95 VB96 VB97 VB98 VB99
spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare spare
EQU TC TC FCA DR
BANK43_2
EQU
;----------------- --------------------------------------------------------; P00 CMC IDLE PRO GRAM ; ; Does nothing ;----------------- --------------------------------------------------------P00 EQU *
; Start any jobs o r tasks needed at AGC initialization. 22000 22001 22002 22003 1 1 , 0 0 0 0 3 11,6004 0 1 1 , 0 0 0 1 0 1,2232 0 11,0002 22005 1 1 1 , 0 0 0 3 0 1,2723 0 CAF TC CAD R TC time1 WAITLIST task1 ENDOFJOB ; add a test task ; 14-bit task address
; TEST CODE - task started by P00 22004 11,0004 01750 1 time1 task1 2 2 0 0 5 1 1 , 0 0 0 5 3 11,6011 1 2 2 0 0 6 1 1 , 0 0 0 6 0 1,3162 1 22007 11,0007 22012 1 22010 11,0010 0 1,2413 0 DS EQU XCH TC CAD R TC 1000 * prio1 NOVAC job1 TASKOVER ; 10 seconds
; TEST CODE - job started by task 22011 11,0011 00003 1 prio1 job1 22012 11,0012 3 1,2050 0 DS EQU CAF %3 * ZERO ; lowest priority
6 6 5 0
1 1 1 0
AD AD TS TC
;----------------- --------------------------------------------------------; P01 DEMO PROGRAM ; ; Calls pinball: v erb 1, noun 4. ;----------------- --------------------------------------------------------22017 11,0017 22020 11,0020 22021 11,0021 00204 1 nvcode1 22024 1 restart1_addr 00042 1 tcadr1 DS DS DS %0204 P01_restart %42 ; verb 01, noun 04
EQU CAF TS
* tcadr1 MPAC+2
P01_restart 2 2 0 2 4 1 1 , 0 0 2 4 3 11,6017 1 2 2 0 2 5 1 1 , 0 0 2 5 0 2,4503 0 2 2 0 2 6 1 1 , 0 0 2 6 0 11,6030 1 2 2 0 2 7 1 1 , 0 0 2 7 0 1,2723 0 2 2 0 3 0 1 1 , 0 0 3 0 3 11,6020 0 2 2 0 3 1 1 1 , 0 0 3 1 0 2,5001 0 22032 11,0032 0 1,2723 0
* nvcode1 NVSUB *+2 ENDOFJOB restart1_addr NVSUBUSY ENDOFJOB ; display busy ; execution of verb/noun succeeded
;----------------- --------------------------------------------------------; P02 DEMO PROGRAM ; ; Calls pinball: v erb 21, noun 2. ; ; Sleeps if DSKY i s busy until KEYREL. Executes verb 21, noun 2 to do ; an external load . Then it sleeps with ENDIDLE until the user loads ; the data or term inatest the load with PROCEED or TERMINATE. ; NOTE: routines t hat call ENDIDLE must be in fixed-switchable memory ;----------------- --------------------------------------------------------22033 11,0033 22034 11,0034 22035 11,0035 05202 1 nvcode2 22040 0 restart2_addr 00042 1 tcadr2 DS DS DS %05202 P02_restart %42 ; verb 21, noun 02
P02 2 2 0 3 6 1 1 , 0 0 3 6 3 11,6035 1 2 2 0 3 7 1 1 , 0 0 3 7 5 0,0132 1 P02_restart 2 2 0 4 0 1 1 , 0 0 4 0 3 11,6033 1 2 2 0 4 1 1 1 , 0 0 4 1 0 2,4503 0 2 2 0 4 2 1 1 , 0 0 4 2 0 11,6044 1 2 2 0 4 3 1 1 , 0 0 4 3 0 11,6047 1 2 2 0 4 4 1 1 , 0 0 4 4 3 11,6034 0 2 2 0 4 5 1 1 , 0 0 4 5 0 2,5001 0 2 2 0 4 6 1 1 , 0 0 4 6 0 1,2723 0 P02_wait 22047 22050 22051 22052 22053 22054 11,0047 11,0050 11,0051 11,0052 11,0053 11,0054 0 2,4541 0 0 11,6060 1 0 11,6055 1 3 1,2051 1 5 0,0043 0 0 1,2723 0 P02_pwd 22055 11,0055 3 22056 11,0056 5 22057 11,0057 0 1,2052 1 0,0043 0 1,2723 0 P02_ter 22060 11,0060 3 22061 11,0061 5 22062 11,0062 0 1,2053 0 0,0043 0 1,2723 0
EQU CAF TS EQU CAF TC TC TC CAF TC TC EQU TC TC TC CAF TS TC EQU CAF TS TC EQU CAF TS TC
* tcadr2 MPAC+2 * nvcode2 NVSUB *+2 P02_wait restart2_addr NVSUBUSY ENDOFJOB * ENDIDLE P02_ter P02_pwd ONE %43 ENDOFJOB * TWO %43 ENDOFJOB * THREE %43 ENDOFJOB ; display busy ; execution of verb/noun succeeded
; ; ; ;
; Nearly identical to P02, except that the job does not go to sleep ; waiting for the load with ENDIDLE. Instead, it busy-waits on LOADSTAT. ; NOTE: routines t hat call ENDIDLE must be in fixed-switchable memory ;----------------- --------------------------------------------------------22063 11,0063 22064 11,0064 22065 11,0065 05202 1 nvcode3 22070 0 restart3_addr 00042 1 tcadr3 DS DS DS %05202 P03_restart %42 ; verb 21, noun 02
P03 2 2 0 6 6 1 1 , 0 0 6 6 3 11,6065 1 2 2 0 6 7 1 1 , 0 0 6 7 5 0,0132 1 P03_restart 2 2 0 7 0 1 1 , 0 0 7 0 3 11,6063 1 2 2 0 7 1 1 1 , 0 0 7 1 0 2,4503 0 2 2 0 7 2 1 1 , 0 0 7 2 0 11,6074 1 2 2 0 7 3 1 1 , 0 0 7 3 0 11,6077 1 2 2 0 7 4 1 1 , 0 0 7 4 3 11,6064 0 2 2 0 7 5 1 1 , 0 0 7 5 0 2,5001 0 2 2 0 7 6 1 1 , 0 0 7 6 0 1,2723 0 P03_wait 22077 22100 in 22101 22102 22103 1 1 , 0 0 7 7 1 0,0503 0 1 1 , 0 1 0 0 0 11,6115 1 1 1 , 0 1 0 1 0 11,6107 1 1 1 , 0 1 0 2 0 11,6120 1 1 1 , 0 1 0 3 3 0,0000 1 1,2051 1 0,0043 0 1,2723 0 P03_yield 22107 11,0107 3 22110 11,0110 6 22111 11,0111 5 1,2051 1 0,0043 0 0,0043 0
EQU CAF TS EQU CAF TC TC TC CAF TC TC EQU CCS TC TC TC NOO P CAF TS TC EQU CAF AD TS CCS TC TC
* tcadr3 MPAC+2 * nvcode3 NVSUB *+2 P03_wait restart3_addr NVSUBUSY ENDOFJOB * LOADSTAT P03_pwd P03_yield P03_ter ; display busy ; execution of verb/noun succeeded
; >0, verb "proceed w/o data" has been k e y e d ; +0, waiting for data ; <0, verb "terminate" has been keyed in ; -0, load has been completed ; data in ; set loc=1
ONE %43 ENDOFJOB * ONE %43 %43 newJob CHANG1 P03_wait * TWO %43 ENDOFJOB * THREE %43 ENDOFJOB
; incr loc while busy-waiting ; yield to higher priority job? ; yes ; no, keep busy-waiting ; proceed without data ; set loc=2
2 2 1 1 2 1 1 , 0 1 1 2 1 0,0307 1 2 2 1 1 3 1 1 , 0 1 1 3 0 1,2733 1 2 2 1 1 4 1 1 , 0 1 1 4 0 11,6077 1 P03_pwd 22115 11,0115 3 22116 11,0116 5 22117 11,0117 0 1,2052 1 0,0043 0 1,2723 0 P03_ter 22120 11,0120 3 22121 11,0121 5 22122 11,0122 0 1,2053 0 0,0043 0 1,2723 0
;----------------- --------------------------------------------------------; P04 DEMO PROGRAM ; ; Calls pinball: m onitor verb 11, noun 04. ;----------------- --------------------------------------------------------22123 11,0123 22124 11,0124 22125 11,0125 22126 11,0126 02604 1 nvcode4 22131 1 restart4_addr 00042 1 tcadr4 ;mon_option 02206 1 mon_option DS DS DS DS DS %02604 P04_restart %42 %6 %2206 ; verb 11, noun 04
EQU CAF TS
* tcadr4 MPAC+2
22141 11,0141 0
1,2723 0
TC
ENDOFJOB
;----------------- --------------------------------------------------------; P78 DEMO PROGRAM ; ;----------------- --------------------------------------------------------P78 22142 22143 22144 22145 22146 11,0142 11,0143 11,0144 11,0145 11,0146 3 6 6 5 0 1,2050 0,0051 1,2051 0,0051 1,2723 0 0 1 0 0 EQU CAF AD AD TS TC * ZERO %51 ONE %51 ENDOFJOB
;----------------- --------------------------------------------------------; P79 DEMO PROGRAM ; ;----------------- --------------------------------------------------------P79 22147 22150 22151 22152 22153 11,0147 11,0150 11,0151 11,0152 11,0153 3 6 6 5 0 1,2050 0,0052 1,2051 0,0052 1,2723 0 0 1 0 0 EQU CAF AD AD TS TC * ZERO %52 ONE %52 ENDOFJOB
A s s e m b l y c o m p lete. Errors = 0 Symbol table: BANK0 MAXDELAY TSKADDR WL_IN_saveQ WL_AT_saveQ WL_AT_timeLeft WL_T3_oldBank WL_ST_newTime WL_RT_runAddr WL_RM_taskPtr2 WL_IS_newTime WL_IS_taskPtr MAXJOBS MPAC BANKSET JOBPRIOBASE JREC2 JREC5 LOCCTR newJob EX_JW_CADR EX_JW_jobPtr2 EX_AJ_loopCnt EX_AJ_field EX_IN_loopCnt EX_IN_field EX_MN_field EX_RM_jobPtr EX_RM_loopCnt EX_RM_findx EX_IS_newLoc EX_IS_jobPtr2 ITEMP1 ITEMP2 ITEMP3 NEWPRIO ITEMP5 NEWLOCP1 RUPTREG2 KEYTEMP1 FLAGFILL INTB15P BLANKRET WDRET ADDRWD CHAR FIXLOC SGNON DECTEM SFTEMP1 SFTEMP2 SIGNRET INDEXLOC MPTEMP
000057 027340 000001 000075 000100 000103 000106 000111 000114 000117 000122 000125 000007 000130 000141 000144 000177 000246 000300 000307 000312 000315 000320 000323 000326 000331 000334 000337 000342 000345 000350 000353 000356 000357 000360 000360 000362 000363 000366 000370 000405 000411 000411 000412 000413 000414 000415 000417 000417 000420 000421 000422 000425 000432
MAXTASK MAXTIMEOUT TRECSZ WL_IN_taskPtr WL_AT_taskPtr WL_AT_loopCnt WL_ST_saveQ WL_ST_loopCnt WL_RM_saveQ WL_RM_loopCnt WL_IS_newAddr WL_IS_taskPtr2 JRECSZ MODE PUSHLOC JREC0 JREC3 JREC6 CHGJOB EX_JW_saveQ EX_JW_foundit EX_JW_fndIndx EX_AJ_jobPrio EX_AJ_findx EX_IN_jobPtr EX_IN_findx EX_MN_findx EX_RM_jobPtr2 EX_RM_retval EX_IS_newPrio EX_IS_saveQ EX_IS_loopCnt WAITEXIT WAITBANK RUPTSTOR ITEMP4 NEWLOC NEWJOB RUPTREG3 DSRUPTEM EMDOT DSEXIT INTBIT15 DECRET POLISH ERCNT OVFIND NOUNTEM SGNOFF HITEMIN LOWTEMIN BUF SWWORD DMPNTEMP
00000 7 01044 0 00000 2 00007 6 00010 1 00010 4 00010 7 00011 2 00011 5 00012 0 00012 3 00012 6 00001 5 00013 7 00014 2 00014 5 00021 4 00026 3 00000 1 00031 0 00031 3 00031 6 00032 1 00032 4 00032 7 00033 2 00033 5 00034 0 00034 3 00034 6 00035 1 00035 4 00035 6 00035 7 00036 0 00036 1 00036 2 00036 4 00036 7 00037 0 00040 5 00041 1 00041 2 00041 2 00041 4 00041 4 00041 6 00041 7 00042 0 00042 0 00042 1 00042 5 00042 5 00043 2
MAXVAL TSKTIME WL_taskList WL_IN_loopCnt WL_AT_newTime WL_T3_saveQ WL_ST_taskPtr WL_RT_saveQ WL_RM_taskPtr WL_RM_retval WL_IS_saveQ WL_IS_loopCnt EX_currentJob LOC PRIORITY JREC1 JREC4 EX_jobList KEEPJOB EX_JW_loopCnt EX_JW_jobPtr EX_AJ_saveQ EX_AJ_jobPtr EX_IN_saveQ EX_IN_recIndex EX_MN_runAddr EX_RM_saveQ EX_RM_savePtr EX_RM_field EX_IS_newPrioB EX_IS_jobPtr FLAGWRD5 EXECTEM1 EXECTEM2 WAITADR WAITTEMP ITEMP6 RUPTREG1 RUPTREG4 STATE STATEXIT EXITEM WRDRET _2122REG UPDATRET DECOUNT VBUF DISTEM NVTEMP CODE MIXTEMP BUF2 SWBIT DOTINC
037777 000000 000057 000077 000102 000105 000110 000113 000116 000121 000124 000127 000130 000140 000143 000162 000231 000300 000000 000311 000314 000317 000322 000325 000330 000333 000336 000341 000344 000347 000352 000355 000356 000357 000360 000361 000363 000365 000370 000371 000407 000411 000412 000412 000414 000414 000417 000417 000420 000421 000422 000430 000426 000433
DVSIGN DOTRET WDCNT MAXDVSW MIXBR DSREL IDADDTEM TEM4 FREERET SEPMNRET NNADTEM IDAD2TEM DEXDEX RTNSAVER NVWORD CADRFLSH FAILREG DSPCNT VERBREG YREG YREGLP LOTEMOUT REQRET NOUT MONSAVE1 NVQTEM CADRSTOR DSPTEM1 NORMTEM1 DSRUPTSW DK_IN_saveQ KP_MPAC REQ_Q SFRUTMIX_L GTSF_RET NVSUB_A FLASHRET SHORTMP_A ADDRWD1 KEYRET BJRET PJA BCA MBCA EXTENDER ERRUPT UPRUPT goER goUP NEG1 ONE FOUR SEVEN BIT15 BIT12 BIT9 BIT6 BIT3 LOW7 OCT1400 CLRMEM CLRMEM_VAL CLRMEM_WC goMAIN V37XEQ WL_tskLstStart WL_numTasks1 WL_maxTimeOut WAITLIST WL_AT_mkFirst WL_AT_done WL_RT_loop WL_RT_done WL_ST_setT3 WL_insert WL_IS_insRec WL_RM_loop EX_DUMMY_PRIO EX_jobRecSize EX_jobLstEnd1 EX_changeJob EX_MN_findJob EX_MN_runIt CHANG1 EX_MN_mvRec JOBWAKE EX_JW_bumpPtr
000433 000434 000434 000435 000435 000436 000437 000441 000441 000441 000443 000446 000437 000442 000452 000455 000460 000465 000470 000473 000476 000477 000502 000505 000510 000526 000531 000534 000534 000543 000546 000551 000554 000557 000562 000565 000570 000573 000576 000601 000604 000607 000612 000615 005777 002010 002024 002036 002043 002046 002051 002054 002057 002062 002065 002070 002073 002076 002101 002104 002107 002050 002123 002126 002153 002175 002200 002203 002232 002306 002343 002364 002414 002461 002473 002552 002603 002643 002646 002651 002654 002662 002720 002733 002757 003003 003041
ESCAPE DVNORMCT INREL POLYCNT TEM1 TEM2 TEM3 LSTPTR DSPWDRET TEM5 NNTYPTEM IDAD3TEM DEX1 TERM1TMP MARXNV CADRMARK MINDEX DSPCOUNT NOUNREG ZREG HITEMOUT MODREG LOADSTAT NOUNCADR MONSAVE2 NVBNKTEM DSPLIST DSPTEM2 OPTIONX T4RET LXCH_LPRET DPTEST_A SETNCADR_Q SFCONUM_L FR_RETQ ENDIDLE_L PASTE_TMP SHORTMP_OVFL MATH_Q SAVEQ PJBANK BCBANK MBCBANK DCBANK GOPROG DSRUPT endRUPT goDS ofbit NEG2 TWO FIVE TEN BIT14 BIT11 BIT8 BIT5 BIT2 bankAddr NOUTCON CLRMEM_CHK TIME3 V37BANK SLAP1 V37XEQC WL_tskLstEnd WL_maxVal WL_initWL WL_AT_noOvf WL_AT_loop WL_TIME3task WL_RT_runIt WL_schedTask WL_ST_noTask WL_IS_loop WL_IS_done WL_RM_done EX_SLEEP_PRIO EX_jobLstStart EX_numJobs EX_keepJob EX_MN_setFlg ENDOFJOB EX_MN_notBank EX_MN_loop3 EX_JW_loop EX_JW_done
00043 3 00043 4 00043 4 00043 5 00043 6 00043 7 00044 0 00044 1 00044 1 00044 2 00044 4 00044 7 00044 0 00043 0 00045 3 00045 6 00046 3 00046 6 00047 1 00047 4 00047 6 00050 0 00050 3 00050 6 00051 1 00052 7 00053 2 00053 7 00053 7 00054 4 00054 7 00055 2 00055 5 00056 0 00056 3 00056 6 00057 1 00057 4 00057 7 00060 2 00060 5 00061 0 00061 3 00061 6 00200 0 00201 4 00203 0 00203 7 00204 4 00204 7 00205 2 00205 5 00206 0 00206 3 00206 6 00207 1 00207 4 00207 7 00210 2 00210 5 00211 3 00003 7 00212 4 00212 6 00216 6 00217 6 00220 1 00220 4 00226 4 00231 1 00234 7 00241 1 00241 7 00246 6 00251 0 00256 2 00263 6 00264 4 00264 7 00265 2 00265 5 00267 7 00272 3 00275 0 00276 3 00301 5 00305 6
ENTRET ESCAPE2 MATINC DSPMMTEM POLYRET DSMAG COUNT RELRET SEPSCRET NOUNADD IDAD1TEM RUTMXTEM DEX2 RESTREG NVSAVE TEMPFLSH MMNUMBER DECBRNCH XREG XREGLP ZREGLP DSPLOCK CLPASS MONSAVE DSPTAB VERBSAVE EXTVRACT DSPTEMX MMTEMP DSPOUTRET LXCH_A DPTEST_Q ALLDC_OC_Q BLANKSUB_Q NVSUB_L NBSUBSY1_L NEWMODEA_Q SHORTMP_OVFH PRSHRTMP_Q BJBANK PJRET BCRET MBCRET DCRET T3RUPT KEYRUPT goT3 goKEY NEG0 ZERO THREE SIX ELEVEN BIT13 BIT10 BIT7 BIT4 BIT1 lowAddr POSMAX CLRMEM_WORD CLRMEM_BADDR SAMASK goMMchange WL_taskRecSize WL_numTasks WL_maxDelay WL_IN_loop WL_AT_chkOrder WL_AT_schTsk WL_runTasks TASKOVER WL_ST_loop WL_ST_done WL_IS_bumpPtr WL_remove EX_WAKE_PRIO EX_jobCurStart EX_jobLstEnd EX_numJobs1 EX_exec EX_MN_runJob JOBSLEEP EX_MN_saveIt EX_MN_done3 EX_JW_moveRec EX_JW_return
000433 000434 000435 000435 000436 000437 000440 000441 000441 000442 000445 000450 000441 000451 000454 000457 000464 000467 000472 000475 000477 000501 000504 000507 000512 000530 000533 000537 000542 000545 000550 000553 000556 000561 000564 000567 000572 000575 000600 000603 000606 000611 000614 000617 002004 002020 002034 002041 002045 002050 002053 002056 002061 002064 002067 002072 002075 002100 002103 002106 002116 000037 002125 002147 002174 002177 002202 002213 002270 002333 002362 002413 002436 002470 002541 002565 002642 002645 002650 002653 002656 002701 002725 002752 003002 003035 003074
SPVAC EX_SP_testFlg NOVAC EX_AJ_testFlg EX_IN_loop1 EX_IN_done EX_FI_bumpPtr EX_remove EX_RM_loop2 EX_RM_done3 dumJob2 DODXCHCALL DOBANKCALL DOPOSTJUMP DATACALL RELTAB11 DSPOFF DSPSCAN DSPLAY DSPOUTEXIT TPAGREE TPA_PZ0 TPA_MZ0 TPA_P1 TPA_P2 MAXPOS TPA_MPAC1 SHORTMP BANK4 BANK40_1 BANK7 BANK43_1 CHECKTAB FCADRMM1 NOV37MM CHARIN2 _89TEST ENDNMTST DECEND CRITCON INRELTAB NVCOM BOTHSGN P_ON SGNTAB CLEAR CLR5 _5BLANK1 BRNCHCON BANK40_2 ENTER ENTEXIT ENTPAS0 REQADD NEG5 LST2CON MIXNOUN REQDATX REQCOM PUTADD GOALMCYC DSPAB DSPB DSPCOM3 NDOMPTST DCTSTCYC COMPICK DSPDCGET GTSFOUTL SFOUTABR SETAUG DEGTAB READLO ENDRDLO SECON1 MINCON1 SEPMIN DSPDPDEC ABCLOAD PUTXY CLOAD VBSP2LD GOQ SFRET1 DISPLACE PUTDPCOM PUTCOM2
003075 003146 003162 003236 003266 003324 003376 003410 003446 003507 003517 003547 003611 003677 003742 004005 004012 004065 004103 004126 004150 004167 004220 004246 004304 004315 004320 004353 010000 012000 016000 020000 010005 010030 010046 012016 012065 012155 012176 012232 012245 012275 012315 012332 012364 012412 012461 012515 012537 012564 014002 000433 014040 014073 014126 014163 014237 014264 014277 014320 014340 014350 014363 014403 014427 014444 014477 014514 014550 014563 012572 012640 012653 012703 016041 016047 016074 012704 014600 014646 014707 014734 014761 015002 015022 015065 015111
EX_SP_loop1 EX_SP_done2 EX_AJ_loop1 EX_AJ_done2 EX_IN_loop2 EX_findIns EX_FI_insRec EX_RM_loop1 EX_RM_done2 dumJob NOTACTLT DC_NOTBANK MYBANKCALL BANKJUMP DODATACALL DKTESTINIT T4PROG TABLNTH DSPOUT CHRPRIO TPA_SGN0 TPA_PZ0FIX TPA_MZ0FIX TPA_M1 TPA_M2 MAXNEG TPA_FIXM DMP BANK04_1 BANK6 BANK42_1 V37 AGAINMM PREMM1 BANK04_2 ELRCODE1 NUM ENDNUM PDECSGN DECON CCSHOLE NOUN PIXCLPAS SGNCOM SIGNTEST CLPASHI LEGALTST SINBLANK _2BLANK NVSUBR ENTPASHI MMADREF TESTVB USEADD INTMCTBS VBFANDIR DPTEST REQDATY ENDRQDAT UPDATVB GODSPALM DSPA DSPC COMPTEST DCOMPTST NOUNTEST GETCOMP DSPDCPUT DSPDCEND BANK41_2 FIXRANGE ARTOUTSF READLO1 BANK40_3 SECON2 HRCON1 ENDSPMIN ENDDPDEC PUTXYZ ALOAD LOADLV VBSP3LD SFRUTNOR SFCONUM CONUMNOR PUTNORM GTSFINLC
00311 0 00315 6 00320 0 00324 6 00330 4 00333 2 00340 5 00342 0 00346 5 00351 0 00352 5 00356 1 00362 4 00371 2 00376 3 00400 6 00404 7 00407 2 00411 6 00413 1 00415 2 00420 0 00423 1 00426 2 00430 6 00431 6 00432 1 00437 4 01000 0 01400 0 01600 0 01000 0 01000 7 01003 7 01004 7 01206 2 01210 1 01217 0 01222 0 01223 7 01227 1 01230 6 01232 1 01234 2 01236 7 01243 1 01246 4 01253 1 01254 0 01400 0 01401 2 01403 6 01404 4 01411 7 01412 7 01416 4 01424 0 01427 0 01430 5 01432 7 01434 1 01435 5 01437 0 01441 4 01443 0 01445 3 01450 1 01452 4 01455 1 01460 0 01260 3 01264 4 01266 5 01270 4 01604 3 01605 1 01611 3 01272 6 01461 4 01466 3 01472 3 01473 5 01476 2 01500 3 01502 5 01507 7 01511 3
EX_SP_done1 FINDVAC EX_AJ_done1 EX_initEX EX_IN_loop3 EX_FI_loop EX_FI_done EX_RM_done1 EX_RM_loop3 dumJob1 DXCHJUMP BANKCALL POSTJUMP DOBANKJUMP RELTAB DK_initDK DSPOUTSR _120MRUPT NODSPOUT KEYPROG TPA_P0 TPA_M0 TPA_SGN1 TPA_SGN2 TPA_P3 TPA_MPAC0 TPA_FIXP BANKFF_1 BANK5 BANK41_1 BANK10 V37BAD V37NONO EPREMM1 CHARIN ENTERJMP DECTOBIN ENDALL MORNUM GETINREL VERB NEGSGN POSGN M_ON SGNTST1 CLEAR1 _5BLANK DOUBLK BLANKCON LOADLV1 ACCEPTWD LOWVERB TESTNN LODNNLOC VERBFAN VERBTAB DPTEST1 REQDATZ UPDATNN UPDAT1 DSPABC DSPCOM1 DSPCOM2 COMPTST1 DECTEST TSTFORDP DECDSP DSPSFNOR DECDSP3 DEGOUTSF DEGCOM SCOUTEND RDLONOR HMSOUT MINCON2 SEPSECNR BANK42_2 BANK40_4 ABLOAD BLOAD VBSP1LD ALLDC_OC SFRUTMIX SFRET PUTCOM PUTNORM_1 PUTDECSF
003127 003161 003217 003252 003307 003347 003405 003437 003472 003514 003526 003565 003653 003733 003772 004007 004057 004074 004126 004132 004157 004210 004241 004277 004310 004317 004337 004435 012000 014000 020000 010002 010026 010046 012000 012063 012137 012174 012227 012241 012272 012312 012326 012353 012404 012454 012473 012534 012563 014001 014032 014037 014054 014124 014151 014167 014262 014274 014307 014335 014343 014361 014375 014417 014435 014462 014510 014546 014560 012564 012616 012651 012701 016000 016045 016053 016114 012727 014635 014673 014733 014736 014770 015020 015031 015111 015114
PUTSFNOR BANK41_3 SIGNFIX SGNTO1 ARTHINSF _2RNDEND BANK42_3 BIT15_14 KILLMON ENDMONDO MONBUSY PASTEVB MID7 ENDSPF DSPRND DSPDCWD1 DECROUND DSP2DEC VNDSPCON DSPOCTWD DSPLW BANK41_6 DFRNT _11DSPIN PREDSPAL MONADR ALMCYCLE MMCHANG VBRQEXEC SETVAC BANK41_7 VBRESEQ UNSUSPEN NVMONOPT NVSRRBNK BLANKDSP NVSUB1 ENDNVSB1 ENDIDLE ISLIST_P0 BSUB1ADDR DSPMM BLNKSUB1 RECALTST RECAL3 BANK40_8a SETEBANK R3D1 SLEFT5 HI5 TCFINDVAC LOW8 ND1 OUT1 FALTOF RELDSPOR DOSHRTMP FLSHTAB NVSUBSY1 RELDSP NEWMODEA PINBRNCH TSTLTS1 TSTCON1 TSTLTS3 TSTAB ERCOM BANK40_10 LODNLV SFCOM NNTYPTAB IDADDTAB GOEXTVB GOPIN P00 prio1 restart1_addr P01_restart tcadr2 P02_wait nvcode3 P03 P03_yield nvcode4 mon_option P78 Q
015125 015146 012750 012766 012776 013024 016114 015155 015232 015273 015276 004435 004473 015307 013046 013071 013117 013131 013155 015310 015341 015356 013226 013253 013265 013313 004474 015356 015420 015444 015453 013325 013342 004507 004531 015453 015505 015571 004541 004560 004612 010047 013350 013413 013444 013452 004633 004637 004656 004666 004671 004673 004676 000011 004706 004720 004754 005000 013452 005003 005036 005067 015600 015623 015631 013467 013505 013521 016156 016173 016354 016640 020000 020077 022000 022011 022020 022024 022035 022047 022063 022066 022107 022123 022126 022142 000001
PUTDCSF2 DEGINSF ENDSCALE DEGCON1 BINROUND TESTOFUF MONITOR MONIT2 MONDEL MONREF LODSAMPT PASTEOPT BANKFF_2 BANK41_5 DPOSMAX TRACE1 DSPDECNR END2DEC GOVNUPDT WDAGAIN DSPMSK DSPIN DSLV DSPOCTIN DSPALARM NVSBENDL ENDALM MODROUTR REQEX1 VBRQWAIT VBPROC VBRELDSP BANK40_8 NVSBCOM NVSUBEND INCR_NOUT_RET ENTSET BANK41_8 ENDINST DSPABORT BS_SUPDXCHZ ENDSPMM TESTBIT RECAL1 DOTERM SETNCADR R1D1 RIGHT5 LOW5 TCNOVAC LOW11 LOW10 MD1 DSALMOUT FALTOR TPSL1 FLASHON NVSUBUSY ENDNVBSY RELDSP2 POODOO BANKFF_6 FULLDSP SHOLTS BANK41_9 ERMINUS NOTBIT12 LODNNTAB MIXCON GTSFIN SFINTAB RUTMXTAB LST2FAN BANK43_2 time1 job1 tcadr1 nvcode2 P02 P02_pwd restart3_addr P03_restart P03_pwd restart4_addr P04 P79 QRUPT
01512 6 01272 7 01276 2 01277 2 01301 1 01302 5 01514 6 01516 4 01523 6 01527 4 01530 0 00445 1 00447 4 01531 0 01306 2 01307 4 01312 0 01314 3 01315 6 01531 7 00205 7 01316 1 01324 5 01326 1 01326 7 01331 4 00450 2 01000 0 01542 5 01544 6 01331 5 01332 7 01335 0 00451 6 00453 2 01546 3 01554 2 01557 2 00455 3 00456 3 00461 3 01005 6 01337 3 01341 6 01344 6 00461 6 00463 5 00464 0 00466 4 00466 7 00467 2 00467 4 00467 7 00001 1 00471 2 00472 1 00476 0 00500 1 01346 1 00501 7 00505 0 00507 0 01562 1 01562 4 01564 4 01347 7 01351 7 01611 4 01616 1 01617 6 01652 0 01712 4 02000 2 02010 1 02200 4 02201 2 02202 1 02203 3 02203 6 02205 5 02206 4 02207 0 02211 5 02212 4 02212 7 02214 7 00002 7
SFINTABR DEGINSF2 NEG180 DEGCON2 _2ROUND BANK40_5 MONIT1 MONREQ MONDO MONBACK BANK41_4 ENDPASTE DSPFMEM DSPSIGN DSPDECWD TRACE1S DSPDC2NR DSPDECVN BANK40_6 OCTBACK DSP2BIT DSPIN1 DSMSK ENDSPOCT CHARALRM BANK40_7 BANKFF_3 REQMM REQUESTC ENDRQWT VBTERM TSTLTS4 NVSUB NVSUBCOM BANKFF_4 INCR_NOUT NVSUB2 KILMONON ISCADR_P0 BLANKSUB BANKFF_5 BANK04_3 DSPMMJB RECAL2 DOPROC SETNADD R2D1 LEFT5 MID5 TCWAIT B12M1 VD1 BINCON FALTON RELDSPON PRSHRTMP FLASHOFF BANKFF_5a BANK40_9 RELDSP1 NOTPALT VBTSTLTS FULLDSP1 TSTLTS2 ERROR ERPLUS ERCON LODMIXNN GTSFOUT NNADTAB SFOUTAB BANK42_4 ALM_END BANK11 task1 nvcode1 P01 restart2_addr P02_restart P02_ter tcadr3 P03_wait P03_ter tcadr4 P04_restart ARUPT TIME1
015131 012740 012764 012774 013014 013031 015150 015215 015237 015275 015301 004472 015301 013031 013064 013105 013124 013144 013161 015337 015344 013206 013247 013264 013307 013315 004503 015404 015431 015452 013323 013334 004503 004524 004536 015501 015543 004536 004554 004565 004616 010057 013400 013427 013450 004625 004636 004647 004665 004670 004672 004675 004700 004701 004713 004740 004770 005003 013462 005026 005066 015572 015622 015625 013462 013502 013520 016135 016162 016210 016570 017220 020076 022000 022005 022017 022022 022034 022040 022060 022065 022077 022120 022125 022131 000026 000036
TIME2 TIME4 LP SR
A IN0 CYL
Abstract
This report describes my successful project to build a working reproduction of the 1964 prototype for the Block I Apollo Guidance Computer. The AGC is the flight computer for the Ap ollo m oon lan din gs, and is the wo rlds first in tegra ted c ircuit com pu ter. I built it in my ba sem ent. It took me 4 yea rs. If you like, you can build one too. It will take you less time, and yours will be better than mine. I docum ented m y project in 9 separate .pdf files: Part 1 Part 2 Part 3 Part 4 Part 5 Part 6 Part 7 Part 8 O v ervie w : Introdu ces the p roject. CTL Module: Design and construction of the control module. PROC M odule: Design and construction of the processing (CPU) modu le. MEM Module: Design and construction of the mem ory module. IO Module: Design and construction of the display/keyboard (DSKY) m odule. Assem bler: A cross-a ssem bler for AG C softw are dev elopm ent. C+ + S imu lator: A low-level simulator that runs assemb led AGC code. Flight Software: My translation of portions of the COLOSSUS 249 flight software. Test & Che ckou t: A suite of test programs in AG C assembly langu age.
Part 9
Overview
A suite of test and checkout programs were coded to verify the operation of the AGC simulators and the hardware AGC.
TECO1
First test and checkout program for the Block 1 AGC. Tests basic instructions: TC, CCS, INDEX, XCH, CS, TS, AD, MA SK. Enters an infinite loop at the end of the test. The A register contains the cod e for the test that failed, or the PAS S code if all tests succeeded. See test codes (in octal) below. Code 01 02 03 04 05 06 07 10 12345 Interpretation TC check failed CCS check failed INDEX check failed XCH check failed CS check failed TS check failed AD check failed MAS K check failed PASSED all checks
TECO2
Second test and checkout program for the Block 1 AGC. Tests extracode instructions: MP, DV, SU. Enters an infinite loop at the end of the test. The A register contains the code for the test that failed, or the PASS code if all tests succeeded. See test codes (in octal) below. Code 01 02 03 12345 Interpretation MP check failed DV check failed SU check failed PASSED all checks
TECO3
Third test and checkout program for the Block 1 AGC. Tests editing registers: CYR, SR, CYL, SL. Enters an infinite loop at the end of the test. The A register contains the code for the test that failed, or the PASS code if all tests succeeded. See test codes (in octal) below. Code 01 02 03 04 12345 Interpretation CYR check failed SR check failed CYL check failed SL check failed PASSED all checks
TECO5
Exercises AGC interrupts by initializing 4 counters, and then entering into a loop that increments the first counter on each iteration. Each of the other 3 counters is assigned to an interrupt and is incremented in the interrupt service routine for that interrupt: KEYRUPT, T3R UPT , and D SR UPT . Interrupts a re inhib ited an d en abled durin g each iteration o f the m ain loop with INHINT and RELINT instructions, and are automatically inhibited during part of each iteration by an overflow condition in register A.
TECO_STBY
An extrem ely sim ple p rogra m for testin g th e ST AN DB Y fun ction . STA ND BY is disabled fo r 2 NOOP instructions and then is enabled. After that, the program infinitely loops (TC TRAP) with STANDBY enabled.
05777
5777
47777 0 OVFCNTR
ORG DS EQU
; ---------------------------------------------; ERASEABLE MEMORY -- DATA SEGMENT 00100 00101 00102 00103 0100 0101 0102 0103 00000 1 curtest 00000 1 savQ ; CCS test 00000 1 CCSk ; INDEX test 00000 1 INDXval ORG DS DS DS DS %100 START %0 %0 0 ; start of data area ; current test
1 0 1 0
; XCH test ; pre-set in erasable memory because we don't ; want to use XCH to initialize them prior to testing XCH. XCHkP0 DS +0 XCHkM0 DS -0 XCHkalt1 DS %52525 ; alternating bit pattern 1 XCHkalt2 DS %25252 ; alternating bit pattern 2 DS DS -0 -0
02000
2000 0
02004 02005 02006 02007 02010 02011 02012 02013 02014 02015 02016 02017 02020 02021 02022 02023
2004 2005 2006 2007 2010 2011 2012 2013 2014 2015 2016 2017 2020 2021 2022 2023
5 3 5 0 5 3 5 0 5 3 5 0 5 3 5 0
0,0026 0,0001 0,0027 1,2717 0,0026 0,0001 0,0027 1,2717 0,0026 0,0001 0,0027 1,2717 0,0026 0,0001 0,0027 1,2717
0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
; interrupt service entry points ORG T3RUPT TS ARUPT XCH Q TS QRUPT TC goT3 ORG TS XCH TS TC ORG TS XCH TS TC ORG TS XCH TS TC ORG TS XCH TS TC ERRUPT ARUPT Q QRUPT goER DSRUPT ARUPT Q QRUPT goDS KEYRUPT ARUPT Q QRUPT goKEY UPRUPT ARUPT Q QRUPT goUP
5 3 5 0
0 0 1 1
; MAIN PROGRAM goMAIN 02030 02031 02032 02033 02034 02035 02036 02037 02040 02041 02042 02043 02044 02045 2030 2 2031 0 2032 2033 2034 2035 2036 2037 2040 2041 0 0 0 0 0 0 0 0 0,0000 0 1,2047 0 1,2054 1,2110 1,2244 1,2274 1,2400 1,2446 1,2573 1,2674 1 0 1 1 1 0 1 0 EQU INHINT TCR * ; disable interrupts begin
; Test basic instructions. TCR chkTC TCR chkCCS TCR chkINDEX TCR chkXCH TCR chkCS TCR chkTS TCR chkAD TCR chkMASK ; Passed all tests. TCR fail EQU XCH TS EQU TC finish * curtest curtest * end ; load last passed test into A
end 1,2045 1
; finished, TC trap
; ---------------------------------------------; INITIALIZE FOR START OF TESTING 02046 02047 02050 02051 2046 2047 3 2050 5 2051 0 00000 1 STRTcode begin 1,2046 1 0,0100 0 0,0000 0 ; ; ; ; ; ; 02052 02053 02054 02055 02056 02057 02060 02061 02062 02063 02064 02065 02066 02067 02070 02071 02072 2052 2053 2054 3 2055 5 2056 3 2057 5 2060 0 2061 0 2062 2063 2064 2065 2066 2067 4 6 1 0 0 0 DS EQU XCH TS RETURN START * STRTcode curtest
---------------------------------------------TEST TC INSTRUCTION SUBROUTINE L: TC K Verifies the following: - Set C(Q) = TC L+1 - Take next instruction from K, and proceed from there. DS DS EQU XCH TS CAF TS TCtst TCret1 * Q savQ TCcode curtest *+2 fail address in Q Q Qtest A fail fail fail ; code for this test ; expected return address
; save return address ; set test code to this test ; make test jump ; failed to jump
; attempt a jump 1,2062 1 TC 1,2043 1 TCret1 TC 0,0001 1,2053 0,0000 1,2043 1,2043 1,2043 1 0 0 1 1 1 ; verify correct return CS AD CCS TC TC TC
; ; ; ; ;
put (-Q) + val2 in A A = DABS >0 (Q < Qtest) +0 (never happens) <0 (Q > Qtest)
; passed the test XCH savQ TS Q ; restore return address RETURN ; ---------------------------------------------; TEST CCS INSTRUCTION SUBROUTINE ; L: CCS K ; Verifies the following: ; - take next instruction from L+n and proceed from there, where: ; -- n = 1 if C(K) > 0
; ; ; ; ; ; 02073 02074 02075 02076 02077 02100 02101 02102 02103 02104 02105 02106 02107 02110 02111 02112 02113 2073 2074 2075 2076 2077 2100 2101 2102 2103 2104 2105 2106 2107 2110 3 2111 5 2112 3 2113 5
-- n = 2 if C(K) = +0 -- n = 3 if C(K) < 0 -- n = 4 if C(K) = -0 - set C(A) = DABS[C(K)], where DABS (diminished abs value): -- DABS(a) = abs(a) - 1, if abs(a) > 1 -- DABS(a) = +0, if abs(a) <= 1 CCStst -2 -1 -0 +0 +1 +2 1 0 0 0 0 1 * Q savQ CCScode curtest ; ; ; ; ; ; for for for for for for K=-2, K=-1, K=-0, K=+0, K=+1, K=+2, DABS DABS DABS DABS DABS DABS = = = = = = +1 +0 +0 +0 +0 +1 ; code for this test
00002 0 CCScode DS ; test values (K) 77775 1 CCSkM2 DS 77776 1 CCSkM1 DS 77777 0 CCSkM0 DS 00000 1 CCSkP0 DS 00001 0 CCSkP1 DS 00002 0 CCSkP2 DS 00001 00000 00000 00000 00000 00001 0 1 1 1 1 0 ; expected DABS values CCSdM2 DS CCSdM1 DS CCSdM0 DS CCSdP0 DS CCSdP1 DS CCSdP2 DS chkCCS 0,0001 0 0,0101 1 1,2073 1 0,0100 0 EQU XCH TS CAF TS
02114 02115 02116 02117 02120 02121 02122 02123 02124 02125 02126 02127 02130
2114 2115 2116 2117 2120 2121 2122 2123 2124 2125 2126 2127 2130
3 5 1 0 0 0 0 4 6 1 0 0 0
1,2074 0,0102 0,0102 1,2043 1,2043 1,2123 1,2043 0,0000 1,2102 0,0000 1,2043 1,2043 1,2043
0 1 0 1 1 0 1 0 0 0 1 1 1
; set K to -2 and execute CCS: ; check for correct branch CAF CCSkM2 ; set K = -2 TS CCSk CCS CCSk ; A = DABS[C(K)] TC fail ; K > 0 TC fail ; K= +0 TC *+2 ; K < 0 TC fail ; K= -0 ; check for correct DABS in A (for K=-2, it should be 1) COM ; 1's compliment of A AD CCSdM2 ; put (-A) + expected value in A CCS A ; A = DABS TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; set K to -1 and execute CCS: ; check for correct branch CAF CCSkM1 ; set K = -1 TS CCSk CCS CCSk ; A = DABS[C(K)] TC fail ; K > 0 TC fail ; K= +0 TC *+2 ; K < 0 TC fail ; K= -0 ; check for correct DABS in A (for K=-1, it should be +0) COM ; 1's compliment of A AD CCSdM1 ; put (-A) + expected value in A CCS A ; A = DABS TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; set K to -0 and execute CCS: ; check for correct branch CAF CCSkM0 ; set K = -0 TS CCSk CCS CCSk ; A = DABS[C(K)] TC fail ; K > 0 TC fail ; K= +0 TC fail ; K < 0 ; check for correct DABS in A (for K=-0, it should be +0) COM ; 1's compliment of A AD CCSdM0 ; put (-A) + expected value in A
02131 02132 02133 02134 02135 02136 02137 02140 02141 02142 02143 02144 02145
2131 2132 2133 2134 2135 2136 2137 2140 2141 2142 2143 2144 2145
3 5 1 0 0 0 0 4 6 1 0 0 0
1,2075 0,0102 0,0102 1,2043 1,2043 1,2140 1,2043 0,0000 1,2103 0,0000 1,2043 1,2043 1,2043
1 1 0 1 1 0 1 0 1 0 1 1 1
3 5 1 0 0 0
1 1 0 1 1 1
2154 4 2155 6
0,0000 0 1,2104 0
1 0 0 0
0 1 1 1
CCS TC TC TC
; ; ; ;
02162 02163 02164 02165 02166 02167 02170 02171 02172 02173 02174 02175 02176
2162 2163 2164 2165 2166 2167 2170 2171 2172 2173 2174 2175 2176
3 5 1 0 0 0 0 4 6 1 0 0 0
1,2077 0,0102 0,0102 1,2043 1,2171 1,2043 1,2043 0,0000 1,2105 0,0000 1,2043 1,2043 1,2043
0 1 0 1 1 1 1 0 1 0 1 1 1
; set K to +0 and execute CCS: ; check for correct branch CAF CCSkP0 ; set K = +0 TS CCSk CCS CCSk ; A = DABS[C(K)] TC fail ; K > 0 TC *+3 ; K= +0 TC fail ; K < 0 TC fail ; K= -0 ; check for correct DABS in A (for K=+0, it should be +0) COM ; 1's compliment of A AD CCSdP0 ; put (-A) + expected value in A CCS A ; A = DABS TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; set K to +1 and execute CCS: ; check for correct branch CAF CCSkP1 ; set K = +1 TS CCSk CCS CCSk ; A = DABS[C(K)] TC *+4 ; K > 0 TC fail ; K= +0 TC fail ; K < 0 TC fail ; K= -0 ; check for correct DABS in A (for K=+1, it should be +0) COM ; 1's compliment of A AD CCSdP1 ; put (-A) + expected value in A CCS A ; A = DABS TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; set K to +2 and execute CCS: ; check for correct branch CAF CCSkP2 ; set K = +2 TS CCSk CCS CCSk ; A = DABS[C(K)] TC *+4 ; K > 0 TC fail ; K= +0 TC fail ; K < 0 TC fail ; K= -0 ; check for correct DABS in A (for K=+2, it should be +1) COM ; 1's compliment of A AD CCSdP2 ; put (-A) + expected value in A CCS A ; A = DABS TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; passed the test XCH savQ TS Q ; restore return address RETURN ; ---------------------------------------------; TEST INDEX INSTRUCTION SUBROUTINE ; L: INDEX K (where K != 0025) ; Verifies the following; ; - Use the sum of C(L+1) + C(K) as the next instruction ; -- just as if that sum had been taken from L+1. DS DS DS DS DS DS DS DS INDEXtst 5 0 1 2 3 4 5 ; code for this test ; somewhere in fixed memory ; base address for indexing
02177 02200 02201 02202 02203 02204 02205 02206 02207 02210 02211 02212 02213
2177 2200 2201 2202 2203 2204 2205 2206 2207 2210 2211 2212 2213
3 5 1 0 0 0 0 4 6 1 0 0 0
1,2100 0,0102 0,0102 1,2206 1,2043 1,2043 1,2043 0,0000 1,2106 0,0000 1,2043 1,2043 1,2043
1 1 0 1 1 1 1 0 1 0 1 1 1
02214 02215 02216 02217 02220 02221 02222 02223 02224 02225 02226 02227 02230 02231 02232 02233
2214 2215 2216 2217 2220 2221 2222 2223 2224 2225 2226 2227 2230
3 5 1 0 0 0 0 4 6 1 0 0 0
1,2101 0,0102 0,0102 1,2223 1,2043 1,2043 1,2043 0,0000 1,2107 0,0000 1,2043 1,2043 1,2043
0 1 0 0 1 1 1 0 0 0 1 1 1
00003 1 INDXcode 00005 1 INDXst 00000 00001 00002 00003 00004 00005 1 INDXbas 0 0 1 0 1
chkINDEX 02244 02245 02246 02247 2244 3 2245 5 2246 3 2247 5 0,0001 0 0,0101 1 1,2234 0 0,0100 0
; Decrementing loop ; - always executes at least once (tests at end of loop) ; - loops 'INDXst+1' times; decrements INDXval 02250 02251 2250 3 2251 5 1,2235 1 INDXlop 0,0103 0 XCH EQU TS INDXst * INDXval ; initialize loop counter
02252 02253 02254 02255 02256 02257 02260 02261 02262 02263 02264 02265 02266
; perform indexed CAF of values in INDXbas array; ; index values range from 5 to 0 0,0103 1 INDEX INDXval 1,2236 1 CAF INDXbas 0,0000 0,0103 0,0000 1,2043 1,2043 1,2043 0 0 0 1 1 1 ; verify value retrieved using INDEX matches expected value COM ; get -A AD INDXval ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) CCS TC INDXval INDXlop ; done? ; not yet
XCH savQ TS Q ; restore return address RETURN ---------------------------------------------TEST XCH INSTRUCTION SUBROUTINE L: XCH K Verifies the following: - set C(A) = b(K) - set C(K) = b(A) - take next instruction from L+1 XCHtst +0 -0 %52525 %25252 * Q savQ XCHcode curtest ; code for this test
00004 0 XCHcode DS ; XCH test values 00000 1 XCHfP0 DS 77777 0 XCHfM0 DS 52525 1 XCHfalt1 DS 25252 0 XCHfalt2 DS chkXCH 0,0001 0 0,0101 1 1,2267 0 0,0100 0 EQU XCH TS CAF TS
02300 02301 02302 02303 02304 02305 02306 02307 02310 02311 02312 02313 02314
2300 4 2301 3 2302 2303 2304 2305 2306 2307 2310 2311 2312 2313 2314 4 6 1 0 0 0 4 6 1 0 0
1,2270 1 0,0104 1 0,0000 1,2270 0,0000 1,2043 1,2043 1,2043 0,0104 1,2271 0,0000 1,2043 1,2043 0 0 0 1 1 1 0 1 0 1 1
; test - initial conditions: K=+0, A=-0 ; initialize A CS XCHfP0 ; exchange A and K XCH XCHkP0 ; test contents of A for expected value COM ; AD XCHfP0 ; CCS A ; TC fail ; TC fail ; TC fail ; ; test contents of K for expected value CS XCHkP0 ; AD XCHfM0 ; CCS A ; TC fail ; TC fail ;
get -A put (-A) + expected value in A A = DABS >0 (A < expected value) +0 <0 (A > expected value) get -A put (-A) + expected value in A A = DABS >0 (A < expected value) +0
02315
2315 0
1,2043 1
TC
fail
02316 02317 02320 02321 02322 02323 02324 02325 02326 02327 02330 02331 02332 02333
2316 4 2317 3 2320 2321 2322 2323 2324 2325 2326 2327 2330 2331 2332 2333 4 6 1 0 0 0 4 6 1 0 0 0
1,2271 0 0,0105 0 0,0000 1,2271 0,0000 1,2043 1,2043 1,2043 0,0105 1,2270 0,0000 1,2043 1,2043 1,2043 0 1 0 1 1 1 1 0 0 1 1 1
; test - initial conditions: K=-0, A=+0 ; initialize A CS XCHfM0 ; exchange A and K XCH XCHkM0 ; test contents of A for expected value COM ; AD XCHfM0 ; CCS A ; TC fail ; TC fail ; TC fail ; ; test contents of K for expected value CS XCHkM0 ; AD XCHfP0 ; CCS A ; TC fail ; TC fail ; TC fail ;
get -A put (-A) + expected value in A A = DABS >0 (A < expected value) +0 <0 (A > expected value) get -A put (-A) + expected value in A A = DABS >0 (A < expected value) +0 <0 (A > expected value)
02334 02335 02336 02337 02340 02341 02342 02343 02344 02345 02346 02347 02350 02351
2334 4 2335 3 2336 2337 2340 2341 2342 2343 2344 2345 2346 2347 2350 2351 4 6 1 0 0 0 4 6 1 0 0 0
1,2272 0 0,0106 0 0,0000 1,2272 0,0000 1,2043 1,2043 1,2043 0,0106 1,2273 0,0000 1,2043 1,2043 1,2043 0 1 0 1 1 1 1 0 0 1 1 1
; test - initial conditions: K=52525, A=25252 ; initialize A CS XCHfalt1 ; exchange A and K XCH XCHkalt1 ; test contents of A for expected value COM ; get -A AD XCHfalt1 ; put (-A) + expected value in A CCS A ; A = DABS TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; test contents of K for expected value CS XCHkalt1 ; get -A AD XCHfalt2 ; put (-A) + expected value in A CCS A ; A = DABS TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; test - initial conditions: K=25252, A=52525 ; initialize A CS XCHfalt2 ; exchange A and K XCH XCHkalt2 ; test contents of A for expected value COM ; get -A AD XCHfalt2 ; put (-A) + expected value in A CCS A ; A = DABS TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; test contents of K for expected value CS XCHkalt2 ; get -A AD XCHfalt1 ; put (-A) + expected value in A CCS A ; A = DABS TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; passed the test XCH TS RETURN ; ; ; ; ; ; savQ Q
02352 02353 02354 02355 02356 02357 02360 02361 02362 02363 02364 02365 02366 02367 02370 02371 02372
2352 4 2353 3 2354 2355 2356 2357 2360 2361 2362 2363 2364 2365 2366 2367 4 6 1 0 0 0 4 6 1 0 0 0
1,2273 1 0,0107 1 0,0000 1,2273 0,0000 1,2043 1,2043 1,2043 0,0107 1,2272 0,0000 1,2043 1,2043 1,2043 0 0 0 1 1 1 0 1 0 1 1 1
---------------------------------------------TEST CS INSTRUCTION SUBROUTINE L: CS K Verifies the following: - Set C(A) = -C(K) - Take next instruction from L+1 CStst ; code for this test
02373
2373
02374 02375 02376 02377 02400 02401 02402 02403 02404 02405 02406 02407 02410 02411 02412 02413 02414 02415 02416 02417 02420 02421 02422 02423 02424 02425 02426 02427 02430 02431 02432 02433 02434 02435 02436
2374 2375 2376 2377 2400 3 2401 5 2402 3 2403 5 2404 2405 2406 2407 2410 2411 2412 2413 2414 2415 2416 2417 2420 2421 2422 2423 2424 2425 2426 2427 2430 2431 2432 2433 4 6 1 0 0 0 4 6 1 0 0 0 4 6 1 0 0 0 4 6 1 0 0 0
1 0 1 0
0,0001 0 0,0101 1 1,2373 1 0,0100 0 1,2374 1,2374 0,0000 1,2043 1,2043 1,2043 1,2375 1,2375 0,0000 1,2043 1,2043 1,2043 1,2376 1,2376 0,0000 1,2043 1,2043 1,2043 1,2377 1,2377 0,0000 1,2043 1,2043 1,2043 1 0 0 1 1 1 0 1 0 1 1 1 0 1 0 1 1 1 1 0 0 1 1 1
; save return address ; set test code to this test ; ; ; ; ; ; ; ; ; ; ; ; load 1's comp of K into A put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value) load 1's comp of K into A put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value)
; clear and subtract +0 CS CSkP0 AD CSkP0 CCS A TC fail TC fail TC fail ; clear and subtract -0 CS CSkM0 AD CSkM0 CCS A TC fail TC fail TC fail
; clear and subtract alternating bit pattern %52525 CS CSkalt1 ; load 1's comp of K into A AD CSkalt1 ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; clear and subtract alternating bit pattern %25252 CS CSkalt2 ; load 1's comp of K into A AD CSkalt2 ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; passed the test XCH savQ TS Q ; restore return address RETURN ; ---------------------------------------------; TEST TS INSTRUCTION SUBROUTINE ; L; TS K ; Verifies the following: ; - Set C(K) = b(A) ; - If b(A) contains no overflow, ; -- C(A) = b(A); take next instruction from L+1 ; - If b(A) has positive overflow, C(A) = 000001; ; -- take next instruction from L+2 ; - If b(A) has negative overflow, C(A) = 177776; ; -- take next instruction from L+2 TScode TSone TSzero TSmzero TSmone TSkP1 TSkM1 chkTS DS DS DS DS DS DS DS EQU XCH TS CAF TS ; initialize TSk to -0 TStst +1 +0 -0 -1 %37777 %40000 * Q savQ TScode curtest ; code for this test
02437 02440 02441 02442 02443 02444 02445 02446 02447 02450 02451
2437 2440 2441 2442 2443 2444 2445 2446 3 2447 5 2450 3 2451 5
1 0 1 0 1 1 0
; TEST1: largest + num w/no ovf ; TEST2: largest - num w/no ovf
02452 02453 02454 02455 02456 02457 02460 02461 02462 02463 02464 02465 02466 02467 02470 02471 02472 02473 02474 02475 02476 02477 02500 02501 02502 02503 02504 02505 02506 02507 02510 02511 02512 02513 02514 02515 02516 02517 02520 02521 02522 02523 02524 02525 02526 02527 02530 02531 02532 02533 02534 02535 02536 02537 02540 02541 02542 02543 02544 02545
2452 3 2453 3 2454 2455 2456 2457 2460 2461 2462 2463 2464 2465 2466 2467 2470 2471 2472 2473 2474 2475 2476 2477 2500 2501 2502 2503 2504 2505 2506 2507 2510 2511 2512 2513 2514 2515 2516 2517 2520 2521 2522 2523 2524 2525 2526 2527 2530 2531 2532 2533 2534 2535 2536 2537 2540 2541 2542 2543 2544 2545 3 5 0 0 4 6 1 0 0 0 4 6 1 0 0 0 3 5 0 0 4 6 1 0 0 0 4 6 1 0 0 0 3 6 5 0 4 6 1 0 0 0 4 6 1 0 0 0 3 6 5 0 4 6 1 0 0 0
1,2442 1 0,0110 1 1,2444 0,0110 1,2460 1,2043 0,0000 1,2444 0,0000 1,2043 1,2043 1,2043 1,2444 0,0110 0,0000 1,2043 1,2043 1,2043 1,2445 0,0110 1,2500 1,2043 0,0000 1,2445 0,0000 1,2043 1,2043 1,2043 1,2445 0,0110 0,0000 1,2043 1,2043 1,2043 1,2444 1,2440 0,0110 1,2043 0,0000 1,2440 0,0000 1,2043 1,2043 1,2043 1,2441 0,0110 0,0000 1,2043 1,2043 1,2043 1,2445 1,2443 0,0110 1,2043 0,0000 1,2443 0,0000 1,2043 1,2043 1,2043 1 1 1 1 0 1 0 1 1 1 0 1 0 1 1 1 0 1 0 1 0 0 0 1 1 1 1 1 0 1 1 1 1 0 1 1 0 0 0 1 1 1 0 1 0 1 1 1 0 0 1 1 0 0 0 1 1 1
CAF XCH
TSmzero TSk
; TEST 1: store positive number, no overflow CAF TSkP1 TS TSk TC *+2 ; no overflow TC fail ; overflow ; verify C(A) = b(A) COM ; get -A AD TSkP1 ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; verify C(K) = b(A) CS TSkP1 ; get -expected value AD TSk ; put value + C(K) into A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; TEST 2: store negative number, no overflow CAF TSkM1 TS TSk TC *+2 ; no overflow TC fail ; overflow ; verify C(A) = b(A) COM ; get -A AD TSkM1 ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; verify C(K) = b(A) CS TSkM1 ; get -expected value AD TSk ; put value + C(K) into A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; TEST 3: store positive number, overflow CAF TSkP1 ; get largest positive number AD TSone ; make it overflow; A = neg ovf TS TSk ; store the positive overflow TC fail ; no overflow ; verify C(A) = 000001 COM ; get -A AD TSone ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; verify C(K) = positive overflow CS TSzero ; get -expected value AD TSk ; put value + C(K) into A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; TEST 4: store negative number, overflow CAF TSkM1 ; get largest negative number AD TSmone ; make it overflow; A = neg ovf TS TSk ; store the negative overflow TC fail ; no overflow ; verify C(A) = 177776 COM ; get -A AD TSmone ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; verify C(K) = negative overflow
4 6 1 0 0 0
0 1 0 1 1 1
CS AD CCS TC TC TC
; ; ; ; ; ;
get -expected value put value + C(K) into A compare >0 (A < expected value) +0 <0 (A > expected value)
XCH savQ TS Q ; restore return address RETURN ---------------------------------------------TEST AD INSTRUCTION SUBROUTINE L: AD K Verifies the following: - Set C(A) = b(A) + C(K) - Take next instruction from L+1 - if C(A) has positive overflow, -- increment overflow counter by 1 - if C(A) has negative overflow, -- decrement overflow counter by 1 DS DS DS DS DS DS DS DS DS DS DS DS EQU XCH TS CAF TS ADtst +0 1 -1 %25252 %12525 %37777 %12524 %52525 %65252 %40000 %65253 * Q savQ ADcode curtest ; code for this test
02557 02560 02561 02562 02563 02564 02565 02566 02567 02570 02571 02572 02573 02574 02575 02576
2557 2560 2561 2562 2563 2564 2565 2566 2567 2570 2571 2572 2573 3 2574 5 2575 3 2576 5
00007 00000 00001 77776 25252 12525 37777 12524 52525 65252 40000 65253
0 1 0 1 0 0 1 1 1 1 0 0
ADcode ADplus0 ADplus1 ADmin1 AD25252 AD12525 AD37777 AD12524 AD52525 AD65252 AD40000 AD65253 chkAD
; ; ; ; ; ; ; ;
+10922 decimal +5461 decimal largest positive number + overflow of %25252+%25252 -10922 decimal -5461 decimal largest negative number neg overflow of %52525+65252
; TEST1: sum positive, no overflow ; add: %25252 + %12525 = %37777 (sign + 14 magnitude) CAF AD25252 AD AD12525 ; verify C(A) = %37777 COM ; get -A AD AD37777 ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; TEST2: sum negative, no overflow (sign + 14 magnitude) ; add: %52525 + %65252 = %40000 CAF AD52525 AD AD65252 ; verify C(A) = %40000 COM ; get -A AD AD40000 ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; TEST3: sum positive, overflow ; initialize overflow counter and positive overflow storage CAF ADplus0 TS OVFCNTR TS ADk ; add: %25252 + %25252 = %52524 (sign + 14 magnitude) CAF AD25252 AD AD25252 TS ADk ; store positive overflow
02625 02626 02627 02630 02631 02632 02633 02634 02635 02636 02637 02640 02641 02642 02643 02644 02645 02646 02647 02650 02651 02652 02653 02654 02655 02656 02657 02660 02661 02662 02663 02664 02665 02666 02667
2625 0 2626 2627 2630 2631 2632 2633 2634 2635 2636 2637 2640 2641 4 6 1 0 0 0 4 6 1 0 0 0
1,2043 1 0,0111 1,2566 0,0000 1,2043 1,2043 1,2043 0,0034 1,2561 0,0000 1,2043 1,2043 1,2043 1 0 0 1 1 1 1 1 0 1 1 1
TC fail ; verify ADk = %12524 CS ADk AD AD12524 CCS A TC fail TC fail TC fail ; verify overflow counter =%00001 CS OVFCNTR AD ADplus1 CCS A TC fail TC fail TC fail
; ; ; ; ; ; ; ; ; ; ; ;
get -A put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value) get -A put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value)
2642 3 2643 5 2644 5 2645 2646 2647 2650 2651 2652 2653 2654 2655 2656 2657 2660 2661 2662 2663 2664 3 6 5 0 4 6 1 0 0 0 4 6 1 0 0 0
1,2560 0 0,0034 0 0,0111 0 1,2567 1,2567 0,0111 1,2043 0,0111 1,2572 0,0000 1,2043 1,2043 1,2043 0,0034 1,2562 0,0000 1,2043 1,2043 1,2043 1 1 0 1 1 0 0 1 1 1 1 1 0 1 1 1
; TEST4: sum negative, overflow CAF ADplus0 TS OVFCNTR TS ADk ; add: %52525 + %52525 = %25253 (sign + 14 magnitude) CAF AD52525 AD AD52525 TS ADk ; store negative overflow TC fail ; verify ADk = %65253 CS ADk ; get -A AD AD65253 ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; verify overflow counter =%77776 CS OVFCNTR ; get -A AD ADmin1 ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) XCH savQ TS Q ; restore return address RETURN ---------------------------------------------TEST MASK INSTRUCTION SUBROUTINE L: MASK K Verifies the following: - Set C(A) = b(A) & C(K) DS DS DS DS EQU XCH TS MASKtst %46314 %25252 %04210 * Q savQ ; code for this test ; expected result: MASK1 & MASK2
02670 02671 02672 02673 02674 02675 02676 02677 02700 02701 02702 02703 02704 02705 02706 02707 02710 02711 02712
2670 2671 2672 2673 2674 3 2675 5 2676 3 2677 7 2700 2701 2702 2703 2704 2705 4 6 1 0 0 0
0 0 0 0
0,0001 0 0,0101 1 1,2671 0 1,2672 1 0,0000 1,2673 0,0000 1,2043 1,2043 1,2043 0 1 0 1 1 1
; perform logical and of MASK1 and MASK2 CAF MASK1 MASK MASK2 ; verify C(A) = b(A) & C(K) COM ; get -A AD MASKval ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) CAF TS ; passed the test XCH TS RETURN MASKcode curtest savQ Q ; set test code to this test
; ---------------------------------------------; PASSED ALL TESTS! 02713 02714 02715 02716 2713 2714 3 2715 5 2716 0 12345 0 PASScode finish 1,2713 0 0,0100 0 0,0000 0 DS EQU CAF TS RETURN PASS * PASScode curtest
; ---------------------------------------------; INTERRUPT SERVICE ROUTINE goT3 goER goDS goKEY goUP endRUPT 02717 02720 02721 02722 2717 2720 2721 2722 3 5 3 2 0,0027 0,0001 0,0026 0,0000 1 0 0 1 EQU EQU EQU EQU EQU EQU XCH TS XCH RESUME * * * * * * QRUPT Q ARUPT
Assembly complete. Errors = 0 Symbol table: START INDEXtst TStst PASS curtest INDXval XCHkalt1 ADk ERRUPT UPRUPT end TCcode TCret1 CCSkM1 CCSkP1 CCSdM1 CCSdP1 INDXcode chkINDEX XCHfP0 XCHfalt2 CSkP0 CSkalt2 TSone TSmone chkTS ADplus1 AD12525 AD52525 AD65253 MASK1 chkMASK goT3 goKEY ARUPT A 000000 000003 000006 012345 000100 000103 000106 000111 002010 002024 002045 002052 002061 002075 002100 002103 002106 002234 002244 002270 002273 002374 002377 002440 002443 002446 002561 002564 002567 002572 002671 002674 002717 002717 000026 000000 TCtst XCHtst ADtst EXTENDER savQ XCHkP0 XCHkalt2 GOPROG DSRUPT goMAIN STRTcode Qtest CCScode CCSkM0 CCSkP2 CCSdM0 CCSdP2 INDXst INDXlop XCHfM0 chkXCH CSkM0 chkCS TSzero TSkP1 ADcode ADmin1 AD37777 AD65252 chkAD MASK2 PASScode goER goUP Q 000001 000004 000007 005777 000101 000104 000107 002000 002014 002030 002046 002053 002073 002076 002101 002104 002107 002235 002251 002271 002274 002375 002400 002441 002444 002557 002562 002565 002570 002573 002672 002713 002717 002717 000001 CCStst CStst MASKtst OVFCNTR CCSk XCHkM0 TSk T3RUPT KEYRUPT fail begin chkTC CCSkM2 CCSkP0 CCSdM2 CCSdP0 chkCCS INDXbas XCHcode XCHfalt1 CScode CSkalt1 TScode TSmzero TSkM1 ADplus0 AD25252 AD12524 AD40000 MASKcode MASKval finish goDS endRUPT QRUPT 000002 000005 000010 000034 000102 000105 000110 002004 002020 002043 002047 002054 002074 002077 002102 002105 002110 002236 002267 002272 002373 002376 002437 002442 002445 002560 002563 002566 002571 002670 002673 002714 002717 002717 000027
%00 %01 %02 %03 ; MP check failed ; DV check failed ; SU check failed
PASS EQU %12345 ; PASSED all checks ; ---------------------------------------------05777 5777 47777 0 ORG DS EXTENDER %47777 ; needed for EXTEND
OVFCNTR
EQU
%00034
; overflow counter
; ---------------------------------------------; ERASEABLE MEMORY -- DATA SEGMENT 00100 00101 00102 00103 00104 00105 00106 00107 0100 0101 0102 0103 0104 0105 0106 0107 00000 1 curtest 00000 1 savQ ; MP test 00000 1 MPindex 00000 1 MPXTND ; DV test 00000 1 DVsavA 00000 1 DVindex 00000 1 DVXTND ; SU test 77777 0 SUk ORG DS DS DS DS DS DS DS DS %100 START %0 %0 %0 %0 %0 %0 -0 ; start of data area ; current test
; indexed extend
; indexed extend
02000
2000 0
02004 02005 02006 02007 02010 02011 02012 02013 02014 02015 02016 02017 02020 02021 02022 02023
2004 2005 2006 2007 2010 2011 2012 2013 2014 2015 2016 2017 2020 2021 2022 2023
5 3 5 0 5 3 5 0 5 3 5 0 5 3 5 0
0,0026 0,0001 0,0027 1,2742 0,0026 0,0001 0,0027 1,2742 0,0026 0,0001 0,0027 1,2742 0,0026 0,0001 0,0027 1,2742
0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
; interrupt service entry points ORG T3RUPT TS ARUPT XCH Q TS QRUPT TC goT3 ORG TS XCH TS TC ORG TS XCH TS TC ORG TS XCH TS TC ORG TS XCH TS TC ERRUPT ARUPT Q QRUPT goER DSRUPT ARUPT Q QRUPT goDS KEYRUPT ARUPT Q QRUPT goKEY UPRUPT ARUPT Q QRUPT goUP
5 3 5 0
0 0 1 1
; ---------------------------------------------; FIXED MEMORY -- SHARED DATA SEGMENT ; ---------------------------------------------; MAIN PROGRAM goMAIN 02030 02031 02032 02033 02034 2030 2 2031 0 2032 0 2033 0 2034 0 0,0000 0 1,2042 0 1,2247 1 1,2551 1 1,2635 0 EQU INHINT TCR * ; disable interrupts begin
end 1,2040 1
; finished, TC trap
; ---------------------------------------------; INITIALIZE FOR START OF TESTING 02041 02042 02043 02044 2041 2042 3 2043 5 2044 0 00000 1 STRTcode begin 1,2041 0 0,0100 0 0,0000 0 ; ; ; ; ; ; 02045 2045 DS EQU XCH TS RETURN START * STRTcode curtest
---------------------------------------------TEST MP INSTRUCTION SUBROUTINE L: MP K Verifies the following - Set C(A,LP) = b(A) * C(K) - Take next instruction from L+1 DS MPtst ; code for this test
00001 0 MPcode
02046
2046
31
02047 02050 02051 02052 02053 02054 02055 02056 02057 02060 02061 02062 02063 02064 02065 02066 02067 02070 02071 02072 02073 02074 02075 02076 02077 02100 02101 02102 02103 02104 02105 02106
2047 2050 2051 2052 2053 2054 2055 2056 2057 2060 2061 2062 2063 2064 2065 2066 2067 2070 2071 2072 2073 2074 2075 2076 2077 2100 2101 2102 2103 2104 2105 2106
37777 37777 40000 40000 00000 00000 77777 77777 00007 00021 00035 00051 00065 00103 00117 00141 00153 00177 00375 00305 00655 00537 02455 02053 11151 07025 20032 17065 30273 26355 37553 36014
1 1 0 0 1 1 0 0 0 1 1 0 1 0 0 0 0 0 0 1 1 0 1 0 1 1 1 1 1 0 0 1
; C(A) test values mp1 EQU * ; check boundary conditions DS %37777 ; check DS %37777 ; check DS %40000 ; check DS %40000 ; check DS %00000 ; check DS %00000 ; check DS %77777 ; check DS %77777 ; check ; randomly selected checks (one word product) DS %00007 ; check DS %00021 ; check DS %00035 ; check DS %00051 ; check DS %00065 ; check DS %00103 ; check DS %00117 ; check DS %00141 ; check DS %00153 ; check DS %00177 ; check ; randomly selected checks (two word product) DS %00375 ; check DS %00305 ; check DS %00655 ; check DS %00537 ; check DS %02455 ; check DS %02053 ; check DS %11151 ; check DS %07025 ; check DS %20032 ; check DS %17065 ; check DS %30273 ; check DS %26355 ; check DS %37553 ; check DS %36014 ; check
#00 #01 #02 #03 #04 #05 #06 #07 #08 #09 #10 #11 #12 #13 #14 #15 #16 #17 #18 #19 #20 #21 #22 #23 #24 #25 #26 #27 #28 #29 #30 #31
(+16383 * (+16383 * (-16383 * (-16383 * (+0 * +0) (+0 * -0) (-0 * +0) (-0 * -0)
(7 * 17) (17 * 7) (29 * 41) (41 * 29) (53 * 67) (67 * 53) (79 * 97) (97 * 79) (107 * 127) (127 * 107) (253 * 197) (197 * 253) (429 * 351) (351 * 429) (1325 * 1067) (1067 * 1325) (4713 * 3605) (3605 * 4713) (8218 * 7733) (7733 * 8218) (12475 * 11501) (11501 * 12475) (16235 * 15372) (15372 * 16235)
02107
2107
; C(K) test values mp2 EQU * ; check boundary conditions 37777 1 DS %37777
02110 02111 02112 02113 02114 02115 02116 02117 02120 02121 02122 02123 02124 02125 02126 02127 02130 02131 02132 02133 02134 02135 02136 02137 02140 02141 02142 02143 02144 02145 02146
2110 2111 2112 2113 2114 2115 2116 2117 2120 2121 2122 2123 2124 2125 2126 2127 2130 2131 2132 2133 2134 2135 2136 2137 2140 2141 2142 2143 2144 2145 2146
DS %40000 ; check DS %37777 ; check DS %40000 ; check DS %00000 ; check DS %77777 ; check DS %00000 ; check DS %77777 ; check ; randomly selected checks (one word product) 00021 1 DS %00021 ; check 00007 0 DS %00007 ; check 00051 0 DS %00051 ; check 00035 1 DS %00035 ; check 00103 0 DS %00103 ; check 00065 1 DS %00065 ; check 00141 0 DS %00141 ; check 00117 0 DS %00117 ; check 00177 0 DS %00177 ; check 00153 0 DS %00153 ; check ; randomly selected checks (two word product) 00305 1 DS %00305 ; check 00375 0 DS %00375 ; check 00537 0 DS %00537 ; check 00655 1 DS %00655 ; check 02053 0 DS %02053 ; check 02455 1 DS %02455 ; check 07025 1 DS %07025 ; check 11151 1 DS %11151 ; check 17065 1 DS %17065 ; check 20032 1 DS %20032 ; check 26355 0 DS %26355 ; check 30273 1 DS %30273 ; check 36014 1 DS %36014 ; check 37553 0 DS %37553 ; check ; A = upper product MPchkA EQU * ; check boundary conditions DS %37776 ; check DS %40001 ; check DS %40001 ; check DS %37776 ; check DS %00000 ; check DS %77777 ; check DS %77777 ; check DS %00000 ; check ; randomly selected checks DS %00000 ; check DS %00000 ; check DS %00000 ; check DS %00000 ; check DS %00000 ; check DS %00000 ; check DS %00000 ; check DS %00000 ; check DS %00000 ; check DS %00000 ; check ; randomly selected checks (two word product) DS %00003 ; check DS %00003 ; check DS %00011 ; check DS %00011 ; check DS %00126 ; check DS %00126 ; check DS %02015 ; check DS %02015 ; check DS %07446 ; check DS %07446 ; check DS %21065 ; check DS %21065 ; check DS %35600 ; check DS %35600 ; check
0 1 0 1 0 1 0
#01 #02 #03 #04 #05 #06 #07 #08 #09 #10 #11 #12 #13 #14 #15 #16 #17 #18 #19 #20 #21 #22 #23 #24 #25 #26 #27 #28 #29 #30 #31
(+16383 * -16383) (-16383 * +16383) (-16383 * -16383) (+0 * +0) (+0 * -0) (-0 * +0) (-0 * -0) (7 * 17) (17 * 7) (29 * 41) (41 * 29) (53 * 67) (67 * 53) (79 * 97) (97 * 79) (107 * 127) (127 * 107) (253 * 197) (197 * 253) (429 * 351) (351 * 429) (1325 * 1067) (1067 * 1325) (4713 * 3605) (3605 * 4713) (8218 * 7733) (7733 * 8218) (12475 * 11501) (11501 * 12475) (16235 * 15372) (15372 * 16235)
02147 02150 02151 02152 02153 02154 02155 02156 02157 02160 02161 02162 02163 02164 02165 02166 02167 02170 02171 02172 02173 02174 02175 02176 02177 02200 02201 02202 02203 02204 02205 02206
2147 2150 2151 2152 2153 2154 2155 2156 2157 2160 2161 2162 2163 2164 2165 2166 2167 2170 2171 2172 2173 2174 2175 2176 2177 2200 2201 2202 2203 2204 2205 2206
37776 40001 40001 37776 00000 77777 77777 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000 00003 00003 00011 00011 00126 00126 02015 02015 07446 07446 21065 21065 35600 35600
0 1 1 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1
#00 #01 #02 #03 #04 #05 #06 #07 #08 #09 #10 #11 #12 #13 #14 #15 #16 #17 #18 #19 #20 #21 #22 #23 #24 #25 #26 #27 #28 #29 #30 #31 (7 * 17) (17 * 7) (29 * 41) (41 * 29) (53 * 67) (67 * 53) (79 * 97) (97 * 79) (107 * 127) (127 * 107) (253 * 197) (197 * 253) (429 * 351) (351 * 429) (1325 * 1067) (1067 * 1325) (4713 * 3605) (3605 * 4713) (8218 * 7733) (7733 * 8218) (12475 * 11501) (11501 * 12475) (16235 * 15372) (15372 * 16235)
02207
2207
; check #00
02210 02211 02212 02213 02214 02215 02216 02217 02220 02221 02222 02223 02224 02225 02226 02227 02230 02231 02232 02233 02234 02235 02236 02237 02240 02241 02242 02243 02244 02245 02246 02247 02250 02251 02252
2210 2211 2212 2213 2214 2215 2216 2217 2220 2221 2222 2223 2224 2225 2226 2227 2230 2231 2232 2233 2234 2235 2236 2237 2240 2241 2242 2243 2244 2245 2246 2247 3 2250 5 2251 3 2252 5
DS %77776 ; check DS %77776 ; check DS %00001 ; check DS %00000 ; check DS %77777 ; check DS %77777 ; check DS %00000 ; check ; randomly selected checks 00167 1 DS %00167 ; check 00167 1 DS %00167 ; check 02245 0 DS %02245 ; check 02245 0 DS %02245 ; check 06737 1 DS %06737 ; check 06737 1 DS %06737 ; check 16757 0 DS %16757 ; check 16757 0 DS %16757 ; check 32425 0 DS %32425 ; check 32425 0 DS %32425 ; check ; randomly selected checks (two word product) 01261 0 DS %01261 ; check 01261 0 DS %01261 ; check 06063 1 DS %06063 ; check 06063 1 DS %06063 ; check 11217 0 DS %11217 ; check 11217 0 DS %11217 ; check 00235 0 DS %00235 ; check 00235 0 DS %00235 ; check 30542 1 DS %30542 ; check 30542 1 DS %30542 ; check 00437 1 DS %00437 ; check 00437 1 DS %00437 ; check 06404 1 DS %06404 ; check 06404 1 DS %06404 ; check chkMP 0,0001 0 0,0101 1 1,2045 1 0,0100 0 EQU XCH TS CAF TS * Q savQ MPcode curtest
1 1 0 1 0 0 1
#01 #02 #03 #04 #05 #06 #07 #08 #09 #10 #11 #12 #13 #14 #15 #16 #17 #18 #19 #20 #21 #22 #23 #24 #24 #26 #27 #28 #29 #30 #31 (7 * 17) (17 * 7) (29 * 41) (41 * 29) (53 * 67) (67 * 53) (79 * 97) (97 * 79) (107 * 127) (127 * 107) (253 * 197) (197 * 253) (429 * 351) (351 * 429) (1325 * 1067) (1067 * 1325) (4713 * 3605) (3605 * 4713) (8218 * 7733) (7733 * 8218) (12475 * 11501) (11501 * 12475) (16235 * 15372) (15372 * 16235)
; Decrementing loop ; - always executes at least once (tests at end of loop) ; 02253 2253 3 1,2046 1 - loops 'MPstart+1' times; decrements MPindex XCH MPstart ; initialize loop counter
02254 02255 02256 02257 02260 02261 02262 02263 02264 02265 02266 02267 02270 02271 02272 02273 02274 02275 02276
2254 5 2255 3 2256 6 2257 5 2260 2261 2262 2263 2264 2265 2266 2267 2270 2271 2272 2273 2274 2275 2276 2 3 2 4 4 2 6 1 0 0 0 4 2 6 1
;-----------------------------; MP check starts here ; uses MPindex to access test values MPloop EQU * 0,0102 1 TS MPindex 2,5777 0 0,0102 1 0,0103 0 0,0102 1,2047 0,0103 1,2107 0,0000 0,0102 1,2147 0,0000 1,2036 1,2036 1,2036 0,0003 0,0102 1,2207 0,0000 0 0 1 1 ; verify C(A) 0 0 1 0 0 0 0 ; verify C(LP) 0 0 0 0 CS INDEX AD CCS LP MPindex MPchkLP A COM INDEX AD CCS TC TC TC CAF AD TS INDEX CAF INDEX MP EXTENDER MPindex MPXTND MPindex mp1 MPXTND mp2
; get -A MPindex MPchkA A fail fail fail ; ; ; ; ; put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value)
TC TC TC
; end of MP check ;-----------------------------02302 02303 02304 02305 02306 2302 1 2303 0 2304 3 2305 5 2306 0 0,0102 0 1,2254 0 0,0101 1 0,0001 0 0,0000 0 ; ; ; ; ; ; ; ; ; 02307 2307 CCS TC MPindex MPloop ; done? ; not yet, do next check
XCH savQ TS Q ; restore return address RETURN ---------------------------------------------TEST DV INSTRUCTION SUBROUTINE L: DV K Verifies the following: - Set C(A) = b(A) / C(K) - Set C(Q) = - abs(remainder) - Set C(LP) > 0 if quotient is positive - Set C(LP) < 0 if quotient is negative - Take next instruction from L+1 DS DVtst ; code for this test
00002 0 DVcode
02310
2310
; DV test values ; 00037 0 DVstart DS ; C(A) test values div1 EQU DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS DS ; C(K) test values div2 EQU DS DS DS DS
31 * %00000 %00000 %77777 %77777 %00000 %00000 %77777 %77777 %00000 %00000 %77777 %77777 %37776 %37776 %40001 %40001 %37777 %37777 %40000 %40000 %00001 %00001 %00001 %00001 %00001 %00001 %00001 %00001 %00002 %00004 %00010 %00020 * %00000 %77777 %00000 %77777
02311 02312 02313 02314 02315 02316 02317 02320 02321 02322 02323 02324 02325 02326 02327 02330 02331 02332 02333 02334 02335 02336 02337 02340 02341 02342 02343 02344 02345 02346 02347 02350
2311 2312 2313 2314 2315 2316 2317 2320 2321 2322 2323 2324 2325 2326 2327 2330 2331 2332 2333 2334 2335 2336 2337 2340 2341 2342 2343 2344 2345 2346 2347 2350
00000 00000 77777 77777 00000 00000 77777 77777 00000 00000 77777 77777 37776 37776 40001 40001 37777 37777 40000 40000 00001 00001 00001 00001 00001 00001 00001 00001 00002 00004 00010 00020
1 1 0 0 1 1 0 0 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
check check check check check check check check check check check check check check check check check check check check check check check check check check check check check check check check
#00 #01 #02 #03 #04 #05 #06 #07 #08 #09 #10 #11 #12 #13 #14 #15 #16 #17 #18 #19 #20 #21 #22 #23 #24 #25 #26 #27 #28 #29 #30 #31
(+0/+0) (+0/-0) (-0/+0) (-0/-0) (+0/+1) (+0/-1) (-0/+1) (-0/-1) (+0/+16383) (+0/-16383) (-0/+16383) (-0/-16383) (+16382/+16383) (+16382/-16383) (-16382/+16383) (-16382/-16383) (+16383/+16383) (+16383/-16383) (-16383/+16383) (-16383/-16383) (+1/+2) (+1/+3) (+1/+4) (+1/+5) (+1/+6) (+1/+7) (+1/+8) (+1/+6) (+2/+12) (+4/+24) (+8/+48) (+16/+96)
1 0 1 0
; ; ; ;
02355 02356 02357 02360 02361 02362 02363 02364 02365 02366 02367 02370 02371 02372 02373 02374 02375 02376 02377 02400 02401 02402 02403 02404 02405 02406 02407 02410
2355 2356 2357 2360 2361 2362 2363 2364 2365 2366 2367 2370 2371 2372 2373 2374 2375 2376 2377 2400 2401 2402 2403 2404 2405 2406 2407 2410
00001 77776 00001 77776 37777 40000 37777 40000 37777 40000 37777 40000 37777 40000 37777 40000 00002 00003 00004 00005 00006 00007 00010 00006 00014 00030 00060 00140
0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 1 0 0 1 1 1 1 1
%00001 %77776 %00001 %77776 %37777 %40000 %37777 %40000 %37777 %40000 %37777 %40000 %37777 %40000 %37777 %40000 %00002 %00003 %00004 %00005 %00006 %00007 %00010 %00006 %00014 %00030 %00060 %00140 * %37777 %40000 %40000 %37777 %00000 %77777 %77777 %00000 %00000 %77777 %77777 %00000 %37776 %40001 %40001 %37776 %37777 %40000 %40000 %37777 %20000 %12525 %10000 %06314 %05252 %04444 %04000 %05252 %05252 %05252 %05252 %05252
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
check check check check check check check check check check check check check check check check check check check check check check check check check check check check
#04 #05 #06 #07 #08 #09 #10 #11 #12 #13 #14 #15 #16 #17 #18 #19 #20 #21 #22 #23 #24 #25 #26 #27 #28 #29 #30 #31
(+0/+1) (+0/-1) (-0/+1) (-0/-1) (+0/+16383) (+0/-16383) (-0/+16383) (-0/-16383) (+16382/+16383) (+16382/-16383) (-16382/+16383) (-16382/-16383) (+16383/+16383) (+16383/-16383) (-16383/+16383) (-16383/-16383) (+1/+2) (+1/+3) (+1/+4) (+1/+5) (+1/+6) (+1/+7) (+1/+8) (+1/+6) (+2/+12) (+4/+24) (+8/+48) (+16/+96)
02411 02412 02413 02414 02415 02416 02417 02420 02421 02422 02423 02424 02425 02426 02427 02430 02431 02432 02433 02434 02435 02436 02437 02440 02441 02442 02443 02444 02445 02446 02447 02450
2411 2412 2413 2414 2415 2416 2417 2420 2421 2422 2423 2424 2425 2426 2427 2430 2431 2432 2433 2434 2435 2436 2437 2440 2441 2442 2443 2444 2445 2446 2447 2450
37777 40000 40000 37777 00000 77777 77777 00000 00000 77777 77777 00000 37776 40001 40001 37776 37777 40000 40000 37777 20000 12525 10000 06314 05252 04444 04000 05252 05252 05252 05252 05252
1 0 0 1 1 0 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
check check check check check check check check check check check check check check check check check check check check check check check check check check check check check check check check
#00 #01 #02 #03 #04 #05 #06 #07 #08 #09 #10 #11 #12 #13 #14 #15 #16 #17 #18 #19 #20 #21 #22 #23 #24 #25 #26 #27 #28 #29 #30 #31
(+0/+0) (+0/-0) (-0/+0) (-0/-0) (+0/+1) (+0/-1) (-0/+1) (-0/-1) (+0/+16383) (+0/-16383) (-0/+16383) (-0/-16383) (+16382/+16383) (+16382/-16383) (-16382/+16383) (-16382/-16383) (+16383/+16383) (+16383/-16383) (-16383/+16383) (-16383/-16383) (+1/+2) (+1/+3) (+1/+4) (+1/+5) (+1/+6) (+1/+7) (+1/+8) (+1/+6) (+2/+12) (+4/+24) (+8/+48) (+16/+96)
02451 02452 02453 02454 02455 02456 02457 02460 02461 02462 02463 02464 02465 02466 02467 02470 02471 02472 02473 02474 02475 02476 02477 02500 02501 02502 02503 02504 02505 02506 02507 02510
2451 2452 2453 2454 2455 2456 2457 2460 2461 2462 2463 2464 2465 2466 2467 2470 2471 2472 2473 2474 2475 2476 2477 2500 2501 2502 2503 2504 2505 2506 2507 2510
77777 77777 77777 77777 77777 77777 77777 77777 77777 77777 77777 77777 40001 40001 40001 40001 40000 40000 40000 40000 77777 77776 77777 77773 77773 77773 77777 77773 77767 77757 77737 77677
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 1 0 1 1 1 0 1 1 1 1 1
* %77777 %77777 %77777 %77777 %77777 %77777 %77777 %77777 %77777 %77777 %77777 %77777 %40001 %40001 %40001 %40001 %40000 %40000 %40000 %40000 %77777 %77776 %77777 %77773 %77773 %77773 %77777 %77773 %77767 %77757 %77737 %77677 * %00001 %40000 %40001 %00001 %00001 %40000 %40001 %00001 %00001 %40000 %40001 %00001 %00001 %40000 %40001 %00001 %00001 %40000 %40001 %00001 %00001 %00001 %00001 %00001 %00001 %00001 %00001
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
check check check check check check check check check check check check check check check check check check check check check check check check check check check check check check check check
#00 #01 #02 #03 #04 #05 #06 #07 #08 #09 #10 #11 #12 #13 #14 #15 #16 #17 #18 #19 #20 #21 #22 #23 #24 #25 #26 #27 #28 #29 #30 #31
(+0/+0) (+0/-0) (-0/+0) (-0/-0) (+0/+1) (+0/-1) (-0/+1) (-0/-1) (+0/+16383) (+0/-16383) (-0/+16383) (-0/-16383) (+16382/+16383) (+16382/-16383) (-16382/+16383) (-16382/-16383) (+16383/+16383) (+16383/-16383) (-16383/+16383) (-16383/-16383) (+1/+2) (+1/+3) (+1/+4) (+1/+5) (+1/+6) (+1/+7) (+1/+8) (+1/+6) (+2/+12) (+4/+24) (+8/+48) (+16/+96)
02511 02512 02513 02514 02515 02516 02517 02520 02521 02522 02523 02524 02525 02526 02527 02530 02531 02532 02533 02534 02535 02536 02537 02540 02541 02542 02543
2511 2512 2513 2514 2515 2516 2517 2520 2521 2522 2523 2524 2525 2526 2527 2530 2531 2532 2533 2534 2535 2536 2537 2540 2541 2542 2543
00001 40000 40001 00001 00001 40000 40001 00001 00001 40000 40001 00001 00001 40000 40001 00001 00001 40000 40001 00001 00001 00001 00001 00001 00001 00001 00001
0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
check check check check check check check check check check check check check check check check check check check check check check check check check check check
#00 #01 #02 #03 #04 #05 #06 #07 #08 #09 #10 #11 #12 #13 #14 #15 #16 #17 #18 #19 #20 #21 #22 #23 #24 #25 #26
(+0/+0) (+0/-0) (-0/+0) (-0/-0) (+0/+1) (+0/-1) (-0/+1) (-0/-1) (+0/+16383) (+0/-16383) (-0/+16383) (-0/-16383) (+16382/+16383) (+16382/-16383) (-16382/+16383) (-16382/-16383) (+16383/+16383) (+16383/-16383) (-16383/+16383) (-16383/-16383) (+1/+2) (+1/+3) (+1/+4) (+1/+5) (+1/+6) (+1/+7) (+1/+8)
0 0 0 0 0 chkDV
; ; ; ; ;
; Decrementing loop ; - always executes at least once (tests at end of loop) ; 02555 2555 3 1,2310 1 - loops 'DVstart+1' times; decrements DVindex XCH DVstart ; initialize loop counter
;-----------------------------; DV check starts here ; uses DVindex to access test values DVloop EQU * 0,0105 0 TS DVindex 2,5777 0 0,0105 0 0,0106 0 0,0105 1,2311 0,0106 1,2351 0,0104 0,0001 0,0105 1,2451 0,0000 1,2036 1,2036 1,2036 0,0104 0,0105 1,2411 0,0000 1,2036 1,2036 1,2036 0,0003 0,0105 1,2511 0,0000 1,2036 1,2036 1,2036 1 0 1 1 1 ; verify C(Q) 02567 02570 02571 02572 02573 02574 02575 02576 02577 02600 02601 02602 02603 02604 02605 02606 02607 02610 02611 02612 02613 2567 2570 2571 2572 2573 2574 2575 2576 2577 2600 2601 2602 2603 2604 2605 2606 2607 2610 2611 2612 2613 4 2 6 1 0 0 0 4 2 6 1 0 0 0 4 2 6 1 0 0 0 1 1 0 0 0 0 0 ; verify C(A) 0 1 1 0 0 0 0 ; verify C(LP) 0 1 0 0 0 0 0 CS INDEX AD CCS TC TC TC LP DVindex DVchkLP A fail fail fail ; get -A ; ; ; ; ; put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value) CS INDEX AD CCS TC TC TC DVsavA DVindex DVchkA A fail fail fail ; get -A ; ; ; ; ; put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value) CS INDEX AD CCS TC TC TC Q DVindex DVchkQ A fail fail fail ; get -A ; ; ; ; ; put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value) CAF AD TS INDEX CAF INDEX DV TS EXTENDER DVindex DVXTND DVindex div1 DVXTND div2 DVsavA
; end of DV check ;-----------------------------02614 02615 02616 02617 02620 2614 1 2615 0 2616 3 2617 5 2620 0 0,0105 1 1,2556 0 0,0101 1 0,0001 0 0,0000 0 CCS TC DVindex DVloop ; done? ; not yet, do next check
XCH savQ TS Q ; restore return address RETURN ; ---------------------------------------------; TEST SU INSTRUCTION SUBROUTINE
; ; ; ; ; ; ; ; 02621 02622 02623 02624 02625 02626 02627 02630 02631 02632 02633 02634 02635 02636 02637 02640 2621 2622 2623 2624 2625 2626 2627 2630 2631 2632 2633 2634 2635 3 2636 5 2637 3 2640 5
L: SU K Verifies the following: - Set C(A) = b(A) - C(K) - Take next instruction from L+1 - if C(A) has positive overflow, -- increment overflow counter by 1 - if C(A) has negative overflow, -- decrement overflow counter by 1 DS DS DS DS DS DS DS DS DS DS DS DS EQU XCH TS CAF TS SUtst +0 1 -1 %25252 %12525 %37777 %12524 %52525 %65252 %40000 %65253 * Q savQ SUcode curtest ; ; ; ; ; ; ; ; +10922 decimal +5461 decimal largest positive number + overflow of %25252+%25252 -10922 decimal -5461 decimal largest negative number - overflow of %52525+65252 ; code for this test
00003 1 SUcode 00000 1 SUplus0 00001 0 SUplus1 77776 1 SUmin1 25252 12525 37777 12524 52525 65252 40000 65253 0 0 1 1 1 1 0 0 SU25252 SU12525 SU37777 SU12524 SU52525 SU65252 SU40000 SU65253 chkSU 0,0001 0 0,0101 1 1,2621 0 0,0100 0 ; ; ; ;
NOTE: these test are similar to the checks for AD, but the AD augend value has been changed to negative and AD has been changed to SU. The results produced by this change are identical to AD, and so the checks are the same.
; TEST1: difference positive, no overflow ; sub: %25252 - %65252 = %37777 (sign + 14 magnitude) CAF SU25252 EXTEND SU SU65252 ; verify C(A) = %37777 COM ; get -A AD SU37777 ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; TEST2: difference negative, no overflow (sign + 14 magnitude) ; sub: %52525 - %12525 = %40000 CAF SU52525 EXTEND SU SU12525 ; verify C(A) = %40000 COM ; get -A AD SU40000 ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; TEST3: difference positive, overflow ; initialize overflow counter and positive overflow storage CAF SUplus0 TS OVFCNTR TS SUk ; sub: %25252 - %52525 = %52524 (sign + 14 magnitude) CAF SU25252 EXTEND SU SU52525 TS SUk ; store positive overflow TC fail ; verify SUk = %12524 CS SUk ; get -A
2673 4
0,0107 0
02674 02675 02676 02677 02700 02701 02702 02703 02704 02705 02706 02707 02710 02711 02712 02713 02714 02715 02716 02717 02720 02721 02722 02723 02724 02725 02726 02727 02730 02731 02732 02733 02734 02735
2674 2675 2676 2677 2700 2701 2702 2703 2704 2705 2706
6 1 0 0 0 4 6 1 0 0 0
AD SU12524 CCS A TC fail TC fail TC fail ; verify overflow counter =%00001 0,0034 1 CS OVFCNTR 1,2623 1 AD SUplus1 0,0000 0 CCS A 1,2036 0 TC fail 1,2036 0 TC fail 1,2036 0 TC fail 1,2622 0 0,0034 0 0,0107 1 1,2631 0,0000 1,2625 0,0107 1,2036 0,0107 1,2634 0,0000 1,2036 1,2036 1,2036 0,0034 1,2624 0,0000 1,2036 1,2036 1,2036 1 1 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0
; ; ; ; ; ; ; ; ; ; ;
put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value) get -A put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value)
2707 3 2710 5 2711 5 2712 2713 2714 2715 2716 2717 2720 2721 2722 2723 2724 2725 2726 2727 2730 2731 2732 3 2 6 5 0 4 6 1 0 0 0 4 6 1 0 0 0
; TEST4: difference negative, overflow CAF SUplus0 TS OVFCNTR TS SUk ; add: %52525 + %25252 = %25253 (sign + 14 magnitude) CAF SU52525 EXTEND SU SU25252 TS SUk ; store negative overflow TC fail ; verify SUk = %65253 CS SUk ; get -A AD SU65253 ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) ; verify overflow counter =%77776 CS OVFCNTR ; get -A AD SUmin1 ; put (-A) + expected value in A CCS A ; compare TC fail ; >0 (A < expected value) TC fail ; +0 TC fail ; <0 (A > expected value) XCH savQ TS Q ; restore return address RETURN ; ---------------------------------------------; PASSED ALL TESTS! DS EQU CAF TS RETURN PASS * PASScode curtest
; ---------------------------------------------; INTERRUPT SERVICE ROUTINE goT3 goER goDS goKEY goUP endRUPT 02742 02743 02744 02745 2742 2743 2744 2745 3 5 3 2 0,0027 0,0001 0,0026 0,0000 1 0 0 1 EQU EQU EQU EQU EQU EQU XCH TS XCH RESUME * * * * * * QRUPT Q ARUPT
Assembly complete. Errors = 0 Symbol table: START SUtst OVFCNTR 000000 000003 000034 MPtst PASS curtest 000001 012345 000100 DVtst EXTENDER savQ 000002 005777 000101
MPindex DVindex GOPROG DSRUPT goMAIN STRTcode MPstart MPchkA MPloop div1 DVchkQ DVloop SUplus1 SU12525 SU52525 SU65253 finish goDS endRUPT QRUPT
000102 000105 002000 002014 002030 002041 002046 002147 002254 002311 002451 002556 002623 002626 002631 002634 002737 002742 002742 000027
MPXTND DVXTND T3RUPT KEYRUPT fail begin mp1 MPchkLP DVcode div2 DVchkLP SUcode SUmin1 SU37777 SU65252 chkSU goT3 goKEY ARUPT A
000103 000106 002004 002020 002036 002042 002047 002207 002307 002351 002511 002621 002624 002627 002632 002635 002742 002742 000026 000000
DVsavA SUk ERRUPT UPRUPT end MPcode mp2 chkMP DVstart DVchkA chkDV SUplus0 SU25252 SU12524 SU40000 PASScode goER goUP Q LP
000104 000107 002010 002024 002040 002045 002107 002247 002310 002411 002551 002622 002625 002630 002633 002736 002742 002742 000001 000003
PASS EQU %12345 ; PASSED all checks ; ---------------------------------------------05777 5777 47777 0 ORG DS EXTENDER %47777 ; needed for EXTEND
; ---------------------------------------------; ERASEABLE MEMORY -- DATA SEGMENT 00100 00101 00102 00103 00104 00105 00106 00107 00110 00111 0100 0101 0102 0103 0104 0105 0106 0107 0110 0111 00000 1 curtest 00000 1 savQ ORG DS DS %100 START %0 %0 %0 %0 %0 %0 %0 %0 %0 ; start of data area ; current test
; CYR test values 00000 1 CYRval DS 00000 1 iCYR DS ; SR test values 00000 1 SRval DS 00000 1 iSR DS ; CYL test values 00000 1 CYLval DS 00000 1 iCYL DS ; SL test values 00000 1 SLval DS 00000 1 iSL DS
; current test value ; current index ; current test value ; current index ; current test value ; current index ; current test value ; current index
02000
2000 0
02004 02005 02006 02007 02010 02011 02012 02013 02014 02015 02016 02017 02020 02021 02022 02023
2004 2005 2006 2007 2010 2011 2012 2013 2014 2015 2016 2017 2020 2021 2022 2023
5 3 5 0 5 3 5 0 5 3 5 0 5 3 5 0
0,0026 0,0001 0,0027 1,2424 0,0026 0,0001 0,0027 1,2424 0,0026 0,0001 0,0027 1,2424 0,0026 0,0001 0,0027 1,2424
0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
; interrupt service entry points ORG T3RUPT TS ARUPT XCH Q TS QRUPT TC goT3 ORG TS XCH TS TC ORG TS XCH TS TC ORG TS XCH TS TC ORG TS XCH TS TC ERRUPT ARUPT Q QRUPT goER DSRUPT ARUPT Q QRUPT goDS KEYRUPT ARUPT Q QRUPT goKEY UPRUPT ARUPT Q QRUPT goUP
5 3 5 0
0 0 1 1
; ---------------------------------------------; FIXED MEMORY -- SHARED DATA SEGMENT ; ---------------------------------------------; MAIN PROGRAM goMAIN 02030 02031 02032 2030 2 2031 0 2032 0 0,0000 0 1,2043 1 1,2070 1 EQU INHINT TCR * ; disable interrupts begin
TCR TCR TCR ; Passed all tests. TCR fail EQU XCH TS EQU TC
chkSR chkCYL chkSL finish * curtest curtest * end ; load last passed test into A
; finished, TC trap
; ---------------------------------------------; INITIALIZE FOR START OF TESTING 02042 02043 02044 02045 2042 2043 3 2044 5 2045 0 00000 1 STRTcode begin 1,2042 0 0,0100 0 0,0000 0 ; ; ; ; ; ; 02046 02047 02050 2046 2047 2050 DS EQU XCH TS RETURN START * STRTcode curtest
---------------------------------------------TEST CYR EDITING FUNCTION SUBROUTINE Rotate a test value right through CYR 15 times. Test the value against an expected value for each time. After 15 rotations, the value should equal the initial value. DS CYRtst %03431 14 ; code for this test ; init test value ; loop CYRindx+1 times
00001 0 CYRcode
02051 02052 02053 02054 02055 02056 02057 02060 02061 02062 02063 02064 02065 02066 02067 02070 02071 02072 02073 02074 02075 02076 02077 02100 02101 02102 02103
2051 2052 2053 2054 2055 2056 2057 2060 2061 2062 2063 2064 2065 2066 2067 2070 3 2071 5 2072 3 2073 5 2074 3 2075 5 2076 3 2077 5 2100 2101 2102 2103 3 5 3 5
03431 07062 16144 34310 70620 61441 43103 06207 14416 31034 62070 44161 10343 20706 41614
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
; check CYR against these values CYRbase EQU * DS %03431 DS %07062 DS %16144 DS %34310 DS %70620 DS %61441 DS %43103 DS %06207 DS %14416 DS %31034 DS %62070 DS %44161 DS %10343 DS %20706 DS %41614 chkCYR EQU XCH TS CAF TS XCH TS XCH CYRloop EQU TS * Q savQ CYRcode curtest CYRinit CYRval CYRindx * iCYR CYRval CYR CYR CYRval
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
check check check check check check check check check check check check check check check
0,0001 0 0,0101 1 1,2046 1 0,0100 0 1,2047 0 0,0102 1 1,2050 0 0,0103 0 0,0102 0,0020 0,0020 0,0102 1 0 0 1
; save return address ; set test code to this test ; init value to rotate ; load init index ; save index
; verify C(A) 02104 02105 02106 02107 02110 02111 02112 02113 02114 02115 02116 02117 2104 2105 2106 2107 2110 2111 2112 4 2 6 1 0 0 0 0,0000 0,0103 1,2051 0,0000 1,2037 1,2037 1,2037 0 1 1 0 1 1 1 COM INDEX AD CCS TC TC TC ; get -A iCYR CYRbase A fail fail fail ; ; ; ; ; put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value)
; loop back to test next value CCS iCYR TC CYRloop XCH TS RETURN ; ; ; ; ; savQ Q
---------------------------------------------TEST SR EDITING FUNCTION SUBROUTINE Shift a test value right through SR 15 times. Test the value against an expected value for each time. After 15 shifts, the value should equal the sign (SG). DS SRtst %03431 %44346 14 ; code for this test ; positive init test value ; negative init test value ; loop SRindx+1 times
00002 0 SRcode
02124 02125 02126 02127 02130 02131 02132 02133 02134 02135 02136 02137 02140 02141 02142
2124 2125 2126 2127 2130 2131 2132 2133 2134 2135 2136 2137 2140 2141 2142
00000 00000 00000 00000 00000 00001 00003 00007 00016 00034 00070 00161 00343 00706 01614
1 1 1 1 1 0 1 0 0 0 0 1 0 0 0
; check SR against these values (positive) SRbaseP EQU * DS %00000 ; check DS %00000 ; check DS %00000 ; check DS %00000 ; check DS %00000 ; check DS %00001 ; check DS %00003 ; check DS %00007 ; check DS %00016 ; check DS %00034 ; check DS %00070 ; check DS %00161 ; check DS %00343 ; check DS %00706 ; check DS %01614 ; check ; check SR against these values (negative) SRbaseN EQU * DS %77777 ; check DS %77777 ; check DS %77776 ; check DS %77774 ; check DS %77771 ; check DS %77762 ; check DS %77744 ; check DS %77710 ; check DS %77621 ; check DS %77443 ; check DS %77107 ; check DS %76216 ; check DS %74434 ; check DS %71071 ; check DS %62163 ; check chkSR EQU XCH TS CAF TS * Q savQ SRcode curtest
02143 02144 02145 02146 02147 02150 02151 02152 02153 02154 02155 02156 02157 02160 02161 02162 02163 02164 02165 02166 02167
2143 2144 2145 2146 2147 2150 2151 2152 2153 2154 2155 2156 2157 2160 2161 2162 3 2163 5 2164 3 2165 5 2166 3 2167 5
77777 77777 77776 77774 77771 77762 77744 77710 77621 77443 77107 76216 74434 71071 62163
0 0 1 0 0 1 0 1 1 1 1 0 1 1 1
; save return address ; set test code to this test ; init value to shift
02170
2170 3
1,2123 0 SRloopP
XCH EQU TS
02171 02172 02173 02174 02175 02176 02177 02200 02201 02202 02203 02204 02205 02206 02207 02210 02211
2171 5 2172 2173 2174 2175 2176 2177 2200 2201 2202 2203 2204 3 5 3 5 4 2 6 1 0 0 0
0,0105 0 0,0104 0,0021 0,0021 0,0104 0,0000 0,0105 1,2124 0,0000 1,2037 1,2037 1,2037 1 1 1 1 0 1 1 0 1 1 1
; save index
; shift A right (SR) XCH TS XCH TS ; verify C(A) COM INDEX AD CCS TC TC TC
; get -A iSR SRbaseP A fail fail fail ; ; ; ; ; put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value)
; loop back to test next value CCS iSR TC SRloopP ; TEST 2: shift a negative value XCH SRinitN TS SRval XCH SRloopN EQU TS SRindx * iSR SRval SR SR SRval
; done? ; not yet, do next check ; init value to shift ; load init index
02212 02213 02214 02215 02216 02217 02220 02221 02222 02223 02224 02225 02226 02227 02230 02231 02232
2212 5 2213 2214 2215 2216 2217 2220 2221 2222 2223 2224 2225 3 5 3 5 4 2 6 1 0 0 0
0,0105 0 0,0104 0,0021 0,0021 0,0104 0,0000 0,0105 1,2143 0,0000 1,2037 1,2037 1,2037 1 1 1 1 0 1 0 0 1 1 1
; save index
; shift A left (SR) XCH TS XCH TS ; verify C(A) COM INDEX AD CCS TC TC TC
; get -A iSR SRbaseN A fail fail fail ; ; ; ; ; put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value)
; loop back to test next value CCS iSR TC SRloopN XCH TS RETURN ; ; ; ; ; ; savQ Q
---------------------------------------------TEST CYL EDITING FUNCTION SUBROUTINE Rotate a test value left through CYL 15 times. Test the value against an expected value for each time. After 15 rotations, the value should equal the initial value. DS CYLtst %03431 14 ; code for this test ; init test value ; loop CYLindx+1 times
00003 1 CYLcode
02236 02237
2236 2237
; check CYL against these values CYLbase EQU * 03431 1 DS %03431 41614 1 DS %41614
02240 02241 02242 02243 02244 02245 02246 02247 02250 02251 02252 02253 02254 02255 02256 02257 02260 02261 02262 02263 02264 02265 02266 02267 02270 02271 02272 02273 02274 02275 02276 02277 02300 02301 02302 02303 02304
2240 2241 2242 2243 2244 2245 2246 2247 2250 2251 2252 2253 2254 2255 3 2256 5 2257 3 2260 5 2261 3 2262 5 2263 3 2264 5 2265 2266 2267 2270 2271 2272 2273 2274 2275 2276 2277 3 5 3 5 4 2 6 1 0 0 0
20706 10343 44161 62070 31034 14416 06207 43103 61441 70620 34310 16144 07062
1 1 1 1 1 1 1 1 1 1 1 1 1 chkCYL
%20706 %10343 %44161 %62070 %31034 %14416 %06207 %43103 %61441 %70620 %34310 %16144 %07062 * Q savQ CYLcode curtest CYLinit CYLval CYLindx * iCYL CYLval CYL CYL CYLval
; ; ; ; ; ; ; ; ; ; ; ; ;
check check check check check check check check check check check check check
0,0001 0 0,0101 1 1,2233 1 0,0100 0 1,2234 0 0,0106 0 1,2235 1 0,0107 1 0,0106 0,0022 0,0022 0,0106 0,0000 0,0107 1,2236 0,0000 1,2037 1,2037 1,2037 0 1 1 0 0 0 1 0 1 1 1
; save return address ; set test code to this test ; init value to rotate ; load init index ; save index
; rotate A left (CYL) XCH TS XCH TS ; verify C(A) COM INDEX AD CCS TC TC TC
; get -A iCYL CYLbase A fail fail fail ; ; ; ; ; put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value)
; loop back to test next value CCS iCYL TC CYLloop XCH TS RETURN ; ; ; ; ; savQ Q
---------------------------------------------TEST SL EDITING FUNCTION SUBROUTINE Shift a test value left through SL 15 times. Test the value against an expected value for each time. After 15 shifts, the value should equal the sign (SG). DS SLtst %03431 %44346 14 ; code for this test ; positive init test value ; negative init test value ; loop SLindx+1 times
00004 0 SLcode
1 1 0 0 0 1 0 0 0
; check SL against these values (positive) SLbaseP EQU * DS %00000 ; check DS %00000 ; check DS %20000 ; check DS %10000 ; check DS %04000 ; check DS %22000 ; check DS %31000 ; check DS %14400 ; check DS %06200 ; check
#0 (back to start) #1 #2 #3 #4 #5 #6 #7 #8
0 1 0 1 1 1
DS DS DS DS DS DS
; ; ; ; ; ;
02330 02331 02332 02333 02334 02335 02336 02337 02340 02341 02342 02343 02344 02345 02346 02347 02350 02351 02352 02353 02354 02355
2330 2331 2332 2333 2334 2335 2336 2337 2340 2341 2342 2343 2344 2345 2346 2347 3 2350 5 2351 3 2352 5 2353 3 2354 5 2355 3
77777 77777 57777 67777 73777 55777 46777 63377 71577 74677 56337 47157 43467 61633 50715
0 0 1 1 1 0 1 1 1 1 0 1 0 0 1
; check SL against these values (negative) SLbaseN EQU * DS %77777 ; check DS %77777 ; check DS %57777 ; check DS %67777 ; check DS %73777 ; check DS %55777 ; check DS %46777 ; check DS %63377 ; check DS %71577 ; check DS %74677 ; check DS %56337 ; check DS %47157 ; check DS %43467 ; check DS %61633 ; check DS %50715 ; check chkSL EQU XCH TS CAF TS * Q savQ SLcode curtest
; save return address ; set test code to this test ; init value to shift ; load init index
; TEST 1: shift a postive value. XCH SLinitP TS SLval XCH EQU TS SLindx * iSL SLval SL SL SLval
02356 02357 02360 02361 02362 02363 02364 02365 02366 02367 02370 02371 02372 02373 02374 02375 02376 02377 02400 02401 02402 02403
2356 5 2357 2360 2361 2362 2363 2364 2365 2366 2367 2370 2371 3 5 3 5 4 2 6 1 0 0 0
0,0111 0 0,0110 0,0023 0,0023 0,0110 0,0000 0,0111 1,2311 0,0000 1,2037 1,2037 1,2037 1 0 0 1 0 1 0 0 1 1 1
; save index
; shift A left (SL) XCH TS XCH TS ; verify C(A) COM INDEX AD CCS TC TC TC
; get -A iSL SLbaseP A fail fail fail ; ; ; ; ; put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value)
2372 1 2373 0 2374 3 2375 5 2376 3 2377 5 2400 2401 2402 2403 3 5 3 5
; loop back to test next value CCS iSL TC SLloopP ; TEST 2: shift a negative value XCH SLinitN TS SLval XCH SLloopN EQU TS SLindx * iSL SLval SL SL SLval
; done? ; not yet, do next check ; init value to shift ; load init index ; save index
; verify C(A) 02404 02405 02406 02407 02410 02411 02412 02413 02414 02415 02416 02417 2404 2405 2406 2407 2410 2411 2412 4 2 6 1 0 0 0 0,0000 0,0111 1,2330 0,0000 1,2037 1,2037 1,2037 0 1 0 0 1 1 1 COM INDEX AD CCS TC TC TC ; get -A iSL SLbaseN A fail fail fail ; ; ; ; ; put (-A) + expected value in A compare >0 (A < expected value) +0 <0 (A > expected value)
; loop back to test next value CCS iSL TC SLloopN XCH TS RETURN savQ Q
; ---------------------------------------------; PASSED ALL TESTS! 02420 02421 02422 02423 2420 2421 3 2422 5 2423 0 12345 0 PASScode finish 1,2420 0 0,0100 0 0,0000 0 DS EQU CAF TS RETURN PASS * PASScode curtest
; ---------------------------------------------; INTERRUPT SERVICE ROUTINE goT3 goER goDS goKEY goUP endRUPT 02424 02425 02426 02427 2424 2425 2426 2427 3 5 3 2 0,0027 0,0001 0,0026 0,0000 1 0 0 1 EQU EQU EQU EQU EQU EQU XCH TS XCH RESUME * * * * * * QRUPT Q ARUPT
Assembly complete. Errors = 0 Symbol table: START CYLtst EXTENDER CYRval iSR SLval T3RUPT KEYRUPT fail begin CYRindx CYRloop SRinitN SRbaseN SRloopN CYLindx CYLloop SLinitN SLbaseN SLloopN goT3 goKEY ARUPT CYR CYL 000000 000003 005777 000102 000105 000110 002004 002020 002037 002043 002050 002077 002122 002143 002212 002235 002264 002307 002330 002377 002424 002424 000026 000020 000022 CYRtst SLtst curtest iCYR CYLval iSL ERRUPT UPRUPT end CYRcode CYRbase SRcode SRindx chkSR CYLcode CYLbase SLcode SLindx chkSL PASScode goER goUP Q A SL 000001 000004 000100 000103 000106 000111 002010 002024 002041 002046 002051 002120 002123 002162 002233 002236 002305 002310 002347 002420 002424 002424 000001 000000 000023 SRtst PASS savQ SRval iCYL GOPROG DSRUPT goMAIN STRTcode CYRinit chkCYR SRinitP SRbaseP SRloopP CYLinit chkCYL SLinitP SLbaseP SLloopP finish goDS endRUPT QRUPT SR 000002 012345 000101 000104 000107 002000 002014 002030 002042 002047 002070 002121 002124 002171 002234 002255 002306 002311 002356 002421 002424 002424 000027 000021
ORG DS DS DS DS
%47 %0 %0 %0 %0
; start of data area ; counts T3RUPTs ; counts DSRUPTs (T4RUPT) ; counts KEYRUPT
02000
2000 0
02004 02005 02006 02007 02014 02015 02016 02017 02020 02021 02022 02023
2004 2005 2006 2007 2014 2015 2016 2017 2020 2021 2022 2023
5 3 5 0 5 3 5 0 5 3 5 0
0,0026 0,0001 0,0027 1,2064 0,0026 0,0001 0,0027 1,2071 0,0026 0,0001 0,0027 1,2076
0 0 1 1 0 0 1 0 0 0 1 1
; interrupt service entry points ORG T3RUPT TS ARUPT XCH Q TS QRUPT TC goT3 ORG TS XCH TS TC ORG TS XCH TS TC DSRUPT ARUPT Q QRUPT goDS KEYRUPT ARUPT Q QRUPT goKEY ; aka T4RUPT
; ---------------------------------------------; FIXED MEMORY -- SHARED DATA SEGMENT 02024 02025 02026 02027 2024 2025 2026 2027 00000 00001 25252 52525 1 0 0 1 ZERO ONE AD25252 AD52525 DS DS DS DS %0 %1 %25252 %52525
;+10922 dec, see TECO1 AD test ;-10922 dec, see TECO1 AD test
; ---------------------------------------------; MAIN PROGRAM goMAIN 02030 2030 2 0,0000 0 EQU INHINT * ; disable interrupts
; clear counters for interrupts and for interations ; though main loop. 02031 02032 02033 02034 02035 2031 2032 2033 2034 2035 3 5 5 5 5 1,2024 0,0047 0,0050 0,0051 0,0052 0 1 1 0 0 CAF TS TS TS TS ZERO mainCtr T3Ctr DSCtr KYCtr ; ; ; ; mainCtr T3Ctr = DSCtr = KYCtr = = 0 0 0 0
; keeps bumping mainCtr in an infinite loop. ; interrupts are disabled and enabled on each ; iteration of the loop. infLoop 02036 2036 2 0,0000 0 EQU INHINT * ; disable interrupt
; increment mainCtr while interrupt is inhibited. 02037 02040 02041 02042 02043 2037 3 2040 6 2041 6 2042 2 2043 5 1,2024 0 0,0047 1 1,2025 1 0,0000 1 0,0047 1 CAF AD AD RELINT TS mainCtr ZERO mainCtr ONE ; load mainCtr into A ; incr ; enable interrupts ; store increment value
; ; ; ; 02044 02045 02046 02047 2044 3 2045 6 2046 3 2047 3 1,2026 1 1,2026 1 0,0000 1 0,0000 1
create a positive overflow in A. Interrupts are inhibited while A contains an overflow. The overflow is produced by adding %25252 + %25252 = %52524 (sign + 14 magnitude). This is the overflow test in TECO1 for the AD instruction. CAF AD NOOP NOOP AD25252 AD25252 ; positive overflow ; interrupt should be inhib
; remove the overflow, this reenables the interrupt. 02050 02051 02052 2050 3 2051 3 2052 3 1,2024 0 0,0000 1 0,0000 1 ; ; ; ; 02053 02054 02055 02056 2053 3 2054 6 2055 3 2056 3 1,2027 0 1,2027 0 0,0000 1 0,0000 1 CAF NOOP NOOP ZERO ; clear the overflow in A ; interrupt should be reenab
create a negative overflow in A. Interrupts are inhibited while A contains an overflow. The overflow is produced by adding %52525 + %52525 = %25253 (sign + 14 magnitude). This is the overflow test in TECO1 for the AD instruction. CAF AD NOOP NOOP AD52525 AD52525 ; positive overflow ; interrupt should be inhib
; remove the overflow, this reenables the interrupt. 02057 02060 02061 02062 02063 2057 3 2060 3 2061 3 2062 0 2063 0 1,2024 0 0,0000 1 0,0000 1 1,2036 0 1,2036 0 CAF NOOP NOOP TC TC infLoop infLoop ZERO ; clear the overflow in A ; interrupt should be reenab
; ---------------------------------------------; INTERRUPT SERVICE ROUTINE goT3 02064 02065 02066 02067 02070 02071 02072 02073 02074 02075 02076 02077 02100 02101 02102 02103 02104 02105 02106 2064 2065 2066 2067 2070 2071 2072 2073 2074 2075 2076 2077 2100 2101 2102 2103 2104 2105 2106 3 6 6 5 0 3 6 6 5 0 3 6 6 5 0 3 5 3 2 1,2024 0,0050 1,2025 0,0050 1,2103 1,2024 0,0051 1,2025 0,0051 1,2103 1,2024 0,0052 1,2025 0,0052 1,2103 0,0027 0,0001 0,0026 0,0000 0 1 1 1 1 goDS 0 0 1 0 1 goKEY 0 0 1 0 1 endRUPT 1 0 0 1 EQU CAF AD AD TS TC EQU CAF AD AD TS TC EQU CAF AD AD TS TC EQU XCH TS XCH RESUME * ZERO T3Ctr ONE T3Ctr endRUPT * ZERO DSCtr ONE DSCtr endRUPT * ZERO KYCtr ONE KYCtr endRUPT * QRUPT Q ARUPT
02000 02001
2000 0 2001
; standby is disabled NOOP NOOP ; enable standby XCH TS infLoop EQU TC ofbit OUT1 * infLoop
Assembly complete. Errors = 0 Symbol table: GOPROG infLoop 002000 002006 ofbit OUT1 002001 000011 goMAIN 002002