PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 1 SBC6120 ROM Monitor BTS6120.PLX 1 .TITLE SBC6120 ROM Monitor 2 3 4 ; Copyright (C) 2001-2003 by R. Armstrong, Milpitas, California. 5 ; Copyright (C) 1983 by R. Armstrong, Indianapolis, Indiana. 6 ; 7 ; This program is free software; you can redistribute it and/or modify 8 ; it under the terms of the GNU General Public License as published by 9 ; the Free Software Foundation; either version 2 of the License, or 10 ; (at your option) any later version. 11 ; 12 ; This program is distributed in the hope that it will be useful, but 13 ; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 ; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 ; for more details. 16 ; 17 ; You should have received a copy of the GNU General Public License along 18 ; with this program; if not, write to the Free Software Foundation, Inc., 19 ; 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 ; 21 22 ; This is the ROM monitor for the SBC6120 computer system, which is a Harris 23 ; HM6120 (a PDP-8 for all practical purposes) microprocessor based single board 24 ; computer. The SBC6120 is intended as a platform for developing other HM6120 25 ; systems and experimenting with various ideas for peripherals, and this gives 26 ; it a rather eclectic mix of hardware: 27 ; 28 ; * 64KW (that's 64K twelve bit WORDS) of RAM - 32KW for panel memory and 29 ; 32KW for conventional memory. 30 ; 31 ; * 8KW of EPROM used for bootstrapping - it contains this software. 32 ; 33 ; * Up to 2Mb (real eight bit bytes this time) of battery backed up, 34 ; non-volatile SRAM used as a RAM disk for OS/8. The RAM disk can be 35 ; mapped into the HM6120 panel memory space. 36 ; 37 ; * A fairly elaborate memory management system which controls the mapping 38 ; of RAM, EPROM and RAM disk into panel memory. 39 ; 40 ; * A real, straight-8, compatible console terminal interface. The control 41 ; logic is implemented in a GAL and no 6121 is used (as it is in both 42 ; models of DECmate). 43 ; 44 ; * A single digit octal display used to show POST error codes. 45 ; 46 ; * An IDE disk interface, implemented by a 8255 PPI 47 ; 48 ; This particular piece of software started life in 1983 as a bootstrap 49 ; program for an elaborate Intersil IM6100 system planned by the author. The 50 ; software was developed and tested on an 6100 emulator running on a 51 ; DECsystem-10, but it never saw any actual hardware. Although I built several 52 ; simpler 6100 based systems, the one intended for this software proved to be 53 ; too elaborate and complex and was never built. Until now, that is... 54 55 56 .HM6120 57 .STACK PAC1, POP1, PPC1, RTN1 6215 6235 6205 6225 58 .NOWARN F PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 2 BTS6120 Memory Layout BTS6120.PLX 59 .TITLE BTS6120 Memory Layout 60 61 ; The EPROM in the SBC6120 is only 8K twelve bit words, so the entire code 62 ; for BTS6120 must fit within fields zero and one. While it's executing, 63 ; however, there is a full 32K of panel RAM available for BTS6120. Currently 64 ; BTS6120 doesn't use fields two thru seven of panel RAM and these are free. 65 ; They could be used by an OS/8 program via the Copy Memory PR0 function, if 66 ; desired. 67 68 ; FIELD 0 69 ; Page Usage 70 ; ----- ---------------------------------------------------------------------- 71 ; 00000 data & initialized constants 72 ; 00200 SYSINI part 2, later overwritten by the command buffer 73 ; 00400 command line parsing & error reporting routines 74 ; 00600 RePeat, Terminal, VErsion and HElp commands 75 ; 01000 Examine and Deposit commands 76 ; 01200 examine and deposit subroutines 77 ; 01400 Block Move, ChecKsum, Clear and Fill Memory commands 78 ; 01600 Word Search and Breakpoint List commands 79 ; 02000 Breakpoint set and Remove commands and breakpoint subroutines 80 ; 02200 Proceed, Continue, SIngle step, TRace, Reset ans EXecute commands 81 ; 02400 Boot sniffer, Boot, 82 ; 02600 Partition Map command, and Disk Formatter Pass 1 83 ; 03000 Disk formatter Pass 2, Disk Format, and RAM Disk Format commands 84 ; 03200 BIN (binary paper tape image) loader and LP command 85 ; 03400 Disk (RAM and IDE) Dump and Load commands 86 ; 03600 Disk buffer ASCII dump and load subroutines 87 ; 04000 Partition Copy command 88 ; 04200 89 ; 04400 90 ; 04600 91 ; 05000 92 ; 05200 93 ; 05400 94 ; 05600 95 ; 06000 96 ; 06200 SIXBIT, ASCII, decimal, and octal terminal output 97 ; 06400 address (15 bit) arithmetic, parsing and output 98 ; 06600 keyword scaner and search, decimal and octal input 99 ; 07000 miscellaneous formatted terminal input and output 100 ; 07200 command line scanner 101 ; 07400 terminal input and output primitives 102 ; 07600 control panel entry and context save 103 104 ; FIELD 1 105 ; Page Usage 106 ; ----- ---------------------------------------------------------------------- 107 ; 10000 SYSINI part 1, later overwritten by field 1 variables 108 ; 10200 ROM monitor call (PR0) processor 109 ; 10400 RAM disk R/W, pack/unpack, and battery test routines 110 ; 10600 RAM disk address calculation and diagnostic tests 111 ; 11000 IDE disk initialization and ATA IDENTIFY DEVICE command 112 ; 11200 IDE sector read/write, LBA calculation, wait for READY or DRQ 113 ; 11400 IDE read/write sector buffer, initialize partition map 114 ; 11600 Partition map functions, IDE I/O PR0 call, read/write IDE registers 115 ; 12000 I/O buffer management, Memory Moce PR0 call, cross field calling 116 ; 12200 117 ; 12400 118 ; 12600 119 ; 13000 120 ; 13200 121 ; 13400 to 17377 are used by command tables, error messages and help text 122 ; 17400 to 17777 are used as a temporary buffer for disk I/O PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 3 Edit History BTS6120.PLX 123 .TITLE Edit History 124 125 126 ; 1 -- Change documentation of ER and DR commands to reflect the 127 ; new format (E and D " character between the 176 ; address (or register name) and the data (instead of a 177 ; space). 178 ; 179 ; 21 -- Update the BM command to use the new 15 bit addressing. 180 ; This now allows transfers to copy more than 4K, and to 181 ; cross field boundries. Also, make it illegal for the source 182 ; address to increment out of field 7. 183 ; 184 ; 22 -- Update the CK command for 15 bit addressing. This makes it 185 ; possible to checksum more than 4K of memory in one command. 186 ; 187 ; 23 -- Move the RDMEM routine to page 6400 (the page it was on had PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 4 Edit History BTS6120.PLX 188 ; 0 words free!). 189 ; 190 ; 24 -- Invent a RAM location KEY and store the WS command search 191 ; key there (not in VALUE). This fixes problems with the WS 192 ; command interacting with RDMEM. 193 ; 194 ; 25 -- Make the WS command apply the mask to the search key too. 195 ; Also, make WS poll the keyboard so that the operator may 196 ; control-C out of a long search. 197 ; 198 ; 26 -- Fix a few bugs in the BM command (these only occur when 199 ; transfers cross memory fields). Also change the syntax of 200 ; the command to accept a source address range (instead of 201 ; a destination address range). 202 ; 203 ; 27 -- Change the name of the SI command to TR (TRace). Then change 204 ; the old SN (single instruction with no register output) to 205 ; be SI. 206 ; 207 ; 30 -- Re-write the examine register to to save space. 208 ; 209 ; 31 -- Move all the register name strings to the text page. 210 ; Re-write the register typeout routines to take less space. 211 ; 212 ; 32 -- Make the examine command accept multiple operands seperated 213 ; by commas. 214 ; 215 ; 33 -- Implement the memory diagnostic routines (address test and 216 ; data test) and the MD command to execute them. 217 ; 218 ; 34 -- Invent the DEVERR routine to report device errors. Also, 219 ; re-write MEMERR to share as much code with deverr as 220 ; possible. 221 ; 222 ; 35 -- Make the memory data and address diagnostics interruptable 223 ; with a control-C (since they take a long time to execute). 224 ; 225 ; 36 -- Invent the REGTST routine to test hardware registers. This 226 ; is used to implement hardware diagnostics. 227 ; 228 ; 37 -- Implement the DPTEST routine to test hardware data paths 229 ; for faults. 230 ; 231 ; 40 -- Implement the EX command (to execute IOT instructions). 232 ; 233 ; 41 -- Implement the basic BIN loader routine (BINLOD). 234 ; 235 ; 42 -- Re-arrange code to more tightly pack memory pages (and free 236 ; another page of memory). 237 ; 238 ; 43 -- Re-define all IOT instructions to agree with the actual 239 ; hardware. 240 ; 241 ; 44 -- Re-write the CP trap and system initialization routines to 242 ; work correctly with the latest hardware design (including 243 ; the auto-start switches). 244 ; 245 ; 45 -- Add the HALT instruction trap routine (it types out the 246 ; message %HALTED @ faaaa)... 247 ; 248 ; 46 -- Ask the user before running diagnostics at startup (even 249 ; if he has enabled them via the auto-start switches). 250 ; 251 ; 47 -- Implement the TRAP routine to handle trapped IOTs. 252 ; PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 5 Edit History BTS6120.PLX 253 ; 50 -- Add the code to emulate a KL8E (via trapped IOTs). 254 ; 255 ; 51 -- Fix a bug in the CP trap routine which prevented it from 256 ; recognizing SI traps correctly. 257 ; 258 ; 52 -- Make sure the TR command types out the contents of the IR 259 ; correctly (add a CLA in an opportune location). 260 ; 261 ; 53 -- Make sure the CONT routine correctly restores the CPU 262 ; registers (add another CLA !!!). 263 ; 264 ; 54 -- Revise the monitor command summary in the introduction to 265 ; be more up to date. 266 ; 267 ; 55 -- Remove the optional count operand from the TR (trace) 268 ; command and always make it execute one instruction instead. 269 ; (The user can always combine it with the RP command to get 270 ; more than one.) 271 ; 272 ; 56 -- Make the BPT instruction use opcode 6077... 273 ; 274 ; 57 -- The BPT instruction is a trapped instruction, but the 275 ; CP entry routine removes breakpoints before the TRAP 276 ; routine is called. Thus TRAP can nenver identify a BPT 277 ; instruction. Solution: don't remove breakpoints in the 278 ; CP routine, but do it in all the routines that it calls 279 ; (except TRAP, of course). 280 ; 281 ; 60 -- Make the BPTINS routine call RDMEM instead of reading memory 282 ; itself. 283 ; 284 ; 61 -- Fix the P command so that other commands after it (after 285 ; a ';') will work too. Also, move the P command to the next 286 ; memory page (with CONT) to free space. 287 ; 288 ; 62 -- Add the BT command to run the disk bootstrap (which 289 ; presently just types a message to the effect that the disk 290 ; bootstrap is not implemented). 291 ; 292 ; 63 -- Implement the following routines: CLRCPU (to clear the 293 ; user's CPU registers in RAM), CLRIO (to clear all I/O 294 ; devices via a CAF), and CLRBUS (to clear the external 295 ; bus by asserting the INITIALIZE signal). 296 ; 297 ; 64 -- Add the MR command to perform a master reset of the CPU and 298 ; hardware... 299 ; 300 ; 65 -- Insure that the terminal flag is set after the CLRIO routine 301 ; (to avoid hanging the monitor)... 302 ; 303 ; 66 -- Define the PRL instruction (READ2 FTPIEB) to pulse the CPU 304 ; RUN/HALT flip-flop. 305 ; 306 ; 67 -- Invent the INIT routine to initialize all hardware which is 307 ; important to the monitor (and call it after a hardware reset 308 ; command). 309 ; 310 ; 70 -- Make the CONTinue routine clear the console status and set 311 ; the RUN flip-flop. 312 ; 313 ; 71 -- Invent the IN (initialize) command to completely initialize 314 ; all hardware and software (it is equivalent to pressing the 315 ; RESET button !). 316 ; 317 ; 72 -- Be sure the SLU mode gets initialized properly... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 6 Edit History BTS6120.PLX 318 ; 319 ; 73 -- Modify the CONOUT routine to timeout the console printer 320 ; flag and force characters out if it dosen't set after a 321 ; reasonable time (this prevents monitor hangs while debugging 322 ; programs which clear the flag). 323 ; 324 ; 74 -- Make the hardware diagnostic routine execute a master 325 ; reset (i.e. the CLEAR routine) after they are finished 326 ; (since they may leave the hardware in a strange state). 327 ; 328 ; 75 -- Change the monitor prompting character to $. 329 ; 330 ; 76 -- Implement the LP command to load paper tapes from the 331 ; console... 332 ; 333 ; 77 -- Initialize both the SLU mode and baud rate correctly when 334 ; the system is reset... 335 ; 336 ; 100 -- Go through the source and put .ORGs in places where they 337 ; have been left out... 338 ; 339 ; After almost 20 years, restart development for the SBC6120 board! 340 ; 341 ; 101 -- A "real" TLS instruction (as the SBC6120 has) doesn't clear 342 ; the AC, the way a "fake" TLS (implemented by a 6101 PIE 343 ; WRITE) does. This causes no end of problems for CONOUT and 344 ; everything that calls it! 345 ; 346 ; 102 -- Remove the terminal filler code (there's no terminal on the 347 ; planet that requires filler characters any more!) 348 ; 349 ; 103 -- Remove the TTY parameters table at TTYTAB. It's still 350 ; possible to set the TTY width and page size with the TW and 351 ; TP commands, but they now default to zero (disabled). 352 ; 353 ; 104 -- Remove the place holder code for IOT trapping and KL8 354 ; emulation. It was never used. 355 ; 356 ; 105 -- Expand the command line buffer to occupy all of RAM page 1, 357 ; and make the stack always fill whatever remains of page 0. 358 ; 359 ; 106 -- Rewrite to use the HM6120 built in hardware stack. 360 ; 361 ; 107 -- Some of the old SYSINI code was still left lying around, 362 ; and this code would clear RAM on startup. This is now a 363 ; bad idea, since it erases all our page zero vectors! 364 ; 365 ; 110 -- Unlike the 6100 software stack simulation, the 6120 PAC1/2 366 ; instructions don't clear the AC. Add a few CLAs to take 367 ; care of this difference. 368 ; 369 ; 111 -- The 6120 stack post decrements after a PUSH, so the stack 370 ; pointer needs to be initialized to the top of the stack, 371 ; not the TOS + 1... 372 ; 373 ; 112 -- Optimize the page zero constants based on the references 374 ; shown in the CREF listing. Add page zero constants for 375 ; popular numerical constants... 376 ; 377 ; 113 -- Do away with the SYNERR link (it's now the same as ZCOMERR). 378 ; 379 ; 114 -- Replace the ERROR link with a simple JMS @ZERROR, and 380 ; reclaim the page 0 RAM it used... 381 ; 382 ; 115 -- Do away with RAMINI and the page zero initialization code. PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 7 Edit History BTS6120.PLX 383 ; It's no longer necessary, since we now initialize all RAM 384 ; from EPROM at startup. 385 ; 386 ; 116 -- Do away with the separate IF, DF and L "registers" and treat 387 ; everything as part of the PS (aka flags) register. 388 ; 389 ; 117 -- Move around, clean up, and generally re-organize the 390 ; E, D, BM, CK, CM and FM commands. 391 ; 392 ; 120 -- Change the examine register command to ER and the deposit 393 ; register command to DR. Make some other general changes 394 ; to the syntax of the E and D commands (e.g. require commas 395 ; between multiple items in the deposit list). 396 ; 397 ; 121 -- Change the address range delimiter to "-". 398 ; 399 ; 122 -- Move around, clean up and generally re-organize another 400 ; block of code; this time everything concerned with break 401 ; points, continue, start, proceed, and CP traps. 402 ; 403 ; 123 -- CONT: needs to use RSP1 to save the monitor's stack pointer, 404 ; not LSP1 !!! 405 ; 406 ; 124 -- If a transition occurs on CPREQ L while we're in panel mode, 407 ; then the 6120 sets the BTSTRP flag in the panel status 408 ; anyway. This will cause an immediate trap back to panel 409 ; mode the instant we try to continue or proceed. The answer 410 ; is to do a dummy PRS before continuing. 411 ; 412 ; 125 -- Move around, clean up and generally re-organize the 413 ; remainder of the code. Move messages and command tables to 414 ; field 1. Change message strings to packed ASCIZ instead of 415 ; SIXBIT. 416 ; 417 ; 126 -- The packed ASCIZ OUTSTR routine still has a few non-stack 418 ; holdovers - a JMS to OUTCHR and a JMP @OUTSTR to return. 419 ; This causes no end of strange symptoms! 420 ; 421 ; 127 -- Use the new \d and \t string escape feature of PALX to put 422 ; the system generation time in the monitor. 423 ; 424 ; 130 -- Start adding RAM disk support - add DISKRD and DISKWR 425 ; 426 ; 131 -- Add MCALL (monitor call, via 6120 PR0 trapped IOT) 427 ; 428 ; 132 -- Add DISKRW ROM call function for OS/8 RAM disk driver 429 ; 430 ; 133 -- We're starting to run short of room on page zero, so move 431 ; some of the temporary variables that are used only by one 432 ; routine to the same page as that routine. Now that we're 433 ; running out of RAM this is possible. 434 ; 435 ; 134 -- Move the breakpoint tables to page 1, field zero and make 436 ; the command buffer that much (about 24 words) smaller. 437 ; Since the breakpoint tables are only addressed indirectly 438 ; anyway, this hardly made a difference to the code... 439 ; 440 ; 135 -- Fold the MEMERR routine into DANDV and simplify it a little 441 ; to save space - just type the good and bad data, and don't 442 ; bother with typing the XOR... 443 ; 444 ; 136 -- TOCT3 types the three most significant digits, not the three 445 ; least significant ! Oooppppssssss.... 446 ; 447 ; 137 -- DDUMP uses COUNT to count the words output, but TOCT4 uses PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 8 Edit History BTS6120.PLX 448 ; it to count digits. Oooppssss... 449 ; 450 ; 140 -- Invent the BSETUP routine and rewrite the break point 451 ; functions to use it. This saves many words of memory. 452 ; 453 ; 141 -- Add the Format Disk (FD) command to "format" RAM disk. This 454 ; is really more of a memory diagnostic than a formatter, but 455 ; the name seems appropriate. 456 ; 457 ; 142 -- CALCDA has a off-by-one error that makes it fail for the 458 ; last 21 sectors of the RAM disk. 459 ; 460 ; 143 -- Invent the CONFRM routine and use it to make the Format Disk 461 ; command ask for confirmation before destroying anything. 462 ; 463 ; 144 -- Add the Disk downLoad command (DL). This accepts RAM disk 464 ; images in exactly the same format as output by DD. 465 ; 466 ; 145 -- Add the H (help) command and a very primitive help system 467 ; (it just types out a screen of one line descriptions for 468 ; every monitor command!). 469 ; 470 ; 146 -- Add a trace function to the DISKRW MCALL. 471 ; 472 ; 147 -- Accidentally typed a couple of JMSes when I should have 473 ; typed .PUSHJ! 474 ; 475 ; 150 -- In DLOAD, we have to use SAVCHR to get the break character 476 ; from OCTNW, not GET. 477 ; 478 ; 151 -- IOCLR L (generated by CAF) also clears the console UART, 479 ; which causes garbage if we happen to be transmitting a 480 ; character at the time. The easiest way to fix this is to 481 ; make the CLEAR routine wait for the console flag to set 482 ; (i.e. the transmitter is done) before executing a CAF. 483 ; 484 ; 152 -- The RAM DISK test at TSTUNI doesn't work if the DX pull 485 ; down resistors are removed because it fails to mask the 486 ; SRAM data to eight bits... 487 ; 488 ; 153 -- Add the infrastructure which allows the code to be split 489 ; between field 0 and 1, then move all the low level RAM disk 490 ; I/O and ROM call processing code to field 1. 491 ; 492 ; 154 -- Add SP1 and SP2 to the REGLST output (but it's still not 493 ; possible to deposit in them or examine them individually). 494 ; 495 ; 155 -- Move the ROM checksums from location 7600 to 0200. 496 ; 497 ; 156 -- Change the hardware so that the TIL311 is loaded via the 498 ; 6120 WSR (Write to Switch Register) instruction. 499 ; 500 ; 157 -- Begin adding basic IDE/ATA support. 501 ; 502 ; 160 -- Add the GETRDS (Get RAM Disk Size) and GETBAT (get backup 503 ; battery status) PR0 functions. 504 ; 505 ; 161 -- Fix a few bugs in the IDE code, and the basic drive 506 ; identification on bootup now works. 507 ; 508 ; 162 -- When programming the 8255 IDE interface, we have to change 509 ; the mode (input vs output) _before_ we set up the address 510 ; bits. If we don't then the address bits get cleared by 511 ; the #$&(*# 8255 when the mode is changed! 512 ; PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 9 Edit History BTS6120.PLX 513 ; 163 -- Add Get and Set Disk Partition mapping PR0 subfunctions. 514 ; 515 ; 164 -- Add Get IDE Disk Size subfunction to PR0. 516 ; 517 ; 165 -- Add the Copy Memory subfunction to PR0. 518 ; 519 ; 166 -- Add the last missing bits of IDE disk I/O. We're now ready 520 ; to try out the OS/8 device handler. 521 ; 522 ; 170 -- INIPMP needs to do a CLL to ensure that the link is in a 523 ; known state - otherwise it can sometimes quit too soon! 524 ; 525 ; 171 -- Extend the BOOT command to boot either IDE or RAM disk. 526 ; Add the "boot sniffer" to determine whether a volume 527 ; contains a real bootstrap and use it to make "B" with no 528 ; arguments search for a bootable volume (just like a real 529 ; computer!). 530 ; 531 ; 172 -- The disk download routine needs to call PNLBUF before it 532 ; attempts to write the buffer... 533 ; 534 ; 173 -- Make illegal PR0 functions print a message and return to 535 ; BTS6120 command level. This solves the problem of how to 536 ; skip over the arguments for a call we don't understand. 537 ; 538 ; 174 -- Make the MR (master reset) command initialize the IDE 539 ; drive and reset the partition map. 540 ; 541 ; 175 -- Add the PM command to edit/view the disk partition map. 542 ; 543 ; 176 -- Completely rewrite the RAM disk formatter code to create 544 ; two commands, RF to format a RAM disk an DF to format an 545 ; IDE disk partition. 546 ; 547 ; 177 -- PMEDIT screws up the disk LUN - there's a DCA that should 548 ; have been a TAD! 549 ; 550 ; 200 -- Fix a few bugs in the DF and RF routines - FMTARG is missing 551 ; a .POPJ, and the unit number gets corrupted in FMTARG 552 ; by the TOCT4S routine, which uses WORD. 553 ; 554 ; 201 -- The pin that corresponds to A17 on a 512K chip is an 555 ; alternate chip select on the 128K chips. Worse, this extra 556 ; chip select is active HIGH, which means that A17 must always 557 ; be set before the 128K chips will do anything! 558 ; 559 ; 202 -- Clean up all the help messages and make sure they agree 560 ; with the current state of all the commands. 561 ; 562 ; 203 -- Do away with F1CALL and create PUSHJ1 instead. Both allow 563 ; field 0 routines to call field 1, however the new one takes 564 ; one less word of code at the point of the call, which 565 ; helps a lot on some pages where words are tight. 566 ; 567 ; 204 -- Invent a few more page zero constants and use them to help 568 ; out on a few more pages where space is tight. 569 ; 570 ; 205 -- Make the disk related commands (DL, DD, and DF) verify that 571 ; an IDE disk is really present by checking for DKSIZE != 0. 572 ; Also make the DISKRW PR0 call return error -1 if no disk 573 ; is attached. 574 ; 575 ; [Start porting to the SBC6120 model 2 hardware] 576 ; 577 ; 206 -- Remove all the bicolor LED stuff - it doesn't exist in PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 10 Edit History BTS6120.PLX 578 ; the SBC6120 model 2. 579 ; 580 ; 207 -- The model 2 schematic accidentally switched CS1FX/CS3FX 581 ; and DIOR/DIOW in the IDE interface. Modify the code to 582 ; paramaterize all IDE interface bits and then chage these 583 ; parameters to agree with the real hardware. 584 ; 585 ; 210 -- Remove all the unnecessary CLAs after PPI instructions 586 ; (in the model 2, these IOTs all clear the AC). 587 ; 588 ; 211 -- Fix the timeouts for the console flag and the LP command 589 ; so they're reasonable given the 4.9152Mhz clock of the 590 ; SBC6120 model 2. 591 ; 592 ; [SBC6120 now runs on the Model 2 hardware!] 593 ; 594 ; 212 -- Fix a nasty bug in the LBA calculation! 595 ; 596 ; 213 -- Fix TDECNW to handle unsigned numbers up to 4095 597 ; 598 ; 214 -- Change the "RAM: " in the RAM disk message to "NVR:" 599 ; to avoid confusion with the main memory.. 600 ; 601 ; 215 -- Add the PC (partition copy) command. 602 ; 603 ; [End of monitor edit history] 604 0215 VERSION=215 ; latest edit number PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 11 SBC6120 IOTs and Definitions BTS6120.PLX 605 .TITLE SBC6120 IOTs and Definitions 606 607 608 ; The console terminal interface of the SBC6120 is actually straight -8 609 ; compatible, which is a proper subset of the KL8E except that the KCF, TFL, 610 ; KIE and TSK (or SPI, depending on which manual you read!) instructions are 611 ; omitted. Console interrupts are permanently enabled, as they were in the 612 ; original PDP-8. The console interface in the SBC6120 DOES NOT use a 6121, 613 ; so there'll be none of this skip-on-flag-and-clear-it nonsense with KSF or 614 ; TSF! 615 6031 KSF=6031 ; Skip of console receive flag is set 616 6032 KCC=6032 ; Clear receive flag and AC 617 6034 KRS=6034 ; OR AC with receive buffer and DON't clear the flag 618 6036 KRB=6036 ; Read receive buffer into AC and clear the flag 619 6041 TSF=6041 ; Skip if the console transmit flag is set 620 6042 TCF=6042 ; Clear transmit flag, but not the AC 621 6044 TPC=6044 ; Load AC into transmit buffer, but don't clear flag 622 6046 TLS=6046 ; Load AC into transmit buffer and clear the flag 623 624 ; 8255 PPI Interface IOTs... 625 6470 PRPA=6470 ; read PPI port A 626 6471 PRPB=6471 ; " " " B 627 6472 PRPC=6472 ; " " " C 628 6473 PRCR=6473 ; " " control register 629 6474 PWPA=6474 ; write PPI port A 630 6475 PWPB=6475 ; " " " B 631 6476 PWPC=6476 ; " " " C 632 6477 PWCR=6477 ; " " control register 633 634 ; Other SBC6120 instructions... 635 6440 POST=6440 ; Display a 4 bit POST code 636 6236 BPT=PR3 ; Breakpoint trap instruction 637 638 ; Special ASCII control characters that get used here and there... 639 0000 CHNUL=000 ; A null character (for fillers) 640 0003 CHCTC=003 ; Control-C (Abort command) 641 0007 CHBEL=007 ; Control-G (BELL) 642 0010 CHBSP=010 ; Control-H (Backspace) 643 0011 CHTAB=011 ; Control-I (TAB) 644 0012 CHLFD=012 ; Control-J (Line feed) 645 0015 CHCRT=015 ; Control-M (carriage return) 646 0017 CHCTO=017 ; Control-O (Suppress output) 647 0021 CHXON=021 ; Control-Q (XON) 648 0022 CHCTR=022 ; Control-R (Retype command line) 649 0023 CHXOF=023 ; Control-S (XOFF) 650 0025 CHCTU=025 ; Control-U (Delete command line) 651 0033 CHESC=033 ; Control-[ (Escape) 652 0177 CHDEL=177 ; RUBOUT (Delete) 653 654 ; OPR microinstructions that load the AC with various special constants... 655 7200 NL0000=CLA ; all models 656 7201 NL0001=CLA IAC ; all models 657 7326 NL0002=CLA CLL CML RTL ; all models 658 7332 NL2000=CLA CLL CML RTR ; all models 659 7350 NL3777=CLA CLL CMA RAR ; all models 660 7330 NL4000=CLA CLL CML RAR ; all models 661 7352 NL5777=CLA CLL CMA RTR ; all models 662 7346 NL7775=CLA CLL CMA RTL ; all models 663 7346 NLM3=NL7775 ; all models 664 7344 NL7776=CLA CLL CMA RAL ; all models 665 7344 NLM2=NL7776 ; all models 666 7240 NL7777=CLA CMA ; all models 667 7240 NLM1=NL7777 ; all models 668 7325 NL0003=CLA STL IAC RAL ; PDP-8/I and later 669 7307 NL0004=CLA CLL IAC RTL ; PDP-8/I and later PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 12 SBC6120 IOTs and Definitions BTS6120.PLX 670 7327 NL0006=CLA STL IAC RTL ; PDP-8/I and later 671 7333 NL6000=CLA STL IAC RTR ; PDP-8/I and later 672 7203 NL0100=CLA IAC BSW ; PDP-8/E and later 673 7215 NL0010=CLA IAC R3L ; HM6120 only PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 13 SBC6120 Memory Mapping Hardware BTS6120.PLX 674 .TITLE SBC6120 Memory Mapping Hardware 675 676 677 ; The SBC6120 has three memory subsystems - 64K words of twelve bit RAM, 678 ; 8K words of 12 bit EPROM (actually the EPROM is 16 bits wide, but the 679 ; hardware just throws away the extra four bits), and up to 2Mb of 8 bit 680 ; battery backed up SRAM for a RAM disk. 681 ; 682 ; The HM6120 on the other hand, has only two memory spaces - panel memory 683 ; and main memory, and each of these is limited to 32K words. The SBC6120 684 ; implements a simple memory mapping scheme to allow all three memory 685 ; subsystems to fit in the available address space. Up to four different 686 ; memory maps are possible, although only three are currently implemented. 687 ; 688 ; The memory map in use is selected by four IOT instructions, MM0, MM1 689 ; MM2 and (what else) MM3. Memory map changes take place immediately with 690 ; the next instruction fetch - there's no delay until the next indirect JMP 691 ; the way there is with a CIF instruction. 692 ; 693 ; The four memory maps implemented by the SBC6120 are: 694 ; 695 ; * Map 0 uses the EPROM for all direct memory accesses, including instruction 696 ; fetch, and uses the RAM for all indirect memory accesses. This is the 697 ; mapping mode set by the hardware after a power on reset. 698 ; 699 ; * Map 1 uses the RAM for all direct memory accesses, including instruction 700 ; fetch, and uses the EPROM for all indirect memory references. This mode 701 ; is the "complement" of map 0, and it's used by the panel memory bootstrap 702 ; to copy the EPROM contents to RAM. 703 ; 704 ; * Map 2 uses the RAM for all memory accesses, regardless. This is the 705 ; mapping mode used during almost all operation after booting. 706 ; 707 ; * Map 3 is the same as map 2, except that the RAM disk memory is enabled 708 ; for all indirect accesses. BEWARE - RAM disk memory is only eight bits 709 ; wide and reads and writes to this memory space only store and return the 710 ; lower byte of a twelve bit word. This mode is used only while we're 711 ; accessing the RAM disk. 712 ; 713 ; IMPORTANT! The memory mapping mode affects only 6120 control panel memory 714 ; accesses. Main memory is always mapped to RAM regardless of the mapping 715 ; mode selected. 716 717 ; DIRECT INDIRECT 718 ; -------- -------- 719 6400 MM0=6400 ; EPROM RAM (automatically selected by a RESET) 720 6401 MM1=6401 ; RAM EPROM (used during system initialization) 721 6402 MM2=6402 ; RAM RAM (used almost all the time) 722 6403 MM3=6403 ; RAM DISK (used to access RAM disk only) PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 14 System Startup and POST Codes BTS6120.PLX 723 .TITLE System Startup and POST Codes 724 725 726 ; Getting the SBC6120 monitor up and running after a power up is a little 727 ; harder than we might wish. Our first problem is that we're actually 728 ; executing code from the EPROM now, and a lot of the usual PDP-8 techniques 729 ; of "self manipulation" (e.g. a JMS instruction!) won't work because the 730 ; program store isn't writable. Our second problem is that all of panel 731 ; fields 0 and 1 are mapped to EPROM, and there's no RAM anywhere in these 732 ; fields at all, not even in page zero. 733 ; 734 ; Our final problem is that we can't even be sure that all the hardware is 735 ; working correctly at this point. If some part isn't working, for example, 736 ; the RAM, we'd like to provide at least some kind of diagnostic message 737 ; before we end up lost forever. The minimum set of system components that 738 ; this monitor needs to have working before it can print a prompt and execute 739 ; commands is 1) the CPU, 2) the ROM, 3) the RAM, and 4) the console terminal. 740 ; 741 ; This means we need to accomplish two things during a cold boot - first, 742 ; to execute a simple power on self test (aka POST), and second, to copy this 743 ; monitor's code from EPROM to panel RAM where we can execute it without 744 ; restriction. 745 ; 746 ; The SBC6120 has a single digit LED display that the program can set, via 747 ; the POST instruction. At the beginning of each step in testing and 748 ; initialization we set this digit to a particular value, and then if that 749 ; test or startup part fails, we simply halt and the display remains at the 750 ; last value set. The digits and their associated failure modes are: 751 ; 752 ; 7 - CPU failure (or it's not a 6120) 753 ; 6 - panel RAM bootstrap failure 754 ; 5 - RAM checksum failure 755 ; 4 - memory test failure 756 ; 3 - currently unused (reserved for 6121 failure?) 757 ; 2 - console terminal failure 758 ; 1 - panel monitor running (success!) 759 ; 0 - user (main memory) program running PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 15 System Startup, Part 1 BTS6120.PLX 760 .TITLE System Startup, Part 1 761 762 763 ; This code lives in field one, page zero of the EPROM and it's the first 764 ; thing that gets executed after a power on clear. Its main job is to get 765 ; the SBC6120 memory initialized, which it does it with these steps: 766 ; 767 ; 1 - execute a simple CPU test 768 ; 2 - execute a very simple RAM test 769 ; 3 - copy EPROM to panel RAM 770 ; 4 - verify the firmware checksum 771 ; 5 - execute an extensive test on the remaining memory 772 ; 773 ; After it's done, it jumps to the second phase of initialization, which 774 ; lives in field zero. When this code starts we're in memory mapping mode 775 ; zero, which means that all instructions are being executed from EPROM and 776 ; RAM can be addressed only indirectly. When it finishes, all code will be 777 ; in panel RAM and we'll be running in memory mapping mode two, which means 778 ; that all memory accesses go to RAM and the EPROM is inaccesible. 779 ; 780 ; After system initialization is complete, all this code is over written 781 ; with page zero variables and storage for field one. 782 10200 .FIELD 1 783 10000 .PAGE 0 784 785 ; Location zero of field 1 (and field 0, for that matter) must contain a 786 ; zero for the checksum routine. See the code at ROMCHK: for a discussion. 787 10000 0000 0000 788 789 ; The first step is the CPU test, which is trivially simple. We just 790 ; verify that we're actually running on a HM6120 and let it go at that... 791 10001 6447 SYSINI: POST+7 ; set the POST code to 7 792 10002 7215 CLA IAC R3L ; Only a 6120 has the R3L instruction 793 10003 1177 TAD [-10] ; Did we get the right answer? 794 10004 7440 SZA ; ??? 795 10005 5005 JMP . ; Nope - halt forever 796 797 ; Before we copy the boot code to panel RAM, do a primitive (and it's really 798 ; primitive!) test of RAM just to make sure there's something there we can 799 ; read and write. Remember that at this point we're using memory map 0, so 800 ; all direct references are to EPROM, but all indirect references are to RAM. 801 10006 6446 POST+6 ; set the POST code to six 802 10007 6276 SPD ; be sure we're accessing panel memory now! 803 10010 7200 CLA ; ... 804 10011 1176 TAD [2525] ; write an alternating bit pattern 805 10012 3575 DCA @[ROMCPY] ; ... to RAM location zero 806 10013 1174 TAD [5252] ; and write the complement to location 1 807 10014 3573 DCA @[ROMCPY+1] ; ... 808 10015 1575 TAD @[ROMCPY] ; now read them both back 809 10016 1573 TAD @[ROMCPY+1] ; and add them up 810 10017 7040 CMA ; and the result should be -1 811 10020 7440 SZA ; ???? 812 10021 5021 JMP . ; low RAM failure 813 814 ; Copy all of the EPROM moving code, which is six words starting at the label 815 ; ROMCPY, from EPROM to exactly the same location in RAM. There's no way to 816 ; use a loop to do this since we don't have any RAM that we can access directly 817 ; to use as a pointer! 818 10022 1040 TAD ROMCPY ; copy this one word from EPROM 819 10023 3575 DCA @[ROMCPY] ; ... to RAM 820 10024 1041 TAD ROMCPY+1 ; and do it for the entire routine 821 10025 3573 DCA @[ROMCPY+1] ; ... 822 10026 1042 TAD ROMCPY+2 ; ... 823 10027 3572 DCA @[ROMCPY+2] ; ... 824 10030 1043 TAD ROMCPY+3 ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 16 System Startup, Part 1 BTS6120.PLX 825 10031 3571 DCA @[ROMCPY+3] ; ... 826 10032 1044 TAD ROMCPY+4 ; ... 827 10033 3570 DCA @[ROMCPY+4] ; ... 828 10034 1045 TAD ROMCPY+5 ; ... 829 10035 3567 DCA @[ROMCPY+5] ; ... 830 831 ; Now it gets tricky. At this instant we're still running in EPROM, and the 832 ; first two instructions (at ROMCP0) get executed from EPROM. As soon as we 833 ; execute the MM1 at ROMCPY:, however, the very next instruction is fetched 834 ; from RAM. This should work, because the previous code has copied the six 835 ; words that make up the ROMCPY loop from EPROM to exactly the same location 836 ; in RAM. 837 ; 838 ; The loop the copies an entire field from EPROM to RAM, executing from RAM 839 ; the whole time. It actually over writes itself in the process, but since it 840 ; over writes itself with a copy of the exact same code we should be OK. By 841 ; the time it falls thru the ISZ at the end of the loop, the subsequent code 842 ; should exist in RAM. 843 ; 844 ; After copying field 1, we switch to field zero and jump back to ROMCP0 845 ; to do it again. Although the first time thru we executed ROMCP0 from EPROM, 846 ; the second time thru we execute it from RAM, which is OK because it got 847 ; copied during the first pass. 848 ; 849 ; Say goodbye to memory map 0 - we'll never need it again! 850 851 ; This loop copies all of a field, except location 0, from EPROM to RAM. 852 10036 7201 ROMCP0: CLA IAC ; always start with location 1, not zero 853 10037 3566 DCA @[0] ; save the address pointer here 854 10040 6401 ROMCPY: MM1 ; (1) address RAM directly, EPROM indirectly 855 10041 1400 TAD @0 ; (2) and load a word from EPROM 856 10042 6402 MM2 ; (3) address RAM for all memory accesses 857 10043 3400 DCA @0 ; (4) and store the word in RAM 858 10044 2000 ISZ 0 ; (5) have we done an entire field? 859 10045 5040 JMP ROMCPY ; (6) nope - keep copying 860 10046 6214 RDF ; which field did we just copy? 861 10047 6201 CDF 0 ; assume that we'll copy field zero next 862 10050 7640 SZA CLA ; but did we just copy field zero? 863 10051 5036 JMP ROMCP0 ; no - go copy it 864 865 ; When we leave this loop, we're using memory map 2 which means panel RAM 866 ; is used everywhere and the EPROM is inaccessible. We'll stay in this mapping 867 ; mode forever, except when we're accessing the RAM disk. 868 869 ; Each field of the panel ROM contains a 12 bit checksum, put there by the 870 ; PDP2HEX program and calculated so that the sum of all words in the field, 871 ; including the checksum word, will be zero. Now we'll compute and verify the 872 ; checksum of both RAM fields, which proves that our RAMs work, that the 873 ; EPROMS were programmed correctly, and that we copied them correctly. 874 ; 875 ; It might seem a better to do this before on the EPROMs before we've copied 876 ; them to RAM, but the answer is that it's just impossible to compute a 877 ; checksum using memory map 0 - there's no directly addressible RAM to use for 878 ; address pointers or for storing the sum! 879 ; 880 ; One last subtle point is that we're keeping an address pointer in location 881 ; zero of RAM, which wasn't in the EPROM when PDP2HEX calculated its checksum. 882 ; This actually works by accident (er - excuse me, "Design"), since we keep 883 ; our pointer in location zero of RAM, it will have the value zero when we 884 ; checksum it. Coincidentally, this is exactly the same value that's in 885 ; location zero of the ROM image. 886 887 ; This loop checksums one RAM field... 888 10052 6445 POST+5 ; set the POST code to five 889 10053 6211 CDF 1 ; checksum field 1 first PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 17 System Startup, Part 1 BTS6120.PLX 890 10054 7201 ROMCHK: CLA IAC ; and start with location 1 (skip zero) 891 10055 3000 DCA 0 ; ... 892 10056 1400 ROMCH0: TAD @0 ; add up another word from RAM 893 10057 2000 ISZ 0 ; have we done an entire field? 894 10060 5056 JMP ROMCH0 ; nope - keep adding 895 10061 7440 SZA ; yes - did the checksum pass? 896 10062 5062 JMP . ; RAM checksum failure 897 10063 6214 RDF ; get the field we just did 898 10064 6201 CDF 0 ; and assume we'll do field zero next 899 10065 7640 SZA CLA ; but did we really just do zero? 900 10066 5054 JMP ROMCHK ; no - go checksum it now 901 902 ; The next step is to run a memory test on the remaining fields (2 thru 7) 903 ; of panel memory and all fields of main memory. It's not a very sophisticated 904 ; test - it just writes each memory location with its address in the first pass 905 ; and then reads it back in the second, but it does prove that there's at least 906 ; some memory out there listening. 907 ; 908 ; Before we do that, however, we do an even simpler test to verify that the 909 ; panel data flag is working and that main memory and panel memory are two 910 ; separate and distinct memory spaces... 911 912 ; Make sure that panel memory and main memory are distinct... 913 10067 6444 POST+4 ; set the POST code to four 914 10070 7240 STA ; put -1 in location 0 of panel memory 915 10071 3566 DCA @[0] ; ... 916 10072 6266 CPD ; and then put 0 in the same location 917 10073 3566 DCA @[0] ; ... of main memory 918 10074 6276 SPD ; back to panel memory 919 10075 2566 ISZ @[0] ; and increment -1 920 10076 5076 JMP . ; if it doesn't skip something is wrong 921 922 ; Test all eight fields of main memory... 923 ; CLA ; and start testing with field zero 924 10077 6266 CPD ; address main memory again 925 10100 4112 MEMTS1: JMS FLDTST ; test this field, halt if it's bad 926 10101 7440 SZA ; have we wrapped around to field 0 again ? 927 10102 5100 JMP MEMTS1 ; no - test the next field 928 929 ; Then test only fields 2 thru 7 of panel memory... 930 10103 6276 SPD ; address panel memory this time 931 10104 1165 TAD [20] ; start testing with field 2 932 10105 4112 MEMTS2: JMS FLDTST ; test this field, halt if it's bad 933 10106 7440 SZA ; ... 934 10107 5105 JMP MEMTS2 ; ... 935 936 ; System initialization, part 1, is finished. The remainder of the code 937 ; lives in field zero... 938 10110 6203 CXF 0 939 10111 5564 JMP @[SYSIN2] 940 941 ; This subroutine will test one field of either main memory or panel memory. 942 ; It's a fairly simple minded test - it just writes each location with its 943 ; address in the first pass and then reads it back in the second pass. If the 944 ; test fails it just halts - there is no error return! 945 10112 0000 FLDTST: 0 ; enter here with the field in the AC 946 10113 1163 TAD [CDF 0] ; make a CDF instruction out of it 947 10114 3115 DCA .+1 ; and execute it inline 948 10115 7000 NOP ; gets over written with a CDF 949 10116 3000 DCA 0 ; reset the address pointer 950 10117 1000 FLDTS1: TAD 0 ; write each word with its address 951 10120 3400 DCA @0 ; ... 952 10121 2000 ISZ 0 ; have we done all 4K? 953 10122 5117 JMP FLDTS1 ; nope - keep going 954 10123 3000 DCA 0 ; yes - reset the address pointer PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 18 System Startup, Part 1 BTS6120.PLX 955 10124 1000 FLDTS2: TAD 0 ; and make another pass to test 956 10125 7041 CIA ; ... what we wrote 957 10126 1400 TAD @0 ; ... 958 10127 7440 SZA ; does this location contain the right value? 959 10130 5130 JMP . ; no - just halt 960 10131 2000 ISZ 0 ; yes - keep going for all 4K 961 10132 5124 JMP FLDTS2 ; ... 962 10133 6214 RDF ; get the data field we just tested 963 10134 1162 TAD [10] ; and increment it for the caller 964 10135 0161 AND [70] ; remove any overflow bits 965 10136 5512 JMP @FLDTST ; return the next field to the caller 966 10161 0070 10162 0010 10163 6201 10164 0201 10165 0020 10166 0000 10167 0045 10170 0044 10171 0043 10172 0042 10173 0041 10174 5252 10175 0040 10176 2525 10177 7770 967 10200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 19 System Startup, Part 2 BTS6120.PLX 968 .TITLE System Startup, Part 2 969 970 971 ; This routine is the second phase of system initialization, and it lives 972 ; in page one of field zero. It's called at the end of the first phase, and 973 ; it will: 974 ; 975 ; 1 - test and initialize any extra hardware (e.g. 6121 chips) 976 ; 2 - test and initialize the console terminal 977 ; 3 - initialize any RAM that needs it 978 ; 4 - print a sign on message 979 ; 5 - jump to the monitor restart address 980 ; 981 ; After this code finishes, the monitor is running and a prompt will have been 982 ; printed on the terminal. This code code gets overwritten immediately by the 983 ; monitor's command line buffer, which also lives in page 1 of field 0. 984 00200 .FIELD 0 985 00200 .PAGE 1 986 987 ; The PDP2HEX program (which converts BIN files into ROM images in Intel 988 ; HEX format) stores a checksum of ROM field 0 in location 00200, which will 989 ; later be used by the POST... 990 00200 ROMCK0: .BLOCK 1 991 992 ; Some space is reserved here for initializing the hardware, especially any 993 ; 6121 chips that might be lying around. We don't currently have any of those, 994 ; so we don't worry about it now. 995 00201 6443 SYSIN2: POST+3 ; set the POST code to three 996 997 ; The next stage in initialization is to test the console terminal. Since 998 ; the SBC6120 hardware doesn't have a loopback mode we can't really verify that 999 ; data is being sent and received correctly, but we can at least test that the 1000 ; flags set and clear at appropriate times. That way we'll know, at last, that 1001 ; we won't hang forever if we do a "TLS; JMP .-1" loop. 1002 00202 6442 POST+2 ; set the POST code to two 1003 00203 7200 CLA ; send a null character to the console 1004 00204 6046 TLS ; ... 1005 00205 6041 TSF ; and then wait for the flag to set 1006 00206 5205 JMP .-1 ; waiting forever, if necessary! 1007 00207 6042 TCF ; clear the console flag 1008 00210 6041 TSF ; and then test it again 1009 00211 7410 SKP ; good - it _isn't_ set! 1010 00212 5212 JMP . ; bad - it's still set, so the console fails 1011 00213 6046 TLS ; send another null 1012 00214 6041 TSF ; and be sure it sets one more time 1013 00215 5214 JMP .-1 ; ... 1014 1015 ; Now make sure we can clear the keyboard input flag, and that KCC also 1016 ; clears the AC. The latter proves that there is at least some hardware out 1017 ; there controlling the C lines for the console terminal, although it doesn't 1018 ; guarantee that we can receive data. 1019 00216 7240 STA ; Load the AC with -1 1020 00217 6032 KCC ; Clear the keyboard flag and the AC 1021 00220 7440 SZA ; Verify that the AC got cleared 1022 00221 5221 JMP . ; Nope - console test failed! 1023 00222 6031 KSF ; And test the keyboard flag 1024 00223 7410 SKP ; Good - it _isn't_ set! 1025 00224 5224 JMP . ; Bad - the keyboard test failed 1026 1027 ; Print a sign on message. 1028 00225 6441 SYSIN3: POST+1 ; the monitor is up and running now 1029 1030 1031 ; This code starts up the monitor/bootstrap after a system reset. It 1032 ; initializes the monitor RAM, sets up the stack, and jumps to the monitor PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 20 System Startup, Part 2 BTS6120.PLX 1033 ; entry point. Since we don't know how we came to be here, this code 1034 ; shouldn't make any assumptions about the current state of the hardware! 1035 00226 6203 CXF 0 ; Be sure the IB and DF are both zero 1036 00227 6276 SPD ; Address CP memory with indirect cycles 1037 00230 7200 CLA ; just in case... 1038 00231 1377 TAD [STACK] ; reset the 6120 stack pointer 1039 00232 6217 LSP1 ; ... 1040 1041 ; Set the control panel entry vector in 7777 to be a "JMP CPSAVE" instruction. 1042 ; We have to do this in a rather awkward way because PALX won't assemble a 1043 ; current page reference to CPSAVE unless we're actually on the same page as 1044 ; CPSAVE! 1045 00233 1376 TAD [CPSAVE&177 | 5200] 1046 00234 3775 DCA @[7777] 1047 1048 ; Do any RAM initialization that needs to be done... 1049 00235 1374 TAD [80.] ; the default terminal width is 80 1050 00236 3040 DCA WIDTH ; ... 1051 00237 3041 DCA LENGTH ; and automatic XOFF is disabled 1052 00240 6205 .PUSHJ @[CLRCPU] ; clear the saved user context 00241 5773 1053 00242 6205 .PUSHJ @[BPTCLR] ; clear the breakpoint tables 00243 5772 1054 00244 4502 JMS @ZPUSHJ1 ; (cross field call) 1055 00245 1513 INIPMP ; initialize the IDE disk partition map 1056 1057 ; Type out the system name... 1058 00246 6205 .PUSHJ @ZCRLF ; First start on a new line 00247 5461 1059 00250 6205 .PUSHJ @[HELLO] ; Finally add our name and version 00251 5771 1060 1061 ; Now we are ready to initialize the RAM disk array by first testing the 1062 ; backup battery and then individually testing each of the four RAM chips to 1063 ; determine a) if one is installed, and b) how big it is. IMPORTANT - because 1064 ; of the way the DS1321 works, we MUST test the backup battery before any 1065 ; other accesses to the RAM disk! The RDTEST routine will automatically 1066 ; initialize the RDSIZE array with the size of each RAM disk chip that it 1067 ; discovers... 1068 00252 4462 JMS @ZINLMES ; say 1069 00253 4406 RAMMS1 ; "RAM disk: " 1070 00254 4502 JMS @ZPUSHJ1 ; (cross field call) 1071 00255 0531 BATTST ; test the backup battery state 1072 00256 4502 JMS @ZPUSHJ1 ; (cross field call) 1073 00257 0665 RDTEST ; test all four RAM disk units 1074 00260 6205 .PUSHJ @[TDECNW] ; type out the total RAM size 00261 5770 1075 00262 4462 JMS @ZINLMES ; say 1076 00263 4413 RAMMS3 ; "Kb - Battery " 1077 00264 6211 CDF 1 ; the battery OK flag lives in field 1 1078 00265 1767 TAD @[BATTOK] ; get the battery status flag 1079 00266 6201 CDF 0 ; ... 1080 00267 7650 SNA CLA ; is the batery OK? 1081 00270 1366 TAD [BFAMSG-BOKMSG] ; no - say "failed" 1082 00271 1365 TAD [BOKMSG] ; yes - say "OK" 1083 00272 6205 .PUSHJ @[OUTSTR] ; ... 00273 5764 1084 00274 6205 .PUSHJ @ZCRLF ; finish the status report and we're done 00275 5461 1085 1086 ; Finally, probe the IDE bus for any drive that might be attached. First 1087 ; we have to initialize the 8255 and reset the IDE bus, and then we can send 1088 ; an ATA IDENTIFY DEVICE command to the drive. The DISKID routine will 1089 ; extract the drive's capacity, in MB, from that and leave the result at 1090 ; DKSIZE. DISKID also leaves the first 256 bytes of the drive's response in PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 21 System Startup, Part 2 BTS6120.PLX 1091 ; the DSKBUF, and we can use that to type out the drive's make and model, 1092 ; which appears there in plain ASCII. 1093 00276 4462 JMS @ZINLMES ; say 1094 00277 4434 IDEMS1 ; "IDE disk: " 1095 00300 4502 JMS @ZPUSHJ1 ; (cross field call) 1096 00301 1013 IDEINI ; initialize the IDE interface 1097 00302 7430 SZL ; is there a drive attached? 1098 00303 5331 JMP SYSIN4 ; nope - quit now 1099 00304 4502 JMS @ZPUSHJ1 ; (cross field call) 1100 00305 1034 DISKID ; send an IDENTIFY DEVICE command to the drive 1101 00306 7630 SZL CLA ; did it work ? 1102 00307 5331 JMP SYSIN4 ; nope - there's no disk there after all 1103 00310 6211 CDF 1 ; disk data lives in field 1 1104 00311 3763 DCA @[DSKBUF+135] ; (make the model string ASCIZ) 1105 00312 1762 TAD @[DKSIZE] ; get the total disk size 1106 00313 6201 CDF 0 ; ... 1107 00314 7450 SNA ; is the disk size zero ? 1108 00315 5326 JMP SYSIN7 ; yes - this disk is "unsupported" ! 1109 00316 6205 .PUSHJ @[TDECNW] ; and type it out in decimal 00317 5770 1110 00320 4462 JMS @ZINLMES ; say 1111 00321 4441 IDEMS2 ; "MB" 1112 00322 1361 TAD [DSKBUF+66-1] ; point to the make/model string 1113 00323 6205 .PUSHJ @[TASZF1] ; and type that out, in ASCII 00324 5760 1114 00325 5333 JMP SYSIN5 ; go type a CRLF and we're done 1115 1116 ; Here if an unsupported (i.e. one which does not support LBA addressing) 1117 ; is detected... 1118 00326 4462 SYSIN7: JMS @ZINLMES ; say 1119 00327 4457 IDEMS4 ; "not supported" 1120 00330 5333 JMP SYSIN5 ; ... 1121 1122 ; Here if no IDE disk is detected... 1123 00331 4462 SYSIN4: JMS @ZINLMES ; and say 1124 00332 4446 IDEMS3 ; "NONE" 1125 00333 6205 SYSIN5: .PUSHJ @ZCRLF ; finish the line and we're done 00334 5461 1126 1127 ; And we're ready for commands... 1128 00335 5477 JMP @ZRESTA 1129 00360 6255 00361 7465 00362 0040 00363 7535 00364 6200 00365 4425 00366 0003 00367 0026 00370 6277 00371 0711 00372 2026 00373 2304 00374 0120 00375 7777 00376 5202 00377 0177 1130 00400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 22 Field 0 Variables BTS6120.PLX 1131 .TITLE Field 0 Variables 1132 1133 1134 ; Page zero of field zero contains most of the runtime data for the monitor, 1135 ; including the saved state of the user (main memory) program. It is purposely 1136 ; NOT overlayed by any startup code so that it may also contain initialized 1137 ; variables, such as JMP/JMS vectors. Data in this page gets initialized 1138 ; automatically when the first phase of system initialization copies the EPROM 1139 ; to RAM. 1140 1141 ; These words contain the saved state of the main memory (aka user) 1142 ; program. The PC gets saved to location zero automatically by the 6120 1143 ; on any entry to control panel, and the rest get saved by the code around 1144 ; CPSAVE... 1145 00000 .ORG 0000 1146 00000 UPC: .BLOCK 1 ; program counter (saved by the hardware) 1147 00001 UAC: .BLOCK 1 ; accumulator 1148 00002 UFLAGS: .BLOCK 1 ; status (LINK, GT, IF, DF, etc) from GCF 1149 00003 UMQ: .BLOCK 1 ; MQ register 1150 00004 USP1: .BLOCK 1 ; 6120 stack pointer #1 1151 00005 USP2: .BLOCK 1 ; " " " #2 1152 00006 UIR: .BLOCK 1 ; the last main memory instruction to be executed 1153 1154 ; Auto-index registers... 1155 00010 .ORG 0010 ; this must be at location 10 !!! 1156 00010 X1: .BLOCK 1 ; the first auto-index register 1157 00011 X2: .BLOCK 1 ; the second auto-index register 1158 00012 X3: .BLOCK 1 ; the third auto-index register 1159 00013 L: .BLOCK 1 ; the command line pointer 1160 00020 .ORG 0020 ; don't put anything else in auto-index locations 1161 1162 ; Command parameters... 1163 00020 ADDR: .BLOCK 1 ; the current address 1164 00021 ADRFLD: .BLOCK 1 ; the field of this command 1165 00022 PNLMEM: .BLOCK 1 ; non-zero if ADDR/ADRFLD references panel memory 1166 00023 HIGH: .BLOCK 1 ; the high end of an address range 1167 00024 LOW: .BLOCK 1 ; the low end of an address range 1168 00025 HGHFLD: .BLOCK 1 ; the field of the high address 1169 00026 LOWFLD: .BLOCK 1 ; the field of the low address 1170 00027 VALUE: .BLOCK 1 ; the data word or value 1171 00030 NAME: .BLOCK 1 ; the name of this command 1172 00031 CHKSUM: .BLOCK 1 ; the checksum of memory or tape 1173 00032 SIMFLG: .BLOCK 1 ; non-zero if we're executing a single instruction 1174 00033 SAVCHR: .BLOCK 1 ; a place to save a character 1175 1176 ; Terminal parameters... 1177 00034 CTRLO: .BLOCK 1 ; non-zero if output is supressed 1178 00035 XOFF: .BLOCK 1 ; non-zero if output is suspended 1179 00036 HPOS: .BLOCK 1 ; the current horizontal position 1180 00037 VPOS: .BLOCK 1 ; the current vertical position 1181 00040 WIDTH: .BLOCK 1 ; the width of the terminal 1182 00041 LENGTH: .BLOCK 1 ; the number of lines on the screen 1183 00042 IRMA: .BLOCK 1 ; the console flag timeout counter 1184 1185 ; Parameters for the repeat command... 1186 00043 REPCNT: .BLOCK 1 ; the number of times to repeat 1187 00044 REPLOC: .BLOCK 1 ; the location to repeat from 1188 1189 ; Number I/O locations... 1190 00045 WORD: .BLOCK 1 ; the number being read or written 1191 00046 WORDH: .BLOCK 1 ; the high order bits of the last word read 1192 00047 COUNT: .BLOCK 1 ; the number of digits read or written 1193 00050 DIGITS: .BLOCK 1 ; counts digits for numeric input/output routines 1194 1195 ; Storage for RDDUMP, DDDUMP, RLLOAD and DLLOAD, RFRMAT, and DFRMAT... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 23 Field 0 Variables BTS6120.PLX 1196 00051 RECSIZ: .BLOCK 1 ; disk (page, block) size 1197 00052 RECCNT: .BLOCK 1 ; number of records to dump 1198 00053 FMTCNT: .BLOCK 1 ; number of blocks/records processed by FORMAT 1199 0023 CPYSRC=HIGH ; source partition for PC command 1200 0024 CPYDST=LOW ; destination partition for PC command 1201 1202 ; Page zero vectors (to save literal space)... 1203 00054 7400 ZOUTCHR: OUTCHR ; type a single character 1204 00055 7063 ZTSPACE: TSPACE ; type a space 1205 00056 6322 ZTOCT4: TOCT4 ; type an octal number 1206 00057 6352 ZTOCT4C: TOCT4C ; type an octal number followed by a CRLF 1207 00060 6347 ZTOCT4S: TOCT4S ; type an octal number followed by a space 1208 00061 7104 ZCRLF: CRLF ; type a carriage return/line feed 1209 00062 6237 ZINLMES: INLMES ; type a string passed in-line 1210 00063 0512 ZSPACMP: SPACMP ; get the next non-blank command character 1211 00064 0514 ZSPACM0: SPACM0 ; get a non-blank character starting with the current 1212 00065 0542 ZBACKUP: BACKUP ; backup the command line pointer 1213 00066 0525 ZEOLTST: EOLTST ; test current character for end of line 1214 00067 0523 ZEOLNXT: EOLNXT ; test the next character for end of line 1215 00070 0463 ZGET: GET ; get the next character from the command line 1216 00071 6720 ZOCTNW: OCTNW ; scan an octal number 1217 00072 6441 ZRANGE: RANGE ; scan an address range (e.g. "0-7777") 1218 00073 6506 ZTSTADR: TSTADR ; compare the HIGH/HGHFLD to LOW/LOWFLD 1219 00074 6473 ZNXTADR: NXTADR ; increment ADDR/ADRFLD 1220 00075 1317 ZRDMEM: RDMEM ; read a word from main or panel memory 1221 00076 1343 ZDANDV: DANDV ; deposit (in memory) and verify 1222 00077 0400 ZRESTA: RESTA ; monitor restart vector 1223 00100 0441 ZCOMERR: COMERR ; report a command syntax error and restart 1224 00101 0453 ZERROR: ERROR ; print an error message and restart 1225 00102 0600 ZPUSHJ1: PUSHJ1 ; call a routine in field 1 and return to field 0 1226 1227 ; Page zero constants (to save literal space)... 1228 00103 0177 ZK177: 177 ; used everywhere as a mask for ASCII characters 1229 00104 0070 ZK70: 70 ; used as a mask for data/instruction fields 1230 00105 0007 ZK7: 7 ; yet another mask 1231 00106 7740 ZMSPACE: -" " ; an ASCII space character (or the negative there of) 1232 00107 7600 ZM128: -128. ; record size of RAM disk 1233 0107 ZK7600=ZM128 1234 00110 7400 ZM256: -256. ; record size of IDE disk 1235 0110 ZK7400=ZM256 1236 00111 0021 ZRDPAGE: RDPAGE ; current RAM disk page number in field 1 1237 00112 0037 ZDKRBN: DKRBN ; current IDE disk block number in field 1 1238 1239 ; The software stack occupies all of the rest of page zero. 1240 00113 STKSAV: .BLOCK 1 ; the last monitor SP is saved here by CONTINUE 1241 0177 STACK=0177 1242 0063 STKLEN=STACK-. ; Length of the stack (if anybody cares) 1243 1244 1245 ; Page one of field zero contains the second phase system initialization 1246 ; code, and it's over written by the command line buffer and break point 1247 ; tables after we're running. 1248 00200 .ORG 0200 1249 1250 ; The PDP2HEX program stores a checksum of ROM field 0 in location 00200, 1251 ; and we have to reserve space for it here so it doesn't get overwritten by 1252 ; any of our data. See the code at ROMCK0: for more discussion. 1253 00200 .BLOCK 1 1254 1255 ; Breakpoint storage... 1256 0010 MAXBPT=8. ; maximum number of breakpoints 1257 00201 BPTADR: .BLOCK MAXBPT ; address assigned to each breakpoint 1258 00211 BPTFLD: .BLOCK MAXBPT ; field of the breakpoint 1259 00221 BPTDAT: .BLOCK MAXBPT ; original data at the breakpoint 1260 0210 BPTEND=BPTADR+MAXBPT-1 ; end of the breakpoint address table PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 24 Field 0 Variables BTS6120.PLX 1261 1262 ; The command line buffer for INCHWL occupies all that remains of page one... 1263 0147 MAXCMD=0400-. ; space available for the command buffer 1264 00231 CMDBUF: .BLOCK MAXCMD ; and the actual command buffer PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 25 Monitor Main Loop BTS6120.PLX 1265 .TITLE Monitor Main Loop 1266 1267 00400 .PAGE 2 1268 1269 ; This routine will read commands from the terminal and execute them. It 1270 ; can be entered at RESTA to restart after a control-C or a fatal error, and 1271 ; at BOOTS after completion of a normal command... 1272 00400 6276 RESTA: SPD ; Insure that CP memory is always selected 1273 00401 7200 CLA ; And be sure the AC is cleared 1274 00402 1377 TAD [STACK] ; Point to the stack 1275 00403 6217 LSP1 ; Clean up the stack pointer 1276 00404 6205 .PUSHJ @ZCRLF ; Be sure the terminal is ready 00405 5461 1277 1278 ; Read another command line... 1279 00406 7200 BOOTS: CLA ; ... 1280 00407 1376 TAD [">"] ; Point to the prompt 1281 00410 6205 .PUSHJ @[INCHWL] ; And read a command line 00411 5775 1282 00412 3043 DCA REPCNT ; Clear the repeat counter initially 1283 1284 ; Execute the next command... 1285 00413 6205 BOOTS1: .PUSHJ @[NAMENW] ; First identify a command 00414 5774 1286 00415 1030 TAD NAME ; Get the name we read 1287 00416 7650 SNA CLA ; Is this a null command ?? 1288 00417 5223 JMP BOOTS2 ; Yes -- just ignore it 1289 00420 1373 TAD [CMDTBL-1] ; Then point to the list of commands 1290 00421 6205 .PUSHJ @[MATCH] ; And look it up 00422 5772 1291 1292 ; See if there are more commands on this line... 1293 00423 1013 BOOTS2: TAD L ; Get the pointer to the last character 1294 00424 3045 DCA WORD ; And save it in a non-autoindex location 1295 00425 1445 TAD @WORD ; Get the last character we saw 1296 00426 1371 TAD [-073] ; Was it a command seperator ?? 1297 00427 7650 SNA CLA ; ???? 1298 00430 5213 JMP BOOTS1 ; Yes -- go execute another command 1299 1300 ; See if this command needs to be repeated... 1301 00431 7240 STA ; Load the AC with -1 1302 00432 1043 TAD REPCNT ; And add to the repeat counter 1303 00433 7510 SPA ; Is the counter positive ?? 1304 00434 5206 JMP BOOTS ; No -- go read anothter line 1305 00435 3043 DCA REPCNT ; Yes -- save the new count 1306 00436 1044 TAD REPLOC ; And get the location to start from 1307 00437 3013 DCA L ; Backup the command scanner 1308 00440 5213 JMP BOOTS1 ; Then go execute this command again PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 26 Command Error Processing BTS6120.PLX 1309 .TITLE Command Error Processing 1310 1311 1312 ; This routine is called when a syntax error is found in the command and it 1313 ; echo the part of the command which has already been scanned inside question 1314 ; marks (very much like TOPS-10 used to do!). After that, the monitor is 1315 ; restarted (i.e. the stack is cleaned up and another prompt issued). 1316 00441 7200 COMERR: CLA ; Ignore the contents of the AC 1317 00442 3413 DCA @L ; And mark the end of what was actually scanned 1318 00443 6205 .PUSHJ @[TQUEST] ; Type the first question mark 00444 5770 1319 00445 1367 TAD [CMDBUF-1] ; And point to the command line 1320 00446 6205 .PUSHJ @[TASCIZ] ; Echo that 00447 5766 1321 00450 6205 .PUSHJ @[TQUEST] ; Then type another question 00451 5770 1322 00452 5200 JMP RESTA ; Go restart the monitor 1323 1324 1325 ; This routine prints an error message and then restarts the monitor. Unlike 1326 ; nearly every other routine in the monitor this one is called via a JMS 1327 ; instruction rather than a .PUSHJ, and that so that the address of the error 1328 ; message can be passed in line, in the word after the JMS. 1329 ; 1330 ; CALL: 1331 ; JMS @ZERROR 1332 ;
1333 00453 0000 ERROR: 0 ; enter here with a JMS 1334 00454 7200 CLA ; the AC is unknown here 1335 00455 6205 .PUSHJ @[TQUEST] ; always type a question mark 00456 5770 1336 00457 1653 TAD @ERROR ; pick up the address of the message 1337 00460 6205 .PUSHJ @[OUTSTR] ; and type that out too 00461 5765 1338 00462 5477 JMP @ZRESTA ; restart the monitor and read another command PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 27 Get Next Command Character BTS6120.PLX 1339 .TITLE Get Next Command Character 1340 1341 1342 ; This routine will get the next character from the command line. If the 1343 ; character is lower case, it is folded to upper case. If the character is a 1344 ; TAB, it is converted to a space. And, if the character is ";" or "!" (the 1345 ; start of a comment) it is converted to zero (end of line). Finally, the 1346 ; character is returned in both the AC and location SAVCHR. 1347 00463 7200 GET: CLA ; Be sure the AC is safe to use 1348 00464 1413 TAD @L ; Get another character from the line 1349 00465 1364 TAD [-"A"-40] ; Compare this character to lower case A 1350 00466 7500 SMA ; ??? 1351 00467 5303 JMP GET1 ; It might be a lower case letter 1352 1353 ; The character is not lower case -- check for a TAB, ; or !... 1354 00470 1363 TAD ["A"+40-CHTAB] ; Is this a tab character ?? 1355 00471 7450 SNA ; ??? 1356 00472 1362 TAD [" "-CHTAB] ; Yes -- convert it to a space 1357 00473 1361 TAD [CHTAB-"!"] ; No -- Is it a ! character ?? 1358 00474 7450 SNA ; ??? 1359 00475 1360 TAD [-"!"] ; Yes -- Convert it to a null 1360 00476 1357 TAD ["!"-073] ; Last chance -- is it a ; ?? 1361 00477 7450 SNA ; ??? 1362 00500 1371 TAD [-073] ; Yes -- convert that to zero too 1363 00501 1356 TAD [073] ; No -- restore the original character 1364 00502 5307 JMP GET2 ; Then store the character and return 1365 1366 ; Here if the character might be lower case... 1367 00503 1355 GET1: TAD ["A"-"Z"] ; Compare to the other end of the range 1368 00504 7550 SPA SNA ; ??? 1369 00505 1354 TAD [-40] ; It's lower case -- convert to upper 1370 00506 1353 TAD ["Z"+40] ; Restore the correct character 1371 1372 ; Store the character and return... 1373 00507 3033 GET2: DCA SAVCHR ; Remember this character 1374 00510 1033 TAD SAVCHR ; And also return it in the AC 1375 00511 6225 .POPJ ; And that's it PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 28 Simple Lexical Functions BTS6120.PLX 1376 .TITLE Simple Lexical Functions 1377 1378 1379 ; This routine will skip over any spaces in the command line and return the 1380 ; next non-space character in the AC and SAVCHR... 1381 1382 ; Here to start skipping with the next character... 1383 00512 6205 SPACMP: .PUSHJ @ZGET ; Get the next character 00513 5470 1384 1385 ; Here to consider the current character and then skip... 1386 00514 7200 SPACM0: CLA ; Be sure the AC is safe to use 1387 00515 1033 TAD SAVCHR ; And look at the current character 1388 00516 1106 TAD ZMSPACE ; Compare it to a space 1389 00517 7650 SNA CLA ; ??? 1390 00520 5312 JMP SPACMP ; Keep going until we don't find one 1391 00521 1033 TAD SAVCHR ; Restore the character 1392 00522 6225 .POPJ ; And we're all done 1393 1394 ; This routine will examine the current character (in SAVCHR) or the next 1395 ; character (via GET) for end of line, which is stored as a null byte). If 1396 ; it isn't the EOL, then COMERR is called and the current command is aborted, 1397 ; otherwise this routine just returns... 1398 1399 ; Enter here to examine the next character... 1400 00523 6205 EOLNXT: .PUSHJ @ZGET ; Load the next character 00524 5470 1401 ; Then fall into the current character test 1402 1403 ; Enter here to examine the current character... 1404 00525 6205 EOLTST: .PUSHJ @ZSPACM0 ; Allow blanks at the end of the line 00526 5464 1405 00527 7640 SZA CLA ; Is it the end of the line ?? 1406 00530 5500 JMP @ZCOMERR ; No -- that's bad 1407 00531 6225 .POPJ ; Yes -- that's good 1408 1409 ; This routine will test either the current character (via SAVCHR) or the 1410 ; next character (via GET) to see if it's a space. If it isn't, then it 1411 ; jumps to COMERR and aborts the current command... 1412 1413 ; Enter here to examine the next character... 1414 00532 6205 SPANXT: .PUSHJ @ZGET ; get the next character 00533 5470 1415 ; and fall into SPATST... 1416 1417 ; Enter here to examine the current character 1418 00534 7200 SPATST: CLA ; don't require that the AC be cleared 1419 00535 1033 TAD SAVCHR ; get the current character 1420 00536 1106 TAD ZMSPACE ; and compare it to a space 1421 00537 7640 SZA CLA ; well?? 1422 00540 5500 JMP @ZCOMERR ; not equal - this is a bad command line 1423 00541 6225 .POPJ ; it's a space 1424 1425 ; This routine will backup the command scanner so that the character 1426 ; just read will be read again with the next call to GET... 1427 00542 7240 BACKUP: STA ; Load the AC with -1 1428 00543 1013 TAD L ; Then decrement the line pointer 1429 00544 3013 DCA L ; ... 1430 00545 6225 .POPJ ; That's all it takes 1431 00553 0172 00554 7740 00555 7747 00556 0073 00557 7746 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 29 Simple Lexical Functions BTS6120.PLX 00560 7737 00561 7750 00562 0027 00563 0130 00564 7637 00565 6200 00566 6246 00567 0230 00570 7066 00571 7705 00572 6642 00573 3377 00574 6600 00575 7200 00576 0076 00577 0177 1432 00600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 30 Call Routines in Field 1 BTS6120.PLX 1433 .TITLE Call Routines in Field 1 1434 1435 1436 ; This routine will allow a routine in field zero to simulate a .PUSHJ 1437 ; to a routine in field one. Even better, when the routine in field one 1438 ; executes a .POPJ, the return will eventually be to field zero! The 1439 ; contents of the AC are preserved both ways across the call. 1440 ; 1441 ;CALL: 1442 ; JMS @ZPUSHJ1 ; cross field call 1443 ; ; address of a routine in field 1 1444 ; ; with the AC preserved across the call 1445 ; 1446 00600 0000 PUSHJ1: 0 ; call here with a JMS instruction 1447 00601 3217 DCA PUSHAC ; save the caller's AC for a minute 1448 00602 1600 TAD @PUSHJ1 ; then get caller's argument 1449 00603 3216 DCA F1ADDR ; that's the address of the routine to call 1450 00604 1200 TAD PUSHJ1 ; now get caller's return address 1451 00605 7001 IAC ; and skip over the argument 1452 00606 6215 .PUSH ; put that on the stack 1453 00607 7200 CLA ; (PUSH doesn't clear the AC!) 1454 00610 1377 TAD [POPJ1] ; the field one routine will return to 1455 00611 6215 .PUSH ; ... POPJ1: in field one 1456 00612 7200 CLA ; ... 1457 00613 1217 TAD PUSHAC ; restore the original AC contents 1458 00614 6213 CXF 1 ; call with IF = DF = 1 1459 00615 5616 JMP @.+1 ; and go to the code in field 1 1460 00616 F1ADDR: .BLOCK 1 ; gets the address of the field 1 routine 1461 00617 PUSHAC: .BLOCK 1 ; a temporary place to save the AC 1462 1463 ; When the routine in field one executes a .POPJ, it will actually return to 1464 ; the code at POPJ1: _in field one_ !! Since we've also stacked our original 1465 ; caller's return address, the code at POPJ1 really only needs to do two 1466 ; things, a "CXF 0" to return to field zero, and then another .POPJ. 1467 ; Unfortunately, this code has to live in field one, so you won't find it 1468 ; here! PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 31 RP Command -- Repeat BTS6120.PLX 1469 .TITLE RP Command -- Repeat 1470 1471 1472 ; This command allows the rest of the command line to be repeated, and it 1473 ; accepts an optional argument which specifes the number of times to repeat, 1474 ; in decimal. The range for this argument is 1 to 2047 and if it is omitted, 1475 ; it defaults to 2047. Note that repeat commands may not be nested; a repeat 1476 ; command will cancel any previous repeat on the same command line. Any error 1477 ; or a control-C will terminate the repetition prematurely. 1478 00620 6205 REPEAT: .PUSHJ @ZSPACMP ; Get the next character 00621 5463 1479 00622 7650 SNA CLA ; Is it the end of the command ?? 1480 00623 5235 JMP REPEA1 ; Yes -- use the default count 1481 00624 6205 .PUSHJ @ZBACKUP ; No -- backup the scanner 00625 5465 1482 00626 6205 .PUSHJ @[DECNW] ; Then read a decimal number 00627 5776 1483 00630 6205 .PUSHJ @ZEOLTST ; Then test for the end of the line 00631 5466 1484 1485 ; Set up the repeat counter... 1486 00632 7240 STA ; Subtract one from the user's 1487 00633 1045 TAD WORD ; argument... 1488 00634 7410 SKP ; ... 1489 00635 7350 REPEA1: NL3777 ; If there's no argument, use 2047 1490 00636 3043 DCA REPCNT ; Set the repeat counter 1491 1492 ; Set up the repeat pointer... 1493 00637 1013 TAD L ; Get the current line pointer 1494 00640 3044 DCA REPLOC ; Remember where to start from 1495 00641 1444 TAD @REPLOC ; Then examine the current character 1496 00642 7650 SNA CLA ; Is the repeat the last command on the line ?? 1497 00643 3043 DCA REPCNT ; Yes -- this is all pointless after all 1498 00644 6225 .POPJ ; Then proceed with the next command PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 32 TW and TP Commands - Set Terminal Width and Page BTS6120.PLX 1499 .TITLE TW and TP Commands - Set Terminal Width and Page 1500 1501 1502 ; The TW command sets the terminal screen width to the value of its argument, 1503 ; which is a _decimal_ number. Screen widths are limited to the range 32..255. 1504 00645 6205 TWCOM: .PUSHJ @[DECNW] ; read a decimal operand again 00646 5776 1505 00647 6205 .PUSHJ @ZEOLTST ; then check for the end of the line 00650 5466 1506 00651 1045 TAD WORD ; get the desired width 1507 00652 7450 SNA ; is it zero ?? 1508 00653 5263 JMP TWCOM1 ; yes -- that disables automatic returns 1509 00654 1375 TAD [-32.] ; compare it to 32 1510 00655 7510 SPA ; is it at least 32 ?? 1511 00656 5265 JMP TFILV ; no -- ?ILLEGAL VALUE 1512 00657 1374 TAD [32.-255.] ; now compare it to 255 1513 00660 7540 SMA SZA ; it can't be bigger than that 1514 00661 5265 JMP TFILV ; but it is... 1515 00662 1373 TAD [255.] ; restore the original number 1516 00663 3040 TWCOM1: DCA WIDTH ; and set the terminal width 1517 00664 6225 .POPJ ; then that's all 1518 1519 ; Here if the parameter value is illegal... 1520 00665 4501 TFILV: JMS @ZERROR ; yes -- it isn't legal 1521 00666 3576 ERRILV ; ?ILLEGAL VALUE 1522 1523 ; The TP command sets the terminal page size to the value of its argument, 1524 ; in _decimal_. Page sizes may range from 12 to 48, or zero. A value of zero 1525 ; disables the automatic XOFF function completely. 1526 00667 6205 TPCOM: .PUSHJ @[DECNW] ; Read a decimal operand 00670 5776 1527 00671 6205 .PUSHJ @ZEOLTST ; And check for the end of the line 00672 5466 1528 00673 1045 TAD WORD ; Get the value he gave 1529 00674 7450 SNA ; Is it zero ?? 1530 00675 5305 JMP TPCOM1 ; Yes -- that is legal (to disable) 1531 00676 1372 TAD [-12.] ; Compare it to 12 lines 1532 00677 7510 SPA ; We have to have at least that many 1533 00700 5265 JMP TFILV ; No -- ?ILLEGAL VALUE 1534 00701 1375 TAD [16.-48.] ; Then compare it to 48 1535 00702 7540 SMA SZA ; Is it more than that ?? 1536 00703 5265 JMP TFILV ; Yes -- that won't work, either 1537 00704 1371 TAD [48.] ; Restore the original number 1538 00705 3041 TPCOM1: DCA LENGTH ; And set the new terminal length 1539 00706 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 33 VE Command - Show System Name and Version BTS6120.PLX 1540 .TITLE VE Command - Show System Name and Version 1541 1542 1543 ; This routine will type the name and version of the monitor. It is called 1544 ; at startup, and by the VE command. 1545 00707 6205 VECOM: .PUSHJ @ZEOLNXT ; enter here for the VE command 00710 5467 1546 00711 4462 HELLO: JMS @ZINLMES ; type out the name of the system 1547 00712 4265 SYSNM1 ; ... 1548 00713 1370 TAD [VERSION] ; get the present edit level 1549 00714 6205 .PUSHJ @[TOCT3] ; type that in octal 00715 5767 1550 00716 4462 JMS @ZINLMES ; say 1551 00717 4304 SYSNM2 ; "Checksum " 1552 00720 1766 TAD @[ROMCK0] ; get the checksum of ROM field 0 1553 00721 6205 .PUSHJ @ZTOCT4S ; type that and a space 00722 5460 1554 00723 6211 CDF 1 ; then do the same for ROM field 1 1555 00724 1766 TAD @[ROMCK1] ; ... 1556 00725 6201 CDF 0 ; ... 1557 00726 6205 .PUSHJ @ZTOCT4S ; this time end with a CRLF 00727 5460 1558 00730 4462 JMS @ZINLMES ; finally, type the system date 1559 00731 4314 SYSNM3 ; ... 1560 00732 6205 .PUSHJ @ZCRLF ; finish that line 00733 5461 1561 00734 4462 JMS @ZINLMES ; then type the copyright notice 1562 00735 4332 SYSCRN ; ... 1563 00736 5461 JMP @ZCRLF ; finish that line and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 34 H Command - Show Monitor Help BTS6120.PLX 1564 .TITLE H Command - Show Monitor Help 1565 1566 ; The H command generates a simple list of all monitor commands and a 1567 ; brief, one line, help message for each. The whole function is driven 1568 ; by a table of help messages stored in field one - this table contains 1569 ; a list of pointers and each pointer points to the packed ASCII text of 1570 ; a single line of help. We simply print each line and add a CRLF at the 1571 ; end. It's done this way (as a table of lines) rather than as a single, 1572 ; huge, string with embedded CRLFs because the automatic XOFF (i.e. terminal 1573 ; page) processing is done via the CRLF routine. Embedded CRLFs wouldn't 1574 ; automatically XOFF, and so most of the text would scroll right off the 1575 ; top of the CRT. 1576 00737 6205 HELP: .PUSHJ @ZEOLTST ; no arguments are allowed 00740 5466 1577 00741 1365 TAD [HLPLST-1] ; point to the list of help messages 1578 00742 3012 DCA X3 ; in an auto index register 1579 00743 6211 HELP1: CDF 1 ; the help text and table lives in field 1 1580 00744 1412 TAD @X3 ; get the next help message 1581 00745 6201 CDF 0 ; back to our field 1582 00746 7450 SNA ; end of list? 1583 00747 6225 .POPJ ; yes - we can quit now 1584 00750 6205 .PUSHJ @[OUTSTR] ; nope - type this string 00751 5764 1585 00752 6205 .PUSHJ @ZCRLF ; and finish the line 00753 5461 1586 00754 5343 JMP HELP1 ; keep typing until we run out of strings 1587 00764 6200 00765 4470 00766 0200 00767 6343 00770 0215 00771 0060 00772 7764 00773 0377 00774 7441 00775 7740 00776 6662 00777 0275 1588 01000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 35 E and EP Commands -- Examine Main Memory or Panel Memory BTS6120.PLX 1589 .TITLE E and EP Commands -- Examine Main Memory or Panel Memory 1590 1591 1592 ; The E command allows the user to examine the contents of memory in octal, 1593 ; either one word at a time or an entire range of addresses. In the latter 1594 ; case a memory dump is printed with eight PDP-8 words per line. It accepts 1595 ; several forms of operands, for example: 1596 ; 1597 ; >E 1234 -> Examine location 1234 in the data field 1598 ; >E 01234 -> Examime location 1234 of field zero 1599 ; >E 41234 -> Examine location 1234, field 4 1600 ; >E 71000-2000 -> Examine locations 1000 through 2000, field 7 1601 ; >E 50000-77777 -> Examine location 0, field 5 thru 7777, field 7 1602 ; 1603 ; The EP command is identical to E, except that panel memory is examined 1604 ; rather than main memory. 1605 1606 ; Enter here for the EP command... 1607 01000 7240 EPMEM: STA ; set the PNLMEM flag 1608 01001 7410 SKP ; fall into the regular code 1609 ; Enter here for the E command... 1610 01002 7200 EMEM: CLA ; clear the PNLMEM flag 1611 01003 3022 DCA PNLMEM ; to reference main memory 1612 1613 ; Both forms join up here... 1614 01004 6205 EMEM0: .PUSHJ @ZRANGE ; go read an address range 01005 5472 1615 01006 7420 SNL ; was there just one address ??? 1616 01007 5242 JMP EONE ; yes -- just examine one location 1617 1618 ; Fix up the address range for multiple word examines... 1619 01010 1024 TAD LOW ; get the low boundry 1620 01011 0377 AND [7770] ; round it down to a multiple of 8 1621 01012 3020 DCA ADDR ; then it becomes the starting address 1622 01013 1023 TAD HIGH ; get the ending address 1623 01014 0377 AND [7770] ; round it up to a multiple of 8 1624 01015 1105 TAD ZK7 ; ... 1625 01016 3023 DCA HIGH ; and remember the last address to process 1626 1627 ; Type out lines of 8 memory locations... 1628 01017 6205 EMEM1: .PUSHJ @[TADDR] ; type out the address of the next word 01020 5776 1629 01021 6205 EMEM2: .PUSHJ @ZRDMEM ; go read a word from main memory 01022 5475 1630 01023 6205 .PUSHJ @ZTOCT4S ; type the word in octal 01024 5460 1631 01025 6205 .PUSHJ @ZTSTADR ; have we done all the locations ?? 01026 5473 1632 01027 7430 SZL ; are we there yet ??? 1633 01030 5244 JMP EMEM3 ; yes -- finish the line and return 1634 01031 6205 .PUSHJ @ZNXTADR ; no -- increment to the next address 01032 5474 1635 01033 1020 TAD ADDR ; get the current address 1636 01034 0105 AND ZK7 ; is it a multiple of 8 ?? 1637 01035 7640 SZA CLA ; ??? 1638 01036 5221 JMP EMEM2 ; no -- keep typing 1639 01037 6205 .PUSHJ @ZCRLF ; yes -- start on a new line 01040 5461 1640 01041 5217 JMP EMEM1 ; and type the next address 1641 1642 ; Here to examine a single memory location... 1643 01042 6205 EONE: .PUSHJ @[TMEM] ; type out the contents of memory 01043 5775 1644 ; and fall into the next range 1645 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 36 E and EP Commands -- Examine Main Memory or Panel Memory BTS6120.PLX 1646 ; Here when we've finished examining one range of addresses... 1647 01044 6205 EMEM3: .PUSHJ @ZCRLF ; finish the current line 01045 5461 1648 01046 6205 .PUSHJ @ZBACKUP ; backup the command line pointer 01047 5465 1649 01050 6205 .PUSHJ @ZSPACMP ; ... and get the next character 01051 5463 1650 01052 7450 SNA ; is it the end of the line ?? 1651 01053 6225 .POPJ ; yes -- just stop now 1652 01054 1374 TAD [-","] ; no -- check for a comma 1653 01055 7640 SZA CLA ; ???? 1654 01056 5500 JMP @ZCOMERR ; this isn't legal 1655 01057 5204 JMP EMEM0 ; yes -- do another operand 1656 1657 ; This routine will type the address and contents of the memory location 1658 ; indicated by registers ADDR and ADRFLD. 1659 01060 6205 TMEM: .PUSHJ @[TADDR] ; first type the address 01061 5776 1660 01062 6205 .PUSHJ @ZRDMEM ; then load the indicated word 01063 5475 1661 01064 5460 JMP @ZTOCT4S ; type it out and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 37 D and DP Commands -- Deposit in Main Memory or Panel Memory BTS6120.PLX 1662 .TITLE D and DP Commands -- Deposit in Main Memory or Panel Memory 1663 1664 1665 ; The D command allows the user to deposit one or more words in memory. The 1666 ; general format is: 1667 ; 1668 ; >D 60123 4567 -> Deposit 4567 into location 0123, field 6 1669 ; >D 40000 1,2,3,4 -> Deposit 0001 into location 0, field 4, and 0002 1670 ; into location 1, field 4, and 0003 into location 1671 ; 2, etc... 1672 ; 1673 ; The DP command is identical to D, except that panel memory is chaged rather 1674 ; than main memory. WARNING - there is no protection against changing the 1675 ; monitor when using this command, so it's up to the user to make sure the 1676 ; changes don't corrupt something important! 1677 1678 ; Enter here for the DP command... 1679 01065 7240 DPMEM: STA ; set the PNLMEM flag 1680 01066 7410 SKP ; fall into the regular code 1681 ; Enter here for the D command... 1682 01067 7200 DMEM: CLA ; clear the PNLMEM flag 1683 01070 3022 DCA PNLMEM ; to reference main memory 1684 1685 ; Both forms join up here... 1686 01071 6205 .PUSHJ @[RDADDR] ; Then read an address 01072 5773 1687 01073 6205 .PUSHJ @[SPATST] ; the next character has to be a space 01074 5772 1688 1689 ; Read words of data and deposit them... 1690 01075 6205 DMEM1: .PUSHJ @ZOCTNW ; read an octal operand 01076 5471 1691 01077 1045 TAD WORD ; get the data we found 1692 01100 6205 .PUSHJ @ZDANDV ; write and verify it 01101 5476 1693 01102 6205 .PUSHJ @ZNXTADR ; advance to the next address 01103 5474 1694 01104 6205 .PUSHJ @ZSPACM0 ; get the break character from OCTNW 01105 5464 1695 01106 7450 SNA ; was it the end of the line ?? 1696 01107 6225 .POPJ ; yes, we're done... 1697 01110 1374 TAD [-","] ; no - it has to be a comma otherwise 1698 01111 7640 SZA CLA ; ???? 1699 01112 5500 JMP @ZCOMERR ; bad command 1700 01113 5275 JMP DMEM1 ; go read and deposit another word PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 38 ER and DR Commands - Examine and Deposit in Registers BTS6120.PLX 1701 .TITLE ER and DR Commands - Examine and Deposit in Registers 1702 1703 1704 ; The ER command examines either a single register, when the register name 1705 ; is given as an argument, or all registers when no argument is given. For 1706 ; example: 1707 ; 1708 ; >ER AC - examine the AC 1709 ; >ER PC - examine the PC 1710 ; >ER - print all registers 1711 ; 1712 01114 6205 EREG: .PUSHJ @ZSPACMP ; get the next non-space character 01115 5463 1713 01116 7650 SNA CLA ; is it the end of line? 1714 01117 5771 JMP @[REGLSC] ; yes - type all registers and return 1715 01120 6205 .PUSHJ @ZBACKUP ; nope - backup the command scanner 01121 5465 1716 01122 6205 .PUSHJ @[NAMENW] ; and go read the register name 01123 5770 1717 01124 6205 .PUSHJ @ZEOLNXT ; now we have to be at the end of line 01125 5467 1718 01126 1367 TAD [ENAMES-1] ; point to the name table 1719 01127 6205 .PUSHJ @[MATCH] ; find it and call a routine to print 01130 5766 1720 01131 5461 JMP @ZCRLF ; finish the line and we're done 1721 1722 ; The DR command deposits a value in a register, and both a register name and 1723 ; an octal value are required arguments. For example: 1724 ; 1725 ; >DR AC 7777 - set the AC to 7777 1726 ; >DR SR 3345 - set the switch register to 3345 1727 ; 1728 01132 6205 DREG: .PUSHJ @[NAMENW] ; get the register name 01133 5770 1729 01134 6205 .PUSHJ @[SPANXT] ; the terminator has to be a space 01135 5765 1730 01136 6205 .PUSHJ @ZOCTNW ; read an octal number to deposit 01137 5471 1731 01140 6205 .PUSHJ @ZEOLTST ; followed by the end of the line 01141 5466 1732 01142 1364 TAD [DNAMES-1] ; point to the list of deposit names 1733 01143 5766 JMP @[MATCH] ; call the right routine and we're done 1734 01164 3525 01165 0532 01166 6642 01167 3511 01170 6600 01171 1240 01172 0534 01173 6416 01174 7724 01175 1060 01176 6400 01177 7770 1735 01200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 39 Deposit in Registers BTS6120.PLX 1736 .TITLE Deposit in Registers 1737 1738 1739 ; Here to deposit in the AC... 1740 01200 1045 DAC: TAD WORD ; Get his value 1741 01201 3001 DCA UAC ; And change the AC 1742 01202 6225 .POPJ ; Then that's all 1743 1744 ; Here to deposit in the PC... 1745 01203 1045 DPC: TAD WORD ; The same old routine... 1746 01204 3000 DCA UPC ; ... 1747 01205 6225 .POPJ ; ... 1748 1749 ; Here to deposit in the MQ... 1750 01206 1045 DMQ: TAD WORD ; ... 1751 01207 3003 DCA UMQ ; ... 1752 01210 6225 .POPJ ; ... 1753 1754 ; Here to deposit in the PS... 1755 01211 1045 DPS: TAD WORD ; ... 1756 01212 0377 AND [6277] ; only these bits can actually change 1757 01213 7421 MQL ; save the new value for a minute 1758 01214 1002 TAD UFLAGS ; get the current status 1759 01215 0376 AND [1500] ; clear the complementary bits 1760 01216 7501 MQA ; or everything together 1761 01217 3002 DCA UFLAGS ; and update the PS 1762 01220 6225 .POPJ ; ... 1763 1764 ; Here to deposit in the switch register... 1765 01221 1045 DSR: TAD WORD ; ... 1766 01222 6246 WSR ; Load the switch register 1767 01223 6225 .POPJ ; Then that's all 1768 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 40 Examine Registers BTS6120.PLX 1769 .TITLE Examine Registers 1770 1771 1772 ; This routine is called to type out all the important internal registers. 1773 ; It is used by the ER, and SI commands, and after breakpoints, traps and 1774 ; halts. 1775 01224 7200 REGLST: CLA ; be sure the AC is cleared 1776 01225 6205 .PUSHJ TYPEPC ; type the PC first 01226 5255 1777 01227 6205 .PUSHJ TYPEPS ; then the LINK 01230 5266 1778 01231 6205 .PUSHJ TYPEAC ; then the AC 01232 5252 1779 01233 6205 .PUSHJ TYPEMQ ; then the MQ 01234 5260 1780 01235 6205 .PUSHJ TYPSP1 ; user stack pointer 1 01236 5271 1781 01237 5274 JMP TYPSP2 ; and finally stack pointer 2 1782 1783 ; The same as REGLST, but with a carriage return added... 1784 01240 6205 REGLSC: .PUSHJ REGLST ; first type the registers 01241 5224 1785 01242 5461 JMP @ZCRLF ; type the carriage return and we're done 1786 1787 ; This routine types a register name followed by an octal register value. 1788 ; The latter is passed in the AC, and the register name is passed inline. 1789 01243 0000 TYPRG4: 0 ; enter here with a JMS instruction 1790 01244 3027 DCA VALUE ; save the register contents for a moment 1791 01245 1643 TAD @TYPRG4 ; and get the address of the register name 1792 01246 6205 .PUSHJ @[OUTSTR] ; type that 01247 5775 1793 01250 1027 TAD VALUE ; get the contents of the register 1794 01251 5460 JMP @ZTOCT4S ; type that in octal and leave a blank 1795 1796 ; This routine will type the last user AC contents... 1797 01252 1001 TYPEAC: TAD UAC ; get the contents of the register 1798 01253 4243 JMS TYPRG4 ; type it and return 1799 01254 4057 ACNAME ; "AC>" 1800 1801 ; This routine will type the last user PC... 1802 01255 1000 TYPEPC: TAD UPC ; the same old routine... 1803 01256 4243 JMS TYPRG4 ; ... 1804 01257 4062 PCNAME ; "PC>" 1805 1806 ; This routine will type the last user MQ contents... 1807 01260 1003 TYPEMQ: TAD UMQ ; ... 1808 01261 4243 JMS TYPRG4 ; ... 1809 01262 4065 MQNAME ; "MQ>" 1810 1811 ; This routine will type the last instruction executed... 1812 01263 1006 TYPEIR: TAD UIR ; ... 1813 01264 4243 JMS TYPRG4 ; ... 1814 01265 4070 IRNAME ; "IR>" 1815 1816 ; This routine will type the current interrupt flags... 1817 01266 1002 TYPEPS: TAD UFLAGS ; get the flags 1818 01267 4243 JMS TYPRG4 ; ... 1819 01270 4076 PSNAME ; "PS>" 1820 1821 ; This routine will type the 6120 stack pointer #1... 1822 01271 1004 TYPSP1: TAD USP1 ; ... 1823 01272 4243 JMS TYPRG4 ; ... 1824 01273 4101 SP1NAM ; "SP1>" 1825 1826 ; This routine will type the 6120 stack pointer #2... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 41 Examine Registers BTS6120.PLX 1827 01274 1005 TYPSP2: TAD USP2 ; ... 1828 01275 4243 JMS TYPRG4 ; ... 1829 01276 4105 SP2NAM ; "SP2>" 1830 1831 ; This routine will type the current switch register contents... 1832 01277 7604 TYPESR: LAS ; actually read the switch register 1833 01300 4243 JMS TYPRG4 ; ... 1834 01301 4073 SRNAME ; "SR>" PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 42 Read and Write Memory BTS6120.PLX 1835 .TITLE Read and Write Memory 1836 1837 1838 ; This routine will change the current data field to the field indicated in 1839 ; location ADRFLD. It's normally used by commands that read or write memory, 1840 ; such as Examine, Deposit, etc. Remember that on the 6120 the EMA works in 1841 ; panel memory as well, so don't forget to change back to field zero after 1842 ; you're done! 1843 01302 7200 CFIELD: CLA ; ... 1844 01303 1021 TAD ADRFLD ; get the desired field number 1845 01304 0104 AND ZK70 ; just in case! 1846 01305 1374 TAD [CDF 0] ; and make a CDF instruction 1847 01306 3307 DCA .+1 ; store that in memory 1848 01307 0000 0 ; isn't self manipulation wonderful? 1849 01310 6225 .POPJ ; that's all 1850 1851 ; This routine will set or clear the panel data flag according to the state 1852 ; of the PNLMEM flag. If PNLMEM is non-zero, the panel data flag is set and 1853 ; commands that access memory (e.g. Examine, Deposit, etc) access panel memory 1854 ; instead. If PNLMEM is zero, then the panel data flag is cleared and these 1855 ; commands access main memory. 1856 01311 7200 CPANEL: CLA ; don't expect anything from the caller 1857 01312 6276 SPD ; assume we're referencing panel memory 1858 01313 1022 TAD PNLMEM ; but get the flag to be sure 1859 01314 7650 SNA CLA ; non-zero means access panel memory 1860 01315 6266 CPD ; we were wrong - use main memory instead 1861 01316 6225 .POPJ ; and we're done 1862 1863 ; This short routine returns, in the AC and memory location VALUE, the 1864 ; contents of the memory location addressed by ADDR and ADRFLD. If PNLMEM is 1865 ; non-zero it reads panel memory to get the data; otherwise it reads main 1866 ; memory... 1867 01317 6205 RDMEM: .PUSHJ CFIELD ; first select the proper field 01320 5302 1868 01321 6205 .PUSHJ CPANEL ; then select main memory or panel memory 01322 5311 1869 01323 1420 TAD @ADDR ; load the data 1870 01324 3027 DCA VALUE ; save the contents in VALUE 1871 01325 1027 TAD VALUE ; and also return it in the AC 1872 01326 6276 SPD ; back to panel memory 1873 01327 6201 CDF 0 ; and back to the monitor's field 1874 01330 6225 .POPJ ; that's all there is 1875 1876 ; This routine will deposit the contents of the AC into the memory location 1877 ; specified by ADRFLD, ADDR and PNLMEM. It's the complement of RDMEM... 1878 01331 3027 WRMEM: DCA VALUE ; save the number to deposit 1879 01332 6205 .PUSHJ CFIELD ; be sure we're in the right field 01333 5302 1880 01334 6205 .PUSHJ CPANEL ; and the right memory space (panel vs main) 01335 5311 1881 01336 1027 TAD VALUE ; get the value back again 1882 01337 3420 DCA @ADDR ; store the data 1883 01340 6276 SPD ; back to panel memory 1884 01341 6201 CDF 0 ; and the monitor's data field 1885 01342 6225 .POPJ ; and return 1886 1887 ; This routine is just like WRMEM, except that it will read back the value 1888 ; deposited and verify that it is, in fact, correct! If it isn't (i.e. there's 1889 ; no memory at that address or the memory there isn't working) a ?MEM ERR 1890 ; message is generated and this command is aborted. 1891 01343 3371 DANDV: DCA GOOD ; save the original, good, value 1892 01344 1371 TAD GOOD ; ... 1893 01345 6205 .PUSHJ WRMEM ; store it 01346 5331 1894 01347 6205 .PUSHJ RDMEM ; read it back PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 43 Read and Write Memory BTS6120.PLX 01350 5317 1895 01351 7041 CIA ; make what we read negative 1896 01352 1371 TAD GOOD ; and compare it to the desired value 1897 01353 7650 SNA CLA ; did they match ?? 1898 01354 6225 .POPJ ; yes -- this memory is ok 1899 1900 ; Type a "?MEM ERR AT faaaa ..." message 1901 01355 4462 JMS @ZINLMES ; type out the first part of the message 1902 01356 3561 MEMMSG ; ... 1903 01357 6205 .PUSHJ @[TADDR] ; then type the address of the error 01360 5773 1904 01361 1371 TAD GOOD ; get the expected value 1905 01362 6205 .PUSHJ @ZTOCT4S ; type that out first 01363 5460 1906 01364 6205 .PUSHJ @ZRDMEM ; read what we actually get from memory 01365 5475 1907 01366 6205 .PUSHJ @ZTOCT4C ; then type that with a CRLF 01367 5457 1908 01370 5477 JMP @ZRESTA ; and bomb this command 1909 1910 ; Temporary storage for DANDV... 1911 01371 GOOD: .BLOCK 1 ; the "good" value we wrote to memory 01373 6400 01374 6201 01375 6200 01376 1500 01377 6277 1912 01400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 44 BM Command -- Memory Block Move BTS6120.PLX 1913 .TITLE BM Command -- Memory Block Move 1914 1915 1916 ; The BM command is used to move blocks of memory words from one location to 1917 ; another. It has three parameters - the source address range (two 15 bit 1918 ; numbers), and the destination address (a single 15 bit number). All words 1919 ; from the starting source address to the ending source address are transferred 1920 ; to the corresponding words starting at the destination address. More than 1921 ; one field may be transferred, and transfers may cross a field boundry. 1922 ; 1923 ; >BM 200-377 400 -> move all of page 1 in the current data field 1924 ; to page 2 of the same field. 1925 ; >BM 0-7777 10000 -> move all of field 0 to field 1 1926 ; >BM 00000-37777 40000 -> move fields 0 thru 3 to fields 4 thru 7 1927 ; 1928 ; Note that this command operates only on main memory - there is no 1929 ; corresponding block move command for panel memory! 1930 ; 1931 01400 6205 BMOVE: .PUSHJ @ZRANGE ; read the source address range 01401 5472 1932 01402 7420 SNL ; did he give 2 numbers ??? 1933 01403 5500 JMP @ZCOMERR ; no -- don't allow a one address range 1934 01404 6205 .PUSHJ @[RDADDR] ; now read the destination 01405 5777 1935 01406 6205 .PUSHJ @ZEOLTST ; this should be the end of the command 01407 5466 1936 01410 3022 DCA PNLMEM ; this command ALWAYS operates on main memory 1937 1938 ; Now copy words from the source to the destination... 1939 01411 6205 MOVE1: .PUSHJ @[SWPADR] ; swap the LOW/LOWFLD (the source address) 01412 5776 1940 01413 6205 .PUSHJ @ZRDMEM ; read a word from the source 01414 5475 1941 01415 6205 .PUSHJ @ZTSTADR ; go see if this is the last address 01416 5473 1942 01417 7630 SZL CLA ; is it the end ??? 1943 01420 7240 STA ; yes -- load -1 into the AC 1944 01421 3047 DCA COUNT ; and remember that fact for later 1945 01422 6205 .PUSHJ @ZNXTADR ; now increment the source address 01423 5474 1946 01424 6205 .PUSHJ @[SWPADR] ; swap the source back into LOW/LOWFLD 01425 5776 1947 01426 1027 TAD VALUE ; get the data we read from the source 1948 01427 6205 .PUSHJ @ZDANDV ; and deposit it in the destination 01430 5476 1949 01431 6205 .PUSHJ @ZNXTADR ; increment the destination address too 01432 5474 1950 01433 7430 SZL ; did we wrap out of field 7 ??? 1951 01434 5240 JMP MOVE2 ; yes -- stop here 1952 01435 2047 ISZ COUNT ; have we copied all the words ?? 1953 01436 5211 JMP MOVE1 ; no -- keep looping 1954 01437 6225 .POPJ ; yes -- that's all 1955 1956 ; Here if the destination address runs out of field 7... 1957 01440 4501 MOVE2: JMS @ZERROR ; don't allow that to continue 1958 01441 3632 ERRWRP ; ?WRAP AROUND PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 45 CK Command -- Checksum Memory BTS6120.PLX 1959 .TITLE CK Command -- Checksum Memory 1960 1961 1962 ; This command will compute the checksum of all memory locations between the 1963 ; two addresses specified and the resulting 12 bit value is then printed 1964 ; on the terminal. This is useful for testing memory, comparing blocks of 1965 ; memory, and so on. Note that the checksum algorithm used rotates the 1966 ; accumulator one bit between each words, so blocks of memory with identical 1967 ; contents in different orders will give different results. 1968 ; 1969 ; >CK 10000-10177 -> checksum all of page 0, field 1 1970 ; 1971 ; Note that this command operates only on main memory - there is no 1972 ; corresponding command for panel memory! 1973 01442 6205 CKMEM: .PUSHJ @ZRANGE ; read a two address range 01443 5472 1974 01444 7420 SNL ; two addresses are required 1975 01445 5500 JMP @ZCOMERR ; ... 1976 01446 6205 .PUSHJ @ZEOLTST ; be sure this is the end of the command 01447 5466 1977 01450 3022 DCA PNLMEM ; this command ALWAYS operates on main memory 1978 01451 3031 DCA CHKSUM ; and clear the checksum accumulator 1979 1980 ; Read words and checksum them... 1981 01452 1031 CKMEM1: TAD CHKSUM ; get the previous total 1982 01453 7104 CLL RAL ; and shift it left one bit 1983 01454 7430 SZL ; did we shift out a one ?? 1984 01455 7001 IAC ; yes -- shift it in the right end 1985 01456 3031 DCA CHKSUM ; save that for a while 1986 01457 6205 .PUSHJ @ZRDMEM ; and go read a word from real memory 01460 5475 1987 01461 1031 TAD CHKSUM ; add it to the checksum 1988 01462 3031 DCA CHKSUM ; save the new checksum 1989 01463 6205 .PUSHJ @ZTSTADR ; compare the addresses next 01464 5473 1990 01465 7430 SZL ; are we all done ?? 1991 01466 5277 JMP TCKSUN ; yes -- type the checksum and return 1992 01467 6205 .PUSHJ @ZNXTADR ; no -- increment the address 01470 5474 1993 01471 5252 JMP CKMEM1 ; and proceed 1994 1995 ; This routine will type out the checksum currently contained in location 1996 ; CHKSUM. If the checksum isn't zero, it will type a question mark (making 1997 ; a pseudo error message) first... 1998 01472 1031 TCKSUM: TAD CHKSUM ; see if the checksum is zero 1999 01473 7650 SNA CLA ; ??? 2000 01474 5277 JMP TCKSUN ; yes -- type it normally 2001 01475 6205 .PUSHJ @[TQUEST] ; no -- type a question mark first 01476 5775 2002 2003 ; Now type the checksum... 2004 01477 4462 TCKSUN: JMS @ZINLMES ; type out the checksum message 2005 01500 3550 CKSMSG ; ... 2006 01501 1031 TAD CHKSUM ; get the actual checksum 2007 01502 5457 JMP @ZTOCT4C ; type it with a CRLF and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 46 CM and FM Commands -- Clear Memory and Fill Memory BTS6120.PLX 2008 .TITLE CM and FM Commands -- Clear Memory and Fill Memory 2009 2010 2011 ; The FM command fills a range of memory locations with a constant. For 2012 ; example: 2013 ; 2014 ; >FM 7402 0-7777 -> fill all of field zero with HLT instructions 2015 ; >FM 7777 0-77777 -> fill all of memory with -1 2016 ; 2017 ; The second and third arguments (the address range) may be omitted, in 2018 ; which case all of memory is filled. 2019 ; 2020 ; Note that this command operates only on main memory - there is no 2021 ; corresponding command for panel memory! 2022 01503 6205 FLMEM: .PUSHJ @ZOCTNW ; read the constant to fill with 01504 5471 2023 01505 1045 TAD WORD ; get the desired value 2024 01506 5312 JMP CMEM0 ; then join the CM command 2025 2026 ; The CM command is identical to FM, except that the fill value is always 2027 ; zero (hence the name - "Clear" memory). For example: 2028 ; 2029 ; >CM 50000 57777 -> clear all of field 5 2030 ; >CM -> (with no arguments) clear all of memory! 2031 ; 2032 ; Like FM, this command operates only on main memory. There is no 2033 ; equivalent for panel memory. 2034 01507 6205 CMEM: .PUSHJ @ZGET ; advance the scanner to the break character 01510 5470 2035 01511 7200 CLA ; and throw it away for now 2036 01512 3027 CMEM0: DCA VALUE ; and fill with zeros 2037 01513 3020 DCA ADDR ; initialize the address range to start 2038 01514 3021 DCA ADRFLD ; at location 0000, field 0 2039 01515 7240 STA ; and to finish at location 7777, 2040 01516 3023 DCA HIGH ; ... 2041 01517 1104 TAD ZK70 ; field 7 2042 01520 3025 DCA HGHFLD ; ... 2043 01521 3022 DCA PNLMEM ; this command ALWAYS operates on main memory 2044 2045 ; See if there is an address range... 2046 01522 6205 .PUSHJ @ZSPACM0 ; get the break character 01523 5464 2047 01524 7650 SNA CLA ; is there any more out there ?? 2048 01525 5334 JMP CMEM1 ; no -- start filling 2049 01526 6205 .PUSHJ @ZBACKUP ; yes - backup to the first character 01527 5465 2050 01530 6205 .PUSHJ @ZRANGE ; and read the address range 01531 5472 2051 01532 6205 .PUSHJ @ZEOLTST ; then check for the end of the line 01533 5466 2052 2053 ; Clear/set memory locations... 2054 01534 1027 CMEM1: TAD VALUE ; get the value to store 2055 01535 6205 .PUSHJ @ZDANDV ; store it and verify 01536 5476 2056 01537 6205 .PUSHJ @ZTSTADR ; see if we have done all the addresses 01540 5473 2057 01541 7430 SZL ; well ?? 2058 01542 6225 .POPJ ; yes -- we can stop now 2059 01543 6205 .PUSHJ @ZNXTADR ; no -- increment the address field 01544 5474 2060 01545 5334 JMP CMEM1 ; then go clear this word 2061 01575 7066 01576 6521 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 47 CM and FM Commands -- Clear Memory and Fill Memory BTS6120.PLX 01577 6416 2062 01600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 48 WS Command -- Word Search Memory BTS6120.PLX 2063 .TITLE WS Command -- Word Search Memory 2064 2065 2066 ; The WS command searches memory for a specific bit pattern. It accepts up 2067 ; to 4 operands: (1) the value to search for, (2) the starting search address, 2068 ; (3) the final search address, and (4) a search mask. All values except the 2069 ; first are optional and have appropriate defaults. Any location in the 2070 ; specified range which matches the given value after being masked is typed 2071 ; out along with its address. For example: 2072 ; 2073 ; >WS 6031 -> search all of memory for KSF instructions 2074 ; >WS 6031 30000-33777 -> search words 0..3377 of field 3 for KSFs 2075 ; >WS 6030 0-77777 7770 -> search memory for any keyboard IOTs 2076 ; 2077 ; N.B. this command operates only on main memory and there is no equivalent 2078 ; for panel memory. 2079 2080 ; Read the first (required) operand and set defaults for all the rest... 2081 01600 6205 SEARCH: .PUSHJ @ZOCTNW ; read the value to search for 01601 5471 2082 01602 1045 TAD WORD ; then get that 2083 01603 3272 DCA KEY ; and save it 2084 01604 3020 DCA ADDR ; set the starting address to 0 2085 01605 3021 DCA ADRFLD ; in field 0 2086 01606 7240 STA ; then stop at location 7777 2087 01607 3023 DCA HIGH ; ... 2088 01610 1104 TAD ZK70 ; field 7 2089 01611 3025 DCA HGHFLD ; ... 2090 01612 7240 STA ; and set the mask to 7777 2091 01613 3273 DCA MASK ; ... 2092 01614 3022 DCA PNLMEM ; this command _always_ searches main memory 2093 2094 ; Try to read any optional operands... 2095 01615 1033 TAD SAVCHR ; is there any more there ?? 2096 01616 7650 SNA CLA ; ??? 2097 01617 5233 JMP SEAR1 ; no -- start looking 2098 01620 6205 .PUSHJ @ZRANGE ; yes -- read the address range 01621 5472 2099 01622 1033 TAD SAVCHR ; is there a mask out there ?? 2100 01623 7650 SNA CLA ; ??? 2101 01624 5233 JMP SEAR1 ; no -- start looking 2102 01625 6205 .PUSHJ @ZOCTNW ; yes -- read the mask too 01626 5471 2103 01627 1045 TAD WORD ; load the mask 2104 01630 3273 DCA MASK ; and save that for later 2105 01631 6205 .PUSHJ @ZEOLTST ; this has to be the end of the line 01632 5466 2106 2107 ; Here to start the search... 2108 01633 3047 SEAR1: DCA COUNT ; count the number of matches we find 2109 01634 1272 TAD KEY ; get the search key 2110 01635 0273 AND MASK ; apply the mask to it too 2111 01636 7041 CIA ; make it negative 2112 01637 3272 DCA KEY ; and remember that instead 2113 2114 ; Look through memory for matches... 2115 01640 6205 SEAR2: .PUSHJ @[INCHRS] ; poll the operator for control-C 01641 5777 2116 01642 6205 .PUSHJ @ZRDMEM ; read a word from real memory 01643 5475 2117 01644 0273 AND MASK ; apply the mask to it 2118 01645 1272 TAD KEY ; and compare to the value 2119 01646 7640 SZA CLA ; does it match ?? 2120 01647 5256 JMP SEAR3 ; no -- skip it 2121 01650 6205 .PUSHJ @[TMEM] ; yes -- type the address and contents PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 49 WS Command -- Word Search Memory BTS6120.PLX 01651 5776 2122 01652 6205 .PUSHJ @ZCRLF ; then finish the line 01653 5461 2123 01654 7240 STA ; make the AC non-zero 2124 01655 3047 DCA COUNT ; and remember that we found a match 2125 01656 6205 SEAR3: .PUSHJ @ZTSTADR ; see if we have looked everywhere 01657 5473 2126 01660 7430 SZL ; well ?? 2127 01661 5265 JMP SEAR4 ; yes -- finish up now 2128 01662 6205 .PUSHJ @ZNXTADR ; no -- increment the address 01663 5474 2129 01664 5240 JMP SEAR2 ; and keep looking 2130 2131 ; Here at the end of the search... 2132 01665 1047 SEAR4: TAD COUNT ; see how many matches there were 2133 01666 7640 SZA CLA ; were there any at all ?? 2134 01667 6225 .POPJ ; yes -- that's fine 2135 01670 4501 JMS @ZERROR ; no -- give an error message 2136 01671 3610 ERRSRF ; ? SEARCH FAILS 2137 2138 ; Temporary storage for the SEARCH routine... 2139 01672 KEY: .BLOCK 1 ; a search key 2140 01673 MASK: .BLOCK 1 ; a search mask 2141 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 50 BL Command -- List Breakpoints BTS6120.PLX 2142 .TITLE BL Command -- List Breakpoints 2143 2144 2145 ; This command will list all the breakpoints which are currently set in 2146 ; the user's program. It has no operands... 2147 ; 2148 ; >BL 2149 ; 2150 01674 6205 BLIST: .PUSHJ @ZEOLNXT ; there should be no more 01675 5467 2151 01676 6205 .PUSHJ BSETUP ; set up X1, X2 and COUNT 01677 5324 2152 01700 3027 DCA VALUE ; count the number of breakpoints here 2153 2154 ; Loop through the breakpoint table and list all valid breakpoints... 2155 01701 1410 BLIST1: TAD @X1 ; get the address of this breakpoint 2156 01702 3020 DCA ADDR ; and remember that 2157 01703 1411 TAD @X2 ; then get the corresponding field 2158 01704 3021 DCA ADRFLD ; ... 2159 01705 1020 TAD ADDR ; let's see that address again 2160 01706 7650 SNA CLA ; is there really a breakpoint set here ?? 2161 01707 5315 JMP BLIST2 ; no -- on to the next one 2162 01710 6205 .PUSHJ @[TMEM] ; yes -- type out the address and memory 01711 5776 2163 01712 6205 .PUSHJ @ZCRLF ; finish this line 01713 5461 2164 01714 2027 ISZ VALUE ; and count the number we find 2165 01715 2047 BLIST2: ISZ COUNT ; are there more breakpoints to do? 2166 01716 5301 JMP BLIST1 ; yes - keep going 2167 2168 ; Here after going through the table... 2169 01717 1027 TAD VALUE ; see how many we found 2170 01720 7640 SZA CLA ; any at all ?? 2171 01721 6225 .POPJ ; yes -- that's great 2172 01722 4501 JMS @ZERROR ; no -- print an error message 2173 01723 4021 ERRNBP ; ?NONE SET 2174 2175 ; This routine will set up the pointers for traversing the break point 2176 ; table. X1 always points to the break point address table, X2 points to 2177 ; the break point field table, and X3 points to the break point data table. 2178 ; COUNT is initialized to the negative of the table size (all three tables 2179 ; are the same size) so that it can be used as an ISZ counter. This same 2180 ; arrangement of pointers is used by all the routines that operate on 2181 ; breakpoints. 2182 01724 7200 BSETUP: CLA ; just in case... 2183 01725 1375 TAD [BPTADR-1] ; X1 points to the address table 2184 01726 3010 DCA X1 ; ... 2185 01727 1374 TAD [BPTFLD-1] ; X2 points to the field table 2186 01730 3011 DCA X2 ; ... 2187 01731 1373 TAD [BPTDAT-1] ; X3 points to the data table 2188 01732 3012 DCA X3 ; ... 2189 01733 1372 TAD [-MAXBPT] ; and COUNT is the table size 2190 01734 3047 DCA COUNT ; ... 2191 01735 3022 DCA PNLMEM ; break points always refer to main memory! 2192 01736 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 51 Search for Breakpoints BTS6120.PLX 2193 .TITLE Search for Breakpoints 2194 2195 2196 ; This routine will search the breakpoint table to see if there is a one set 2197 ; at the location specified by ADDR and ADRFLD. If one is found, it will 2198 ; return with the LINK set and with X1/X2 pointing to the table entry. If 2199 ; there is no breakpoint at the specified address, it returns with the LINK 2200 ; cleared. 2201 01737 6205 BPTFND: .PUSHJ BSETUP ; set up X1, X2 and COUNT 01740 5324 2202 2203 ; Look through the entire table... 2204 01741 1410 BPTFN1: TAD @X1 ; get this breakpoint address 2205 01742 7450 SNA ; is there breakpoint here at all ?? 2206 01743 5357 JMP BPTFN2 ; no -- just forget it 2207 01744 7041 CIA ; make this address negative 2208 01745 1020 TAD ADDR ; and compare to what we want 2209 01746 7640 SZA CLA ; does it match ?? 2210 01747 5357 JMP BPTFN2 ; no -- on to the next one 2211 01750 1411 TAD @X2 ; yes -- get the field number 2212 01751 7041 CIA ; make that negative 2213 01752 1021 TAD ADRFLD ; and compare to the field we need 2214 01753 7640 SZA CLA ; do they match to ?? 2215 01754 5360 JMP BPTFN3 ; no -- keep looking 2216 01755 7120 STL ; yes -- set the LINK 2217 01756 6225 .POPJ ; and stop right now 2218 2219 ; Here if the current address dosen't match... 2220 01757 2011 BPTFN2: ISZ X2 ; increment the field pointer too 2221 01760 2047 BPTFN3: ISZ COUNT ; have we searched the entire table? 2222 01761 5341 JMP BPTFN1 ; no -- keep looking 2223 01762 7100 CLL ; yes -- clear the LINK 2224 01763 6225 .POPJ ; and return 2225 01772 7770 01773 0220 01774 0210 01775 0200 01776 1060 01777 7477 2226 02000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 52 BR Command -- Remove Breakpoints BTS6120.PLX 2227 .TITLE BR Command -- Remove Breakpoints 2228 2229 2230 ; The BR command removes a breakpoint at a specific address or, if no 2231 ; operand is given, removes all breakpoints. For example: 2232 ; 2233 ; >BR 17605 -> remove the breakpoint at location 7605, field 1 2234 ; >BR -> remove all breakpoints regardless of address 2235 ; 2236 02000 6205 BREMOV: .PUSHJ @ZGET ; get the next character 02001 5470 2237 02002 7650 SNA CLA ; is it the end of the line ?? 2238 02003 5226 JMP BPTCLR ; yes -- clear all breakpoints 2239 02004 6205 .PUSHJ @ZBACKUP ; no -- backup the scanner 02005 5465 2240 02006 6205 .PUSHJ @[OCTNI] ; then read an address 02007 5777 2241 02010 1045 TAD WORD ; get the breakpoint address 2242 02011 7450 SNA ; be sure it isn't location zero 2243 02012 5500 JMP @ZCOMERR ; that isn't legal 2244 02013 3020 DCA ADDR ; save the address of the breakpoint 2245 2246 ; Here to remove a single breakpoint... 2247 02014 6205 .PUSHJ @[BPTFND] ; look for this breakpoint it the table 02015 5776 2248 02016 7420 SNL ; did we find it ?? 2249 02017 5224 JMP BREMO1 ; no -- there's no breakpoint at that address 2250 02020 1010 TAD X1 ; yes -- get the pointer to BPTADR 2251 02021 3020 DCA ADDR ; and save it in a non-autoindex location 2252 02022 3420 DCA @ADDR ; clear the BPTADR entry (to remove it) 2253 02023 6225 .POPJ ; and that's all 2254 2255 ; Here if the breakpoint does not exist... 2256 02024 4501 BREMO1: JMS @ZERROR ; give an appropriate error message 2257 02025 4030 ERRNST ; ?NOT SET 2258 2259 ; Here to clear all breakpoints... 2260 02026 6205 BPTCLR: .PUSHJ @[BSETUP] ; setup X1, X2, X3 and COUNT 02027 5775 2261 02030 3410 BPTCL2: DCA @X1 ; clear this breakpoint 2262 02031 3411 DCA @X2 ; ... 2263 02032 3412 DCA @X3 ; ... 2264 02033 2047 ISZ COUNT ; have we done them all? 2265 02034 5230 JMP BPTCL2 ; no -- keep looping 2266 02035 6225 .POPJ ; yes -- that's it PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 53 BP Command -- Set Breakpoints BTS6120.PLX 2267 .TITLE BP Command -- Set Breakpoints 2268 2269 2270 ; The BP command sets a breakpoint in the main memory (aka user) program. 2271 ; It requires a single argument giving the 15 bit address where the breakpoint 2272 ; is to be set. For example: 2273 ; 2274 ; >BP 07605 -> set a breakpoint at location 7605, field 0 2275 ; >BP 7605 -> same, but in the current instruction field 2276 ; 2277 ; It's not possible to set a breakpoint at location zero in any field because 2278 ; the monitor uses zero as a marker for an unused breakpoint table entry. 2279 ; 2280 ; Note that this routine only enters the breakpoint into the table - nothing 2281 ; actually happens to the main memory program until we start running it and 2282 ; the BPTINS routine is called. 2283 02036 6205 BPTCOM: .PUSHJ @[OCTNI] ; go read the address 02037 5777 2284 02040 1045 TAD WORD ; get the address operand 2285 02041 7450 SNA ; be sure it isn't zero 2286 02042 5500 JMP @ZCOMERR ; no breakpoints at address zero 2287 02043 3020 DCA ADDR ; and put it in a safe place 2288 02044 6205 .PUSHJ @ZEOLTST ; then test for the end of the line 02045 5466 2289 2290 ; See if this breakpoint is already in the table.. 2291 02046 6205 .PUSHJ @[BPTFND] ; ... 02047 5776 2292 02050 7620 SNL CLA ; was it found ?? 2293 02051 5254 JMP BPTCO1 ; no -- go try to add it 2294 02052 4501 JMS @ZERROR ; yes -- say that it is already set 2295 02053 4036 ERRAST ; ?ALREADY SET 2296 2297 ; Here to search for a free location in the table... 2298 02054 6205 BPTCO1: .PUSHJ @[BSETUP] ; setup X1 and COUNT 02055 5775 2299 02056 2011 BPTCO2: ISZ X2 ; keep X1 and X2 in sync 2300 02057 1410 TAD @X1 ; get this table entry 2301 02060 7650 SNA CLA ; have we found an empty one ?? 2302 02061 5266 JMP BPTCO3 ; yes -- great 2303 02062 2047 ISZ COUNT ; have we searched the entire table? 2304 02063 5256 JMP BPTCO2 ; no -- keep trying 2305 02064 4501 JMS @ZERROR ; yes -- say that the table is full 2306 02065 4047 ERRBTF ; ?TABLE FULL 2307 2308 ; Here to insert the breakpoint in the table... 2309 02066 1010 BPTCO3: TAD X1 ; get the pointer to the free location 2310 02067 3024 DCA LOW ; and put it in a non-autoindex location 2311 02070 1020 TAD ADDR ; get the desired address 2312 02071 3424 DCA @LOW ; and store that in the table 2313 02072 1011 TAD X2 ; do the same with the field table 2314 02073 3024 DCA LOW ; ... 2315 02074 1021 TAD ADRFLD ; get the field we need 2316 02075 3424 DCA @LOW ; and put that in the table 2317 02076 6225 .POPJ ; then that's all PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 54 Insert Breakpoints in Memory BTS6120.PLX 2318 .TITLE Insert Breakpoints in Memory 2319 2320 2321 ; This routine will insert breakpoints in main memory (aka the user program) 2322 ; at the locations specified in the breakpoint table. The current contents of 2323 ; each breakpoint location are stored in CP memory in the BPTDAT table, and 2324 ; then are replaced by a BPT instruction. This routine is normally called 2325 ; just before returning control to the user's program. 2326 02077 6205 BPTINS: .PUSHJ @[BSETUP] ; set up X1, X2, X3 and COUNT 02100 5775 2327 2328 ; Loop through the table and insert the breakpoints... 2329 02101 1410 BPTIN1: TAD @X1 ; get the next address 2330 02102 7450 SNA ; is there a breakpoint set there ?? 2331 02103 5316 JMP BPTIN2 ; no -- proceed to the next one 2332 02104 3020 DCA ADDR ; yes -- save the address 2333 02105 1411 TAD @X2 ; and get the field 2334 02106 3021 DCA ADRFLD ; save that too 2335 02107 6205 .PUSHJ @ZRDMEM ; go read the contents of that location 02110 5475 2336 02111 3412 DCA @X3 ; save the user's data in the table 2337 02112 1374 TAD [BPT] ; then get a breakpoint instruction 2338 02113 6205 .PUSHJ @ZDANDV ; deposit that in the breakpoint location 02114 5476 2339 02115 5320 JMP BPTIN3 ; proceed to the next one 2340 2341 ; See if we have finished the table... 2342 02116 2011 BPTIN2: ISZ X2 ; keep the pointers in sync 2343 02117 2012 ISZ X3 ; ... 2344 02120 2047 BPTIN3: ISZ COUNT ; have we been all the way through ?? 2345 02121 5301 JMP BPTIN1 ; no -- keep going 2346 02122 6225 .POPJ ; yes -- quit now PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 55 Remove Breakpoints from Memory BTS6120.PLX 2347 .TITLE Remove Breakpoints from Memory 2348 2349 2350 ; This routine will restore the original contents of all breakpoint locations 2351 ; in the main memory program from the table at BPTDAT. It is normally called 2352 ; after a trap to CP memory occurs. Breakpoints must be restored so that the 2353 ; user may examine or change them. 2354 02123 6205 BPTRMV: .PUSHJ @[BSETUP] ; set up X1, X2, X3 and COUNT 02124 5775 2355 2356 ; Loop through the breakpoint table and restore all data... 2357 02125 1410 BPTRM1: TAD @X1 ; get the address of this breakpoint 2358 02126 7450 SNA ; is there one there at all ?? 2359 02127 5337 JMP BPTRM2 ; no -- on to the next one 2360 02130 3020 DCA ADDR ; yes -- remember the address 2361 02131 1411 TAD @X2 ; then get the correct field too 2362 02132 3021 DCA ADRFLD ; ... 2363 02133 1412 TAD @X3 ; finally get the original contents 2364 02134 6205 .PUSHJ @ZDANDV ; deposit and verify it back where it goes 02135 5476 2365 02136 5341 JMP BPTRM3 ; on to the next one 2366 2367 ; Here to advance to the next breakpoint... 2368 02137 2011 BPTRM2: ISZ X2 ; keep the pointers in sync 2369 02140 2012 ISZ X3 ; ... 2370 02141 2047 BPTRM3: ISZ COUNT ; have we done them all ?? 2371 02142 5325 JMP BPTRM1 ; no -- keep looping 2372 02143 6225 .POPJ ; yes -- that's it for this time PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 56 TR Command -- Single Instruction with Trace BTS6120.PLX 2373 .TITLE TR Command -- Single Instruction with Trace 2374 2375 2376 ; The TR command will execute one instruction of the user's program and then 2377 ; print the registers. It always executes one instruction, but it may be 2378 ; combined with the repeat (RP) command to execute multiple instructions. 2379 02144 6205 SICOM: .PUSHJ @ZEOLNXT ; there are no operands 02145 5467 2380 2381 ; Figure out what we are going to execute... 2382 02146 1002 TAD UFLAGS ; get the instruction field 2383 02147 0104 AND ZK70 ; ... 2384 02150 3021 DCA ADRFLD ; so we can change to that field 2385 02151 1000 TAD UPC ; get the current main memory PC 2386 02152 3020 DCA ADDR ; and point to that 2387 02153 3022 DCA PNLMEM ; always access main memory 2388 02154 6205 .PUSHJ @ZRDMEM ; go read what we're about to execute 02155 5475 2389 02156 3006 DCA UIR ; remember that for later 2390 2391 ; Execute 1 instruction... 2392 02157 6205 .PUSHJ @[SINGLE] ; just like it says 02160 5773 2393 2394 ; Print all the registers... 2395 02161 6205 .PUSHJ @[TYPEIR] ; first type the UIR 02162 5772 2396 02163 5771 JMP @[REGLSC] ; and then print the rest and return 2397 02171 1240 02172 1263 02173 2202 02174 6236 02175 1724 02176 1737 02177 7000 2398 02200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 57 SI and P Commands - Single Instruction and Proceed BTS6120.PLX 2399 .TITLE SI and P Commands - Single Instruction and Proceed 2400 2401 2402 ; This routine will execute a single instruction of the user's program and 2403 ; then return to the caller. It is used directly to execute the SI command, 2404 ; and indirectly by many other commands... 2405 2406 ; Here for the SI command... 2407 02200 6205 SNCOM: .PUSHJ @ZEOLNXT ; make sure that there is no more 02201 5467 2408 2409 ; Setting the HALT flip flop will cause the HM6120 to immediately trap back 2410 ; to panel mode after it has executed exactly one instruction of the main 2411 ; memory program. This makes it easy to implement a single step function. 2412 ; 2413 ; Note that SINGLE is a subroutine which you can actually call, via a 2414 ; .PUSHJ, from anywhere in the monitor and it will return after the main 2415 ; memory instruction has been executed. This little bit of magic happens 2416 ; because the code at CONT1 saves the monitor stack and then restores 2417 ; it after the single instruction trap. 2418 02202 6003 SINGLE: PGO ; first make sure the HALT flip flop is cleared 2419 02203 7402 HLT ; then make sure it's set 2420 02204 7240 STA ; set the software single step flag 2421 02205 3032 DCA SIMFLG ; ... so that CPSAVE will know what to do 2422 02206 5222 JMP CONT1 ; then restore the registers and go 2423 2424 ; The P command is used to proceed after the main memory program has stopped 2425 ; at a breakpoint. You can't simply continue at this point because the PC 2426 ; points to the location of the breakpoint, and Continue would simply break 2427 ; again, instantly. The Proceed command gets around this problem by first 2428 ; executing a single instruction, and then contining normally. 2429 02207 6205 PROCEE: .PUSHJ @ZEOLNXT ; this command has no operands 02210 5467 2430 02211 6205 .PUSHJ SINGLE ; first execute the location under the BPT 02212 5202 2431 02213 5216 JMP CONT ; then restore the breakpoints and continue PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 58 C Command - Restore Main Memory Context and Continue BTS6120.PLX 2432 .TITLE C Command - Restore Main Memory Context and Continue 2433 2434 2435 ; This routine will restore all the user's registers and return to his 2436 ; program. It is called directly for the continue command, and is used 2437 ; indirectly (to change contexts) by several other commands. 2438 ; 2439 ; When this routine finishes in the most literal sense, the user mode 2440 ; program is running and the monitor is no longer active. However the 2441 ; CONT function can and will actually return, via a POPJ, if the user 2442 ; program causes a breakpoint or single instruction trap. This property is 2443 ; critical to the operation of the Proceed, TRace and Single Instruction 2444 ; commands! 2445 2446 ; Here for the continue command... 2447 02214 6205 CONTCM: .PUSHJ @ZEOLNXT ; continue has no operands 02215 5467 2448 2449 ; Select free running mode and insert all breakpoints... 2450 02216 6205 CONT: .PUSHJ @[BPTINS] ; insert all breakpoints 02217 5777 2451 02220 3032 DCA SIMFLG ; clear our software single step flag 2452 02221 6003 PGO ; make sure the HALT flip-flop is cleared 2453 2454 ; Restore all registers and context switch. Naturally, part of this involves 2455 ; restoring the original user mode stack pointers, so before we lose our own 2456 ; stack forever, we save a copy of the last monitor stack pointer in RAM. It 2457 ; gets restored by the code at CPSAVE after a breakpoint or single instruction 2458 ; trap. 2459 ; 2460 ; Another gotcha - if a transition on CPREQ L occurs while we're in panel 2461 ; mode, the BTSTRP flag in the panel status will still set anyway. If that 2462 ; happens and we try to continue, the 6120 will trap back to panel mode 2463 ; immediately. The simplest fix for this is to do a dummy read of the panel 2464 ; status flags, which clears them. 2465 02222 6000 CONT1: PRS ; dummy read of panel status to clear BTSTRP 2466 02223 6207 RSP1 ; get our monitor's stack pointer 2467 02224 3113 DCA STKSAV ; and save it for later 2468 02225 6440 POST+0 ; show post code 0 2469 02226 1004 TAD USP1 ; reload stack pointer #1 2470 02227 6217 LSP1 ; ... 2471 02230 1005 TAD USP2 ; and stack #2 2472 02231 6237 LSP2 ; ... 2473 02232 1003 TAD UMQ ; restore the MQ register 2474 02233 7421 MQL ; ... 2475 02234 1002 TAD UFLAGS ; restore the flags, including IF, DF and LINK 2476 02235 6005 RTF ; ... 2477 02236 1001 TAD UAC ; restore the AC 2478 02237 6004 PEX ; exit panel mode 2479 02240 5400 JMP @UPC ; and, lastly, restore the PC 2480 2481 ; At this point we're running the main memory program. If that program 2482 ; causes a breakpoint or single instruction trap, then the HM6120 will enter 2483 ; the CPSAVE routine thru the vector at 7777. After it figures out the reason 2484 ; for the trap, CPSAVE will restore the original monitor's stack, from STKSAV, 2485 ; and execute a .POPJ. Only then will this routine "return". PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 59 ST Command -- Start a Main Memory Program BTS6120.PLX 2486 .TITLE ST Command -- Start a Main Memory Program 2487 2488 2489 ; The start command initializes the CPU registers and all I/O devices and 2490 ; then transfers control to a main memory (user) program. A single, optional, 2491 ; argument may be given to specify the start address of the the main memory 2492 ; program. If the start address is omitted, then the default is location 2493 ; 7777 of field 0 (this is a little strange by PDP-8 standards, but it's the 2494 ; typical reset vector for 6100 and 6120 devices). For example: 2495 ; 2496 ; >ST 00200 - start at location 200 in field 0 (DF is also 0) 2497 ; >ST 70200 - start at location 200 in field 7 (DF is also 7) 2498 ; >ST - start at location 7777 of field 0 (DF is also 0) 2499 ; 2500 02241 6205 START: .PUSHJ @ZGET ; get the next character 02242 5470 2501 02243 7650 SNA CLA ; is there anything out there ?? 2502 02244 5265 JMP START1 ; no -- use the defaults 2503 2504 ; Start at a specific (non-default) address... 2505 02245 6205 .PUSHJ @ZBACKUP ; backup to the start of the address 02246 5465 2506 02247 6205 .PUSHJ @[OCTNI] ; then read it 02250 5776 2507 02251 6205 .PUSHJ @ZEOLTST ; now it has to be the end of the line 02252 5466 2508 02253 6205 .PUSHJ CLRCPU ; clear the saved main memory registers 02254 5304 2509 02255 1045 TAD WORD ; and overwrite the PC with the desired address 2510 02256 3000 DCA UPC ; ... 2511 02257 1021 TAD ADRFLD ; get the start field 2512 02260 7112 CLL RTR ; and make the DF be the same 2513 02261 7106 CLL RTL ; ... 2514 02262 1021 TAD ADRFLD ; ... 2515 02263 3002 DCA UFLAGS ; those are the default processor flags 2516 02264 5216 JMP CONT ; insert any breakpoints and then go 2517 2518 ; Start at the default address. 2519 02265 6205 START1: .PUSHJ CLRCPU ; set all main saved CPU registers to default 02266 5304 2520 02267 5216 JMP CONT ; and then start there PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 60 MR Command - Master Reset BTS6120.PLX 2521 .TITLE MR Command - Master Reset 2522 2523 2524 ; The MR command executes a CAF instruction to assert IOCLR L and initialize 2525 ; all external I/O devices, and then it resets the saved state of the main 2526 ; memory program to the "default" values. From the point of view of an I/O 2527 ; device on the bus, this is equivalent to pressing the RESET button, but it 2528 ; doesn't actually reset the CPU itself (which would re-initialize this 2529 ; monitor!). This command doesn't have any effect on the contents of main 2530 ; memory. 2531 02270 6205 CLRCOM: .PUSHJ @ZEOLNXT ; There are no operands 02271 5467 2532 2533 ; Initialize the saved user context... 2534 02272 6205 .PUSHJ CLRCPU ; clear UAC, UPC, UMQ, etc... 02273 5304 2535 2536 ; Execute a CAF instruction to clear all I/O devices. On the IM6100 we 2537 ; couldn't do this, since CAF would also clear the CP flag (!), but the 6120 2538 ; designers allowed for this case. 2539 ; 2540 ; Unfortunately IOCLR L also resets the console UART, which plays havoc 2541 ; with any character that we might be transmitting at the moment. The only 2542 ; safe thing is to wait for the console to finish before executing the CAF. 2543 ; Note that this will _leave_ the console flag cleared, which is the way a 2544 ; real PDP-8 program should expect it (clearing a real PDP-8 clears the 2545 ; console flag too, after all). 2546 02274 6041 TSF ; has the console finished yet? 2547 02275 5274 JMP .-1 ; no - wait for it 2548 02276 6007 CAF ; clear all I/O flags 2549 2550 ; Reset the IDE disk too. If none is attached, then this is harmless... 2551 02277 4502 JMS @ZPUSHJ1 ; (cross field call) 2552 02300 1013 IDEINI ; reset the IDE disk and then return 2553 02301 4502 JMS @ZPUSHJ1 ; (cross field call) 2554 02302 1513 INIPMP ; and initialize the partition map 2555 02303 6225 .POPJ ; all done ... 2556 2557 2558 ; This routine is called by the START and RESET commands and at system 2559 ; initialization to clear the saved user context... 2560 02304 7200 CLRCPU: CLA ; start with all zeros 2561 02305 3001 DCA UAC ; clear the AC 2562 02306 3003 DCA UMQ ; and the MQ 2563 02307 3002 DCA UFLAGS ; the DF, IF and LINK 2564 02310 3004 DCA USP1 ; stack pointer #1 2565 02311 3005 DCA USP2 ; and #2 2566 02312 7240 STA ; then finally set the PC to 7777 2567 02313 3000 DCA UPC ; ... 2568 02314 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 61 EX Command - Execute IOT Instructions BTS6120.PLX 2569 .TITLE EX Command - Execute IOT Instructions 2570 2571 2572 ; The EX command allows a user to type in and execute an IOT instruction 2573 ; directly from the terminal, which can be very useful for testing peripheral 2574 ; devices. Either one or two operands are allowed - the first is the octal 2575 ; code of the IOT to be executed, and the second (which is optional) is a 2576 ; value to be placed in the AC before the IOT is executed. If it is omitted, 2577 ; zero is placed in the AC. After the instruction is executed, the word SKIP 2578 ; is typed if the instruction skipped, along with the new contents of the AC. 2579 ; 2580 ; >EX 6471 -> execute IOT 6741 (the AC will be cleared) 2581 ; >EX 6474 1176 -> put 1176 in the AC and execute IOT 6474 2582 ; 2583 ; WARNING - some care must be exercised with this command, since executing 2584 ; the wrong IOT can crash the monitor! 2585 02315 6205 XCTCOM: .PUSHJ @ZOCTNW ; go read the IOT instruction code 02316 5471 2586 02317 1045 TAD WORD ; then get the value 2587 02320 3341 DCA XCTBLK ; save that where we'll execute it 2588 02321 3045 DCA WORD ; assume to use zero in the AC 2589 02322 1033 TAD SAVCHR ; next get the break character 2590 02323 7650 SNA CLA ; was it the end of the line ?? 2591 02324 5331 JMP XCT1 ; yes -- default to zero 2592 02325 6205 .PUSHJ @ZOCTNW ; no -- read another number 02326 5471 2593 02327 6205 .PUSHJ @ZEOLTST ; then test for the end of the line 02330 5466 2594 2595 ; Be sure the instruction is really an IOT... 2596 02331 1341 XCT1: TAD XCTBLK ; get the instruction 2597 02332 1375 TAD [-6000] ; compare it to 6000 2598 02333 7700 SMA CLA ; is it an IOT or OPR instruction ? 2599 02334 5337 JMP XCT2 ; yes -- that's OK 2600 02335 4501 JMS @ZERROR ; no -- don't allow this 2601 02336 3576 ERRILV ; ?ILLEGAL VALUE 2602 2603 ; Execute the instruction... 2604 02337 3047 XCT2: DCA COUNT ; will be non-zero if the IOT doesn't skip 2605 02340 1045 TAD WORD ; get the value we're supposed to put in the AC 2606 02341 7000 XCTBLK: NOP ; gets overwritten with the IOT to execute 2607 02342 2047 ISZ COUNT ; set the flag if it doesn't skip 2608 02343 3027 DCA VALUE ; and remember what is left in the AC 2609 2610 ; Print the results of the instruction.. 2611 02344 1047 TAD COUNT ; see if it skipped 2612 02345 7640 SZA CLA ; well ?? 2613 02346 5351 JMP XCT3 ; no -- no message 2614 02347 4462 JMS @ZINLMES ; yes -- say that it did 2615 02350 3643 SKPMSG ; ... 2616 02351 4462 XCT3: JMS @ZINLMES ; then print the AC after the instruction 2617 02352 4057 ACNAME ; ... 2618 02353 1027 TAD VALUE ; ... 2619 02354 5457 JMP @ZTOCT4C ; in octal, with a CRLF, and return 2620 02375 2000 02376 7000 02377 2077 2621 02400 .PAGE 2622 .TITLE OS/8 Bootstrap 2623 2624 2625 ; How to boot OS/8 (there's lots of documentation on how to write a device 2626 ; handler, even a system handler, but I couldn't find a description of how 2627 ; to make a bootable device anywhere!): PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 62 OS/8 Bootstrap BTS6120.PLX 2628 ; 2629 ; The primary bootstrap for a device (the one which you have to toggle in 2630 ; with the switches!) normally loads cylinder 0, head 0, sector 0 (which is 2631 ; the equivalent to OS/8 logical block zero) into memory page zero field zero. 2632 ; The code loaded into page zero is then started in some device specific way, 2633 ; but usually the primary bootstrap is overwritten by this data and the CPU 2634 ; just "ends up" there. 2635 ; 2636 ; The first few words of block zero are called the secondary bootstrap, and 2637 ; it's normally found in the header for the system device handler. OS/8 BUILD 2638 ; copies this code from the handler to block zero when it builds the system 2639 ; device. The second half of block zero contains the system handler, what's 2640 ; resident in page 7600 while OS/8 is running, plus some OS/8 resident code 2641 ; that BUILD wraps around it. All of the second half of block zero must be 2642 ; loaded into page 7600, field 0 by the secondary bootstrap. 2643 ; 2644 ; The remainder of the first half of block zero, the part after the secondary 2645 ; bootstrap, contains the OS/8 resident code for field 1. This starts some 2646 ; where around offset 47 in the first half of block zero, and this code needs 2647 ; to be loaded into the corresponding locations of page 7600, field 1. The 2648 ; remaining words in page 7600, field 1 (i.e. those that belong to the 2649 ; secondary bootstrap) OS/8 uses for tables and their initial values are 2650 ; unimportant. It suffices to simply copy all of the first half of block zero 2651 ; to page 7600, field 1. 2652 ; 2653 ; All this discussion presupposes a single page system handler, as we have 2654 ; here. For a two page handler BUILD will put the second page in the first 2655 ; half of block 66 on the system device and I believe (although I can't 2656 ; guarantee it) that the second half of this block also contains an image 2657 ; of the OS/8 resident code at page 7600, field 1. This would make it the 2658 ; same as, excepting the bootstrap part, the first half of block zero. In 2659 ; the case of a two page handler, the secondary bootstrap is also responsible 2660 ; for loading the second handler page from block 66 into page 7600, field 2. 2661 ; OS/8 bootstrap code (secondary bootstrap). 2662 ; 2663 ; Once everything has been loaded, the secondary bootstrap can simply do a 2664 ; "CDF CIF 0" and then jump to location 7600 to load the keyboard monitor. 2665 ; 2666 ; The primary bootstrap for the SBC6120 RAM and IDE disks are six words 2667 ; loaded in locations 0 thru 5: 2668 ; 2669 ; 0000/ 6206 PR0 / execute a panel request 2670 ; 0001/ 0001 1 / 1 for RAM disk, 4 for IDE disk 2671 ; 0002/ 0100 0100 / read one page into field zero 2672 ; 0003/ 0000 0000 / location zero 2673 ; 0004/ 0000 0000 / from page/block zero of the device 2674 ; 0005/ 7402 HLT / should never get here 2675 ; 2676 ; If all goes well, the HLT in location 5 is never executed - it gets 2677 ; overwritten by the secondary bootstrap code before the ROM returns from 2678 ; the PR0 function. 2679 ; 2680 ; The B (BOOT) command in BTS6120 actually bypasses the primary bootstrap 2681 ; step and simply reads block zero of the boot device into page zero, field 2682 ; zero directly. The VM01 and ID01 secondary bootstraps all contain a special 2683 ; "key" in words 0 thru 4, the ones which would normally overwrite the primary 2684 ; boostrap, and BTS6120 looks for this key to identify a bootable volume. 2685 ; If the key is found, then BTS6120 simply jumps to main memory location 5 2686 ; to start the secondary bootstrap and finish loading OS/8. 2687 ; 2688 ; This system should also work for any other, non OS/8, system provided that 2689 ; it uses the same primary bootstrap shown above and that its secondary boot 2690 ; contains the special key in the first five words. As long as the secondary 2691 ; bootstrap starts at offset 5, the remainder of its code is unimportant to 2692 ; BTS6120 and it can do anything it likes. PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 63 Boot Sniffer BTS6120.PLX 2693 .TITLE Boot Sniffer 2694 2695 2696 ; The secondary bootstraps for both VM01 and ID01 devices contain a special 2697 ; key, the ASCIZ string "BOOT", in the first five words. The caller is 2698 ; expected to read block zero of the boot device into memory, and then call 2699 ; this routine to examine page zero, field zero, of main memory to determine 2700 ; if a valid secondary bootstrap exists. If the key is found, then the LINK 2701 ; will be cleared on return... 2702 02400 1377 CKBOOT: TAD [BOOKEY-1] ; point X1 to the key string 2703 02401 3010 DCA X1 ; ... 2704 02402 7240 NL7777 ; and point X2 to page zero of main memory 2705 02403 3011 DCA X2 ; ... 2706 02404 7100 CKBOO1: CLL ; be sure the LINK is in a known state 2707 02405 1410 TAD @X1 ; get the next word of the key 2708 02406 7450 SNA ; have we done them all ? 2709 02407 6225 .POPJ ; yes - return success 2710 02410 7041 CIA ; make it negative 2711 02411 6266 CPD ; address main memory now 2712 02412 1411 TAD @X2 ; and compare our key to what's there 2713 02413 0103 AND ZK177 ; (PAL8 likes to set the high bit for ASCII!) 2714 02414 6276 SPD ; (back to panel memory) 2715 02415 7120 STL ; assume that we failed 2716 02416 7640 SZA CLA ; did the key match ? 2717 02417 6225 .POPJ ; nope - return with the LINK set 2718 02420 5204 JMP CKBOO1 ; yes - keep testing... 2719 2720 ; Ok, here it is - the magic key that makes a volume bootable! 2721 02421 BOOKEY: .ASCIZ /BOOT/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 64 B Command - Boot Disk BTS6120.PLX 2722 .TITLE B Command - Boot Disk 2723 2724 2725 ; The B command boots, or at least it tries to, either RAM or IDE disk. 2726 ; It can be used with an argument to specify the device to be booted, or 2727 ; without to ask BTS6120 to search for a bootable volume. For example: 2728 ; 2729 ; >B VM - boot device VMA0 2730 ; >B ID - boot device IDA0 2731 ; >B - search VMA0, then IDA0, for a bootstrap 2732 ; 2733 ; If no valid bootsrap can be found, then the message "?Not bootable" is 2734 ; printed. 2735 ; 2736 ; NOTE: It is currently only possible to bootstrap from unit zero for RAM 2737 ; disk, or partition zero in the case of IDE disk. 2738 02426 6205 BOOT: .PUSHJ @ZSPACMP ; get the next non-space character 02427 5463 2739 02430 7650 SNA CLA ; is it the end of the line ? 2740 02431 5252 JMP BOOT1 ; yes - go search for a bootstrap 2741 02432 6205 .PUSHJ @ZBACKUP ; nope - backup to the first letter 02433 5465 2742 02434 6205 .PUSHJ @[NAMENW] ; and read the boot device name 02435 5776 2743 02436 6205 .PUSHJ @ZEOLNXT ; now there has to be an EOL 02437 5467 2744 2745 ; Here if a specific device name is given on the command line... 2746 02440 1375 TAD [BNAMES-1] ; point to the table of boot names 2747 02441 6205 .PUSHJ @[MATCH] ; go call the right boot routine 02442 5774 2748 02443 7430 SZL ; did we find a bootstrap ? 2749 02444 5262 JMP NOBOOT ; nope - print an error message 2750 2751 ; Now do the equivalent of a "ST 5" to start the bootstrap running... 2752 02445 6205 BOOTGO: .PUSHJ @[CLRCPU] ; clear all saved main memory state 02446 5773 2753 02447 1372 TAD [5] ; the secondary bootstrap starts at offset 5 2754 02450 3000 DCA UPC ; ... 2755 02451 5771 JMP @[CONT] ; cross your fingers! 2756 2757 ; Here to search for a bootable device... 2758 02452 6205 BOOT1: .PUSHJ BTVMA0 ; first try booting VMA0 02453 5264 2759 02454 7420 SNL ; did we succeed? 2760 02455 5245 JMP BOOTGO ; yes - go start the bootstrap 2761 02456 6205 .PUSHJ BTIDA0 ; nope - try IDA0 next 02457 5300 2762 02460 7420 SNL ; how about this? 2763 02461 5245 JMP BOOTGO ; yes - use that on instead 2764 2765 ; Here if no bootstrap can be found... 2766 02462 4501 NOBOOT: JMS @ZERROR ; print an error and return to command level 2767 02463 3674 ERRNBT ; ?NO BOOTSTRAP 2768 2769 2770 ; Here to attempt booting VMA0... 2771 02464 4502 BTVMA0: JMS @ZPUSHJ1 ; (cross field call) 2772 02465 0334 RDBOOT ; RAM disk primary bootstrap 2773 02466 6205 .PUSHJ CKBOOT ; is this volume bootable? 02467 5200 2774 02470 7430 SZL ; skip if yes 2775 02471 6225 .POPJ ; not bootable - just give up 2776 02472 4462 JMS @ZINLMES ; say 2777 02473 4253 VMAMSG ; "-VMA0" PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 65 B Command - Boot Disk BTS6120.PLX 2778 02474 6205 .PUSHJ @ZCRLF ; ... 02475 5461 2779 02476 7100 CLL ; be sure to return success 2780 02477 6225 .POPJ ; ... 2781 2782 2783 ; Here to attempt booting IDA0... 2784 02500 4502 BTIDA0: JMS @ZPUSHJ1 ; (cross field call) 2785 02501 1126 IDBOOT ; IDE disk primary bootstrap 2786 02502 6205 .PUSHJ CKBOOT ; is this volume bootable? 02503 5200 2787 02504 7430 SZL ; skip if yes 2788 02505 6225 .POPJ ; not bootable - just give up 2789 02506 4462 JMS @ZINLMES ; say 2790 02507 4260 IDAMSG ; "-IDA0" 2791 02510 6205 .PUSHJ @ZCRLF ; ... 02511 5461 2792 02512 7100 CLL ; and be sure to return success 2793 02513 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 66 Parse FORMAT Unit/Partition Argument BTS6120.PLX 2794 .TITLE Parse FORMAT Unit/Partition Argument 2795 2796 2797 ; This routine will parse the unit/partition number argument for FORMAT. 2798 ; Since this command is little on the dangerous side (it does erase all the 2799 ; data on the disk, after all!), we'll go to the extraordinary length of 2800 ; asking for confirmation before we do anything. Confirmation is nothing 2801 ; more than a single character (we don't wait for a carriage return) - "Y" 2802 ; continues with the format and anything else, including ^C, aborts... 2803 ; 2804 ; Assuming the user confirms, then the unit/partition number will be 2805 ; returned in the AC. If the user aborts, or if there are any syntax 2806 ; errors, then we restart the command scanner and never return. 2807 02514 6205 FMTARG: .PUSHJ @ZOCTNW ; read the unit/partition number 02515 5471 2808 02516 6205 .PUSHJ @ZEOLTST ; that has to be followed by the end of line 02517 5466 2809 02520 4462 JMS @ZINLMES ; say 2810 02521 4111 FCFMSG ; "Format partition/unit " 2811 02522 1045 TAD WORD ; get the partition number once again 2812 02523 3027 DCA VALUE ; TOCT corrupts WORD, 2813 02524 1027 TAD VALUE ; .... so we have to stash it here 2814 02525 6205 .PUSHJ @ZTOCT4S ; and type it out 02526 5460 2815 02527 6205 .PUSHJ @[CONFRM] ; go wait for a "Y" or "y" 02530 5770 2816 02531 7620 SNL CLA ; did he confirm? 2817 02532 5477 JMP @ZRESTA ; no - just abort now 2818 02533 1027 TAD VALUE ; yes he did - return the unit in the AC 2819 02534 6225 .POPJ ; ... 2820 2821 ; Here if the RAM disk unit number is illegal... 2822 02535 4501 NOUNIT: JMS @ZERROR ; ... 2823 02536 3576 ERRILV ; "?Illegal value" 2824 2825 ; This little routine verifies that a hard disk is attached to the system. 2826 ; If there is none, then an error message is printed and the command aborted. 2827 02537 6211 NODISK: CDF 1 ; there's a disk attached 2828 02540 1767 TAD @[DKSIZE] ; ... only if DKSIZE != 0 2829 02541 6201 CDF 0 ; ... 2830 02542 7640 SZA CLA ; skip if there's no disk there 2831 02543 6225 .POPJ ; yes - return now 2832 02544 4501 JMS @ZERROR ; print a message and abort the command 2833 02545 3705 ERRNDK ; "?No disk" 2834 02567 0040 02570 7025 02571 2216 02572 0005 02573 2304 02574 6642 02575 3541 02576 6600 02577 2420 2835 02600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 67 PM Command - Show and Edit Disk Partition Map BTS6120.PLX 2836 .TITLE PM Command - Show and Edit Disk Partition Map 2837 2838 2839 ; The PM command allows the default mapping of OS/8 units to IDE disk 2840 ; partitions to be changed. PM accepts two arguments, both of which are 2841 ; optional. The first argument is the OS/8 logical unit number, and the 2842 ; second argument a partition number, in octal. Used without any arguments, 2843 ; the PM command will display a list of all eight OS/8 units and their current 2844 ; mappings. With one argument, PM will display only the mapping for that 2845 ; unit, and with two arguments PM will change the mapping of that unit. 2846 ; 2847 ; >PM u pppp - map OS/8 ID01 unit u to IDE partition pppp 2848 ; >PM u - display the mapping for unit u 2849 ; >PM - display the mapping for all units 2850 ; 2851 02600 6205 PMEDIT: .PUSHJ @ZSPACMP ; get the next non-space character 02601 5463 2852 02602 7650 SNA CLA ; is it the end of the line ? 2853 02603 5242 JMP PMALL ; yes - show the entire map 2854 02604 6205 .PUSHJ @ZBACKUP ; nope - backup and read this character 02605 5465 2855 02606 6205 .PUSHJ @ZOCTNW ; it should be a unit number 02607 5471 2856 02610 1045 TAD WORD ; get the value we read 2857 02611 0377 AND [7770] ; and the unit number must be less than 7 2858 02612 7640 SZA CLA ; ?? 2859 02613 5240 JMP PMEDI1 ; nope - "Illegal value" 2860 02614 1045 TAD WORD ; transfer the unit number 2861 02615 3047 DCA COUNT ; to COUNT for later use 2862 2863 ; See if there's also a partition number on the line... 2864 02616 6205 .PUSHJ @ZSPACM0 ; get the next non-space character 02617 5464 2865 02620 7650 SNA CLA ; is it the end of the line? 2866 02621 5253 JMP PMSHOW ; yes - print the mapping for this unit only 2867 02622 6205 .PUSHJ @ZBACKUP ; nope - read what comes next 02623 5465 2868 02624 6205 .PUSHJ @ZOCTNW ; this should be the partition number 02625 5471 2869 02626 6205 .PUSHJ @ZEOLTST ; and then we have to be at the EOL 02627 5466 2870 2871 ; Here to change the mapping for a specific unit... 2872 02630 1047 TAD COUNT ; get the unit number 2873 02631 1376 TAD [PARMAP-1] ; and make an index into the mapping table 2874 02632 3010 DCA X1 ; ... 2875 02633 6211 CDF 1 ; PARMAP lives in field one 2876 02634 1045 TAD WORD ; get the desired mapping 2877 02635 3410 DCA @X1 ; and update the partition table 2878 02636 6201 CDF 0 ; back to this field 2879 02637 6225 .POPJ ; and we're all done 2880 2881 ; Here if the unit number is illegal... 2882 02640 4501 PMEDI1: JMS @ZERROR ; say 2883 02641 3576 ERRILV ; "?Illegal value" and abort 2884 2885 2886 ; Here to show all eight entries in the entire partition map... 2887 02642 3047 PMALL: DCA COUNT ; start with unit zero 2888 02643 6205 .PUSHJ PMSHOW ; and show the mapping for that unit 02644 5253 2889 02645 2047 ISZ COUNT ; now onto the next one 2890 02646 1047 TAD COUNT ; have we done eight ? 2891 02647 1377 TAD [-10] ; ??? 2892 02650 7640 SZA CLA ; well ? PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 68 PM Command - Show and Edit Disk Partition Map BTS6120.PLX 2893 02651 5243 JMP PMALL+1 ; nope - keep going 2894 02652 6225 .POPJ ; yes, we can quit now 2895 2896 ; Here to show the mapping for the unit in COUNT... 2897 02653 4462 PMSHOW: JMS @ZINLMES ; say 2898 02654 4233 PM1MSG ; "Unit " 2899 02655 1047 TAD COUNT ; get the selected unit 2900 02656 6205 .PUSHJ @[TDIGIT] ; and type it 02657 5775 2901 02660 4462 JMS @ZINLMES ; now say 2902 02661 4240 PM2MSG ; " mapped to partition " 2903 02662 1047 TAD COUNT ; get the count again 2904 02663 1376 TAD [PARMAP-1] ; and index the partition table 2905 02664 3010 DCA X1 ; ... 2906 02665 6211 CDF 1 ; the partition table lives in field 1 2907 02666 1410 TAD @X1 ; get the partition mapped to this unit 2908 02667 6201 CDF 0 ; ... 2909 02670 5457 JMP @ZTOCT4C ; type it, in octal, and a CRLF PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 69 Disk Formatter, Pass 1 BTS6120.PLX 2910 .TITLE Disk Formatter, Pass 1 2911 2912 2913 ; Pass one of the RAM/IDE disk formatter writes every block with a simple 2914 ; test pattern consisting of alternating words filled with the block number 2915 ; and its complement. Although it's not too creative, this pattern does do 2916 ; two things - it guarantees that each block is unique (so we can make sure 2917 ; the disk addresssing is working!) and it does ensure that every bit gets 2918 ; tested with a zero and a one (so we can make sure the data lines are 2919 ; working). 2920 ; 2921 ; This routine expects that a number of memory locations will be initialized 2922 ; before it's called. RECSIZ must contain the negative of the logical record 2923 ; size for the device (-256 for IDE disk or -128 for RAM disk). FMTCNT should 2924 ; contain the negative of the device size, in blocks/pages, and FMTWRP (a 2925 ; location in this routine!) must be initialized with the address of the 2926 ; disk write routine... 2927 02671 4462 FMTP1: JMS @ZINLMES ; say 2928 02672 4131 FM1MSG ; ... "Writing " 2929 02673 6211 CDF 1 ; ... 2930 02674 3512 DCA @ZDKRBN ; reset the current disk block 2931 02675 3511 DCA @ZRDPAGE ; and page numbers 2932 2933 ; Fill the disk buffer with the test pattern... 2934 02676 1051 FMTP11: TAD RECSIZ ; get the negative of the record size 2935 02677 7130 CLL CML RAR ; and divide it by two 2936 02700 3047 DCA COUNT ; since we'll fill the buffer in word pairs 2937 02701 1374 TAD [DSKBUF-1] ; point X1 to the disk buffer 2938 02702 3010 DCA X1 ; ... 2939 02703 6211 CDF 1 ; (the disk buffer is in field 1) 2940 02704 1053 FMTP12: TAD FMTCNT ; get the current block/page number 2941 02705 3410 DCA @X1 ; store that 2942 02706 1053 TAD FMTCNT ; then store its complement 2943 02707 7040 CMA ; ... 2944 02710 3410 DCA @X1 ; in the next word 2945 02711 2047 ISZ COUNT ; have we done the whole buffer? 2946 02712 5304 JMP FMTP12 ; nope - keep filling 2947 02713 6201 CDF 0 ; return to our default field 2948 2949 ; Write the buffer to the disk... 2950 02714 4502 JMS @ZPUSHJ1 ; (cross field call) 2951 02715 2024 PNLBUF ; setup our temporary buffer in field 1 2952 02716 1051 TAD RECSIZ ; pass the record size to the I/O routine 2953 02717 4502 JMS @ZPUSHJ1 ; (cross field call) 2954 02720 FMTWRP: .BLOCK 1 ; modified to either DISKWR or RAMDWR 2955 02721 7430 SZL ; were there any errors ? 2956 02722 5773 JMP @[DIOERR] ; yes - quit now 2957 2958 ; See if we've done the whole disk... 2959 02723 7200 CLA ; ... 2960 02724 2053 ISZ FMTCNT ; increment the page/block counter 2961 02725 7410 SKP ; not done yet - keep going 2962 02726 6225 .POPJ ; all done! 2963 02727 6211 CDF 1 ; disk data lives in field 1 2964 02730 2512 ISZ @ZDKRBN ; increment the disk block number 2965 02731 2511 ISZ @ZRDPAGE ; and the RAM disk page number 2966 02732 6201 CDF 0 ; back to safe ground 2967 2968 ; Print a dot every so often to make a simple "progress bar"... 2969 02733 1051 TAD RECSIZ ; get the current record size 2970 02734 7040 CMA ; and make it a mask for the lower bits 2971 02735 0053 AND FMTCNT ; apply it to the current block/page number 2972 02736 7640 SZA CLA ; ... 2973 02737 5276 JMP FMTP11 ; not time for a dot yet 2974 02740 6205 .PUSHJ @[TDOT] ; print a dot to show our progress PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 70 Disk Formatter, Pass 1 BTS6120.PLX 02741 5772 2975 02742 5276 JMP FMTP11 ; and another page or block 2976 02772 7077 02773 3504 02774 7377 02775 7102 02776 0041 02777 7770 2977 03000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 71 Disk Formatter, Pass 2 BTS6120.PLX 2978 .TITLE Disk Formatter, Pass 2 2979 2980 2981 ; Pass two of the RAM/IDE disk formatter reads back every block and verifies 2982 ; that the test pattern written by pass 1 is there. If any block doesn't 2983 ; contain the data we expect, then a "Verification error" message will be 2984 ; printed, but verification continues. This routine expects all the same 2985 ; data to be set up in FMTCNT and RECSIZ as Pass 1, and in addition it 2986 ; expects FMTRDP to be initialized with the address of the disk read routine. 2987 03000 4462 FMTP2: JMS @ZINLMES ; say 2988 03001 4140 FM2MSG ; "Verifying" 2989 03002 6211 CDF 1 ; ... 2990 03003 3512 DCA @ZDKRBN ; reset the current disk block 2991 03004 3511 DCA @ZRDPAGE ; and page numbers 2992 03005 6201 CDF 0 ; ... 2993 2994 ; Read the next block/page from the disk... 2995 03006 4502 FMTP21: JMS @ZPUSHJ1 ; (cross field call) 2996 03007 2024 PNLBUF ; setup a temporary disk buffer in panel memory 2997 03010 1051 TAD RECSIZ ; pass the record size to DISKRD 2998 03011 4502 JMS @ZPUSHJ1 ; (cross field call) 2999 03012 FMTRDP: .BLOCK 1 ; gets modified to either DISKRD or RAMDRD! 3000 03013 7430 SZL ; any I/O errors ? 3001 03014 5777 JMP @[DIOERR] ; yes - just give up now 3002 3003 ; Verify that the data in the buffer matches what we wrote... 3004 03015 1051 TAD RECSIZ ; and get the block/page size 3005 03016 7130 CLL CML RAR ; divide it by two 3006 03017 3047 DCA COUNT ; because we'll test in double word pairs 3007 03020 1376 TAD [DSKBUF-1] ; point X1 to the disk buffer 3008 03021 3010 DCA X1 ; ... 3009 03022 6211 CDF 1 ; (disk buffer lives in field 1) 3010 03023 1053 FMTP22: TAD FMTCNT ; get the current block/page number 3011 03024 7041 CIA ; make it negative 3012 03025 1410 TAD @X1 ; and compare to the first word in the buffer 3013 03026 7640 SZA CLA ; it matches, no? 3014 03027 5257 JMP FMTP29 ; no - verify error! 3015 03030 1410 TAD @X1 ; the second word is the complement of the page 3016 03031 1053 TAD FMTCNT ; so that plus this 3017 03032 7001 IAC ; plus 1 should be zero! 3018 03033 7640 SZA CLA ; are we right? 3019 03034 5257 JMP FMTP29 ; no - verify error! 3020 03035 2047 ISZ COUNT ; have we done the whole buffer? 3021 03036 5223 JMP FMTP22 ; nope - keep testing 3022 03037 6201 CDF 0 ; return to our regular field 3023 3024 ; See if we've done the whole disk... 3025 03040 2053 FMTP23: ISZ FMTCNT ; increment the page/block counter 3026 03041 7410 SKP ; not done yet - keep going 3027 03042 6225 .POPJ ; all done! 3028 03043 6211 CDF 1 ; disk data lives in field 1 3029 03044 2512 ISZ @ZDKRBN ; increment the disk block number 3030 03045 2511 ISZ @ZRDPAGE ; and the RAM disk page number 3031 03046 6201 CDF 0 ; back to safe ground 3032 3033 ; Print a dot every so often to make a simple "progress bar"... 3034 03047 1051 TAD RECSIZ ; get the current record size 3035 03050 7040 CMA ; and make it a mask for the lower bits 3036 03051 0053 AND FMTCNT ; apply it to the current block/page number 3037 03052 7640 SZA CLA ; ... 3038 03053 5206 JMP FMTP21 ; not time for a dot yet 3039 03054 6205 .PUSHJ @[TDOT] ; print a dot to show our progress 03055 5775 3040 03056 5206 JMP FMTP21 ; and another page or block 3041 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 72 Disk Formatter, Pass 2 BTS6120.PLX 3042 ; Here if one (or more) words don't match.. 3043 03057 6201 FMTP29: CDF 0 ; restore the usual field 3044 03060 6205 .PUSHJ @ZCRLF ; we're in the middle of a line now 03061 5461 3045 03062 4462 JMS @ZINLMES ; so start a new one and print 3046 03063 4156 ERRDSK ; "?Verification error, block/page " 3047 03064 6211 CDF 1 ; (disk data is in field 1) 3048 03065 1512 TAD @ZDKRBN ; get the current block/page number 3049 03066 6201 CDF 0 ; ... 3050 03067 6205 .PUSHJ @ZTOCT4C ; and type it (in octal) 03070 5457 3051 03071 5240 JMP FMTP23 ; better luck with the next block PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 73 DF Command - Format IDE Disk Partition BTS6120.PLX 3052 .TITLE DF Command - Format IDE Disk Partition 3053 3054 3055 ; The DF command will "format" an IDE disk partition. The name is a misnomer 3056 ; because there's nothing about an IDE disk that needs formatting in the way 3057 ; a floppy does, but this command does write and then read back every single 3058 ; block of the partition which serves the useful function of testing the disk. 3059 ; It works in two passes - the first pass writes every block with a test 3060 ; pattern, and the second pass reads and verifies every block for the correct 3061 ; data. 3062 ; 3063 ; >DF pppp - format disk partition pppp 3064 ; 3065 03072 6205 DFRMAT: .PUSHJ @[NODISK] ; verify that a hard disk is attached 03073 5774 3066 03074 6205 .PUSHJ @[FMTARG] ; get the partition and ask for confirmation 03075 5773 3067 03076 6211 CDF 1 ; the IDE disk data lives in field one 3068 03077 3772 DCA @[DKPART] ; save the partition number 3069 03100 6201 CDF 0 ; ... 3070 03101 1110 TAD ZM256 ; the record size for IDE disk is 256 words 3071 03102 3051 DCA RECSIZ ; ... 3072 3073 ; Do pass 1... 3074 03103 3053 DCA FMTCNT ; an IDE partition always holds 4096 blocks 3075 03104 1371 TAD [DISKWR] ; point to the correct I/O routine 3076 03105 3770 DCA @[FMTWRP] ; and point pass 1 towards that 3077 03106 6205 .PUSHJ @[FMTP1] ; go do pass 1 03107 5767 3078 3079 ; And do pass 2... 3080 03110 3053 DCA FMTCNT ; reset the block count to 4096 3081 03111 1366 TAD [DISKRD] ; and point pass 2 to the disk read routine 3082 03112 3212 DCA FMTRDP ; ... 3083 03113 6205 .PUSHJ FMTP2 ; and away we go! 03114 5200 3084 3085 ; We've tested the entire disk... 3086 03115 4462 FRDONE: JMS @ZINLMES ; let the operator know we're done 3087 03116 4151 FM3MSG ; "Finished" 3088 03117 5461 JMP @ZCRLF ; finish the line and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 74 RF Command - Format a RAM Disk BTS6120.PLX 3089 .TITLE RF Command - Format a RAM Disk 3090 3091 3092 ; The RF command will "format" a RAM disk virtual drive and it's essentially 3093 ; identical to the DF command that formats IDE disks. 3094 ; 3095 ; >RF u - format RAM disk unit u 3096 ; 3097 03120 6205 RFRMAT: .PUSHJ @[FMTARG] ; get the unit and ask for confirmation 03121 5773 3098 03122 6211 CDF 1 ; the RAM disk data lives in field one 3099 03123 3765 DCA @[RDUNIT] ; save the unit 3100 03124 6201 CDF 0 ; ... 3101 03125 4502 JMS @ZPUSHJ1 ; (cross field call) 3102 03126 0635 RAMSEL ; try to select this RAM disk unit 3103 03127 7630 SZL CLA ; was the unit number legal ?? 3104 03130 5764 JMP @[NOUNIT] ; nope - quit while we're ahead! 3105 03131 1107 TAD ZM128 ; the record size for RAM disk is 128 words 3106 03132 3051 DCA RECSIZ ; ... 3107 3108 ; Do pass 1... 3109 03133 6211 CDF 1 ; get the size of this RAM disk unit 3110 03134 1763 TAD @[RAMUSZ] ; which is left here by RAMSEL 3111 03135 3053 DCA FMTCNT ; save it for pass 1 3112 03136 6201 CDF 0 ; ... 3113 03137 1362 TAD [RAMDWR] ; get the correct I/O routine 3114 03140 3770 DCA @[FMTWRP] ; and point pass 1 towards that 3115 03141 6205 .PUSHJ @[FMTP1] ; go do pass 1 03142 5767 3116 3117 ; And do pass 2... 3118 03143 6211 CDF 1 ; get the size of this RAM disk unit 3119 03144 1763 TAD @[RAMUSZ] ; which is left here by RAMSEL 3120 03145 3053 DCA FMTCNT ; save it for pass1 3121 03146 6201 CDF 0 ; ... 3122 03147 1361 TAD [RAMDRD] ; and point pass 2 to the disk read routine 3123 03150 3212 DCA FMTRDP ; ... 3124 03151 6205 .PUSHJ FMTP2 ; and away we go! 03152 5200 3125 3126 ; We've tested the entire disk... 3127 03153 5315 JMP FRDONE ; say "Finished" and we're done! 3128 03161 0400 03162 0411 03163 0035 03164 2535 03165 0020 03166 1200 03167 2671 03170 2720 03171 1220 03172 0036 03173 2514 03174 2537 03175 7077 03176 7377 03177 3504 3129 03200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 75 LP Command - Load Binary Paper Tapes from the Console BTS6120.PLX 3130 .TITLE LP Command - Load Binary Paper Tapes from the Console 3131 3132 3133 ; The LP command loads a "paper tape" in standard PDP-8 BIN loader format 3134 ; from the console. If the console is actually an ASR-33 and you actually 3135 ; have a real PDP-8 paper tape, then this will probably even work, but a more 3136 ; likely situation is that you're using a PC with a terminal emulator. In 3137 ; that case the paper tape image can be downloaded from the PC's disk. 3138 ; 3139 ; The loader accepts all standard BIN data frames, including field changes, 3140 ; and correctly calculates and verifies the tape checksum. If the checksum 3141 ; matches then the number of words loaded is printed - otherwise a checksum 3142 ; error message is generated. When initially started, this routine ignores 3143 ; all input until two consectutive leader codes (octal 200) are found - this 3144 ; allows us to ignore any extra ASCII characters from the terminal emulator 3145 ; (such as carriage returns, spaces, etc). 3146 ; 3147 ; Since we're using the real console, the same one that you're typing 3148 ; commands on, for input we have a problem in that we need some way to 3149 ; terminate loading. Control-C won't work since the BIN loader eats all 3150 ; eight bit characters. A hardware reset isn't a good idea, since the POST 3151 ; memory test will erase everything we've loaded. Instead we use a special 3152 ; routine, CONGET, to read characters from the console and this routine has a 3153 ; timeout built in. If we go approximately 5 seconds without any input then 3154 ; the loader is terminated. 3155 03200 6205 CONLOD: .PUSHJ @ZEOLNXT ; this command has no operands 03201 5467 3156 03202 3022 DCA PNLMEM ; files are always lodaded into main memory 3157 3158 ; Look for two consecutive bytes of leader code... 3159 03203 1377 BINLO1: TAD [-2] ; we need two bytes of leader/trailer 3160 03204 3047 DCA COUNT ; ... 3161 03205 6205 BINLO2: .PUSHJ CONGET ; go read a byte of input 03206 5325 3162 03207 1376 TAD [-200] ; is this a leader code ?? 3163 03210 7640 SZA CLA ; ?? 3164 03211 5203 JMP BINLO1 ; no -- keep looking for two 3165 03212 2047 ISZ COUNT ; yes -- is this the second in a row ?? 3166 03213 5205 JMP BINLO2 ; no -- go look for the next one 3167 3168 ; Here after we have 2 bytes of leader -- look for the end of the leader... 3169 03214 6205 BINLO3: .PUSHJ CONGET ; get another byte of data 03215 5325 3170 03216 1376 TAD [-200] ; are we still in the leader ?? 3171 03217 7450 SNA ; ??? 3172 03220 5214 JMP BINLO3 ; yes -- keep looking 3173 03221 1375 TAD [200] ; no -- restore the character 3174 03222 3045 DCA WORD ; and remember it for later 3175 3176 ; Now actually start loading data... 3177 03223 3031 DCA CHKSUM ; start with a zero checksum 3178 03224 1375 TAD [200] ; set the default load address to location 200 3179 03225 3020 DCA ADDR ; ... 3180 03226 3021 DCA ADRFLD ; in field zero 3181 3182 ; Decode the type of the next load record... 3183 03227 7621 BINLO5: CAM ; ... 3184 03230 1045 TAD WORD ; Get the last character we read 3185 03231 0375 AND [200] ; Is this a single byte frame ??? 3186 03232 7640 SZA CLA ; ?? 3187 03233 5301 JMP BINLO7 ; Yes -- this is EOF or a field setting 3188 3189 ; Load a two frame record (either data or an address)... 3190 03234 1045 TAD WORD ; get the first byte back again 3191 03235 3323 DCA BINCH1 ; and remember that PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 76 LP Command - Load Binary Paper Tapes from the Console BTS6120.PLX 3192 03236 6205 .PUSHJ CONGET ; then go read the next byte 03237 5325 3193 03240 3324 DCA BINCH2 ; and save that 3194 03241 1323 TAD BINCH1 ; get the first byte 3195 03242 0374 AND [77] ; trim it to just 6 bits 3196 03243 7002 BSW ; put it in the left half 3197 03244 7421 MQL ; and save it in the MQ for now 3198 03245 1324 TAD BINCH2 ; then get the second character 3199 03246 0374 AND [77] ; trim it to 6 bits too 3200 03247 7501 MQA ; and OR it with the first character 3201 03250 3027 DCA VALUE ; remember what we read 3202 3203 ; Determine what to do with this word... 3204 03251 6205 .PUSHJ CONGET ; look ahead one byte 03252 5325 3205 03253 3045 DCA WORD ; save that character 3206 03254 1045 TAD WORD ; and get it back 3207 03255 1376 TAD [-200] ; is this the end of the tape ?? 3208 03256 7650 SNA CLA ; ?? 3209 03257 5314 JMP BINLO8 ; yes -- we read a checksum word 3210 03260 1031 TAD CHKSUM ; no -- checksum the two characters we read 3211 03261 1323 TAD BINCH1 ; ... 3212 03262 1324 TAD BINCH2 ; ... 3213 03263 3031 DCA CHKSUM ; ... 3214 03264 1323 TAD BINCH1 ; then look at the first character 3215 03265 0373 AND [100] ; is this an address or data frame ?? 3216 03266 7640 SZA CLA ; skip if it's data 3217 03267 5276 JMP BINLO6 ; no -- it is an address 3218 3219 ; Load this word of data into memory... 3220 03270 1027 TAD VALUE ; get the word back 3221 03271 6205 .PUSHJ @ZDANDV ; and write it into memory 03272 5476 3222 03273 2020 ISZ ADDR ; automatically advance the address 3223 03274 7000 NOP ; (and ignore any wrap around) 3224 03275 5227 JMP BINLO5 ; then go process the next frame 3225 3226 ; This word is an address... 3227 03276 1027 BINLO6: TAD VALUE ; get the 12 bits of data 3228 03277 3020 DCA ADDR ; and change to that address 3229 03300 5227 JMP BINLO5 ; then go process the next frame 3230 3231 ; Here of the current frame is a field setting... 3232 03301 1045 BINLO7: TAD WORD ; get the last character back again 3233 03302 0373 AND [100] ; see if it is really a field frame 3234 03303 7650 SNA CLA ; ??? 3235 03304 5314 JMP BINLO8 ; no -- treat it like a trailer code 3236 03305 1045 TAD WORD ; get the field back 3237 03306 0104 AND ZK70 ; we only want these bits 3238 03307 3021 DCA ADRFLD ; and change to the selected field 3239 03310 6205 .PUSHJ CONGET ; Then look ahead one byte 03311 5325 3240 03312 3045 DCA WORD ; ... 3241 03313 5227 JMP BINLO5 ; and go process that frame 3242 3243 ; Here when we find the checksum byte... 3244 03314 1027 BINLO8: TAD VALUE ; get the checksum byte 3245 03315 7041 CIA ; make it negative 3246 03316 1031 TAD CHKSUM ; and add it to our checksum 3247 03317 3031 DCA CHKSUM ; this should leave zero 3248 03320 6205 .PUSHJ @[TCKSUM] ; go type the checksum and return 03321 5772 3249 03322 5203 JMP BINLO1 3250 3251 ; Temporary storage for BIN loader routine... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 77 LP Command - Load Binary Paper Tapes from the Console BTS6120.PLX 3252 03323 BINCH1: .BLOCK 1 ; the first of a two character frame 3253 03324 BINCH2: .BLOCK 1 ; the second of a two character frame PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 78 Paper Tape Console Input Routine BTS6120.PLX 3254 .TITLE Paper Tape Console Input Routine 3255 3256 3257 ; This routine will read a character from the console, waiting if there is 3258 ; none ready right now, and with a timeout if one doesn't arrive soon. It is 3259 ; intended to be used only with the paper tape binary loader routine, and most 3260 ; "textual" input should be done via the INCHRS or INCHWL routines. Since the 3261 ; user cannot type control-C to abort the paper tape loader (data is being read 3262 ; from the console, remember ?) this routine provides a timeout feature to 3263 ; prevent the monitor from becoming 'hung'. If no character is received from 3264 ; the console in approximately 10 seconds, a control-C is simulated by jumping 3265 ; to RESTA. 3266 0310 FTCONT=200. ; approximately 10 seconds with a 4.9152Mhz clock 3267 3268 03325 7200 CONGET: CLA ; ... 3269 03326 1371 TAD [-FTCONT] ; get the console timeout time 3270 03327 3042 DCA IRMA ; and set up a counter 3271 3272 ; Try to read a character... 3273 03330 6031 CONGE1: KSF ; is there a character there ??? 3274 03331 5335 JMP CONGE2 ; no -- check the timer 3275 03332 7200 CLA ; yes -- clear the timer 3276 03333 6036 KRB ; and get the character 3277 03334 6225 .POPJ ; then return that 3278 3279 ; Here to keep the timeout counter. The loop between CONGE1 and CONGE2 3280 ; requires 56 states, or approximately .1835 seconds at 2.5Mhz. This is 3281 ; executed FTCONT times for the overall timeout. 3282 03335 7001 CONGE2: IAC ; increment the timer 3283 03336 7440 SZA ; has it counted to 4096 ??? 3284 03337 5330 JMP CONGE1 ; no -- keep waiting 3285 03340 2042 ISZ IRMA ; yes -- have we waited long enough ?? 3286 03341 5330 JMP CONGE1 ; no -- wait a little longer 3287 03342 7325 NL0003 ; yes -- simulate a control-C 3288 03343 6205 .PUSHJ @ZOUTCHR ; echo ^C 03344 5454 3289 03345 5477 JMP @ZRESTA ; and restart 3290 03371 7470 03372 1472 03373 0100 03374 0077 03375 0200 03376 7600 03377 7776 3291 03400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 79 RD and DD Commands - Dump Disk (RAM and IDE) Records BTS6120.PLX 3292 .TITLE RD and DD Commands - Dump Disk (RAM and IDE) Records 3293 3294 3295 ; These commands dump one or more disk records, in octal, to the console. 3296 ; What you get from DP is exactly how the OS/8 device driver sees the disk 3297 ; data. Each command accepts one, two or three parameters. The first is unit 3298 ; number for RAM Disk (RD) commands, or the partition number for IDE Disk (DD) 3299 ; commands. The second parameter is the number of the block to be dumped, in 3300 ; octal. If this number is omitted then the ENTIRE disk will be dumped which, 3301 ; although legal, will take quite a while! The third parameter is the count 3302 ; of pages (for RAM Disk) or blocks (for IDE disk) to be dumped and, if 3303 ; omitted, this defaults to 1. For example: 3304 ; 3305 ; >RD 0 0 - dump only page 0 (the boot block) of RAM disk unit 0 3306 ; >DD 2 100 - dump only page 100 (octal) of IDE partition 2 3307 ; >RD 1 100 77 - dump 64 (77 octal) pages of unit 1 from 100 to 177 3308 ; >DD 0 - dump ALL of IDE partition zero (4095 blocks!) 3309 ; 3310 3311 ; Enter here for the RD command... 3312 03400 1377 RDDUMP: TAD [RAMDRD] ; point to the RAM disk read routine 3313 03401 3267 DCA RDPTR ; modify the code to use that 3314 03402 1107 TAD ZM128 ; get the record size for RAM disk 3315 03403 3051 DCA RECSIZ ; and save that 3316 03404 5213 JMP PARSDX ; fall into the regular code now 3317 3318 ; And here for the DD command... 3319 03405 6205 DDDUMP: .PUSHJ @[NODISK] ; verify that a hard disk exists 03406 5776 3320 03407 1375 TAD [DISKRD] ; point to the IDE disk read routine 3321 03410 3267 DCA RDPTR ; and use that instead 3322 03411 1110 TAD ZM256 ; IDE disk uses 256 word records 3323 03412 3051 DCA RECSIZ ; ... 3324 3325 ; Parse the argument lists for either command... 3326 03413 6205 PARSDX: .PUSHJ @ZOCTNW ; read the unit/partition number (required) 03414 5471 3327 03415 6211 CDF 1 ; all disk data lives in field 1 3328 03416 1045 TAD WORD ; get what we found 3329 03417 3774 DCA @[DKPART] ; save both the partition number 3330 03420 1045 TAD WORD ; ... 3331 03421 3773 DCA @[RDUNIT] ; and the unit number 3332 03422 3512 DCA @ZDKRBN ; set the default starting block/page to zero 3333 03423 3511 DCA @ZRDPAGE ; ... 3334 03424 6201 CDF 0 ; back to the current field 3335 03425 3052 DCA RECCNT ; make the default record count the whole disk 3336 3337 ; See if there's a starting page number on the command line... 3338 03426 6205 .PUSHJ @ZSPACM0 ; are there any more characters in the command? 03427 5464 3339 03430 7650 SNA CLA ; skip if there are 3340 03431 5263 JMP DDUMP1 ; nope - start dumping now 3341 03432 6205 .PUSHJ @ZBACKUP ; yes - re-read the character 03433 5465 3342 03434 6205 .PUSHJ @ZOCTNW ; and read the page/block number 03435 5471 3343 03436 6211 CDF 1 ; back to field 1 3344 03437 1045 TAD WORD ; get the starting block/page number 3345 03440 3512 DCA @ZDKRBN ; and save it for both RAM disk and IDE disk 3346 03441 1045 TAD WORD ; ... 3347 03442 3511 DCA @ZRDPAGE ; ... 3348 03443 6201 CDF 0 ; back to our field 3349 03444 7240 NLM1 ; now the default record count is one 3350 03445 3052 DCA RECCNT ; ... 3351 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 80 RD and DD Commands - Dump Disk (RAM and IDE) Records BTS6120.PLX 3352 ; See if there's a page/block count too.. 3353 03446 6205 .PUSHJ @ZSPACM0 ; still more characters? 03447 5464 3354 03450 7650 SNA CLA ; skip if there are 3355 03451 5263 JMP DDUMP1 ; nope - start dumping now 3356 03452 6205 .PUSHJ @ZBACKUP ; yes - re-read the character 03453 5465 3357 03454 6205 .PUSHJ @ZOCTNW ; and read the page count 03455 5471 3358 03456 1045 TAD WORD ; ... 3359 03457 7041 CIA ; make it negative for ISZ 3360 03460 3052 DCA RECCNT ; and save the count 3361 03461 6205 .PUSHJ @ZEOLTST ; finally, this has to be the end of the line 03462 5466 3362 3363 ; Read a page from the disk into the panel memory buffer and dump it... 3364 03463 4502 DDUMP1: JMS @ZPUSHJ1 ; (call field 1 routine) 3365 03464 2024 PNLBUF ; set the disk buffer to DSKBUF 3366 03465 1051 TAD RECSIZ ; pass the record size to the I/O routine 3367 03466 4502 JMS @ZPUSHJ1 ; (cross field call) 3368 03467 RDPTR: .BLOCK 1 ; gets overwritten with DISKRD or RAMDRD! 3369 03470 7430 SZL ; were there any errors detected ? 3370 03471 5304 JMP DIOERR ; yes - report it and quit 3371 03472 1051 TAD RECSIZ ; nope - get the size of this record 3372 03473 6205 .PUSHJ @[DDBUF] ; and go dump the DSKBUF 03474 5772 3373 03475 6211 CDF 1 ; disk data lives in field 1 3374 03476 2512 ISZ @ZDKRBN ; increment both the IDE block 3375 03477 2511 ISZ @ZRDPAGE ; and RAM disk page 3376 03500 6201 CDF 0 ; ... 3377 03501 2052 ISZ RECCNT ; have we done all we need to? 3378 03502 5263 JMP DDUMP1 ; nope - go dump another one 3379 03503 6225 .POPJ ; yes - we're done (finally!!) 3380 3381 ; Here if a disk I/O error occurs... 3382 03504 6201 DIOERR: CDF 0 ; just in case 3383 03505 3027 DCA VALUE ; save the error code for a minute 3384 03506 4462 JMS @ZINLMES ; say 3385 03507 3650 ERRDIO ; "?I/O Error " 3386 03510 1027 TAD VALUE ; get the error status 3387 03511 6205 .PUSHJ @ZTOCT4C ; type it and a CRLF 03512 5457 3388 03513 5477 JMP @ZRESTA ; and abort this command completely PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 81 RL and DL Commands - Load Disk (RAM and IDE) Records BTS6120.PLX 3389 .TITLE RL and DL Commands - Load Disk (RAM and IDE) Records 3390 3391 3392 ; The DL and RL commands allow a disk to be downloaded over the console 3393 ; serial port. The format of the data expected is identical that that 3394 ; generated by the RD and DD (dump RAM/IDE disk) commands, which makes it 3395 ; possible to upload a disk image to the PC and then later download the same 3396 ; image back to the SBC6120. Since all the data is simple printing ASCII 3397 ; text, any terminal emulator program can be used to capture and replay the 3398 ; data will suffice. 3399 ; 3400 ; >RL u - download data to RAM disk unit u 3401 ; >DL pppp - download data to IDE disk partition pppp 3402 3403 ; Enter here for the RL command... 3404 03514 1371 RLLOAD: TAD [RAMDWR] ; point to the RAM disk write routine 3405 03515 3355 DCA WRPTR ; modify the code to use that 3406 03516 1107 TAD ZM128 ; set the record (page) size for RAM disk 3407 03517 3051 DCA RECSIZ ; ... 3408 03520 5327 JMP DLOAD ; fall into the regular code 3409 3410 ; Enter here for the DL command... 3411 03521 6205 DLLOAD: .PUSHJ @[NODISK] ; verify that a hard disk is attached 03522 5776 3412 03523 1370 TAD [DISKWR] ; this time use the IDE disk write routine 3413 03524 3355 DCA WRPTR ; ... 3414 03525 1110 TAD ZM256 ; and the record (block) size is 256 3415 03526 3051 DCA RECSIZ ; ... 3416 3417 ; Parse the argument for the DL and RL commands... 3418 03527 6205 DLOAD: .PUSHJ @ZOCTNW ; read the unit/partition number (required) 03530 5471 3419 03531 6205 .PUSHJ @ZEOLTST ; that has to be followed by the end of line 03532 5466 3420 03533 6211 CDF 1 ; all disk data lives in field 1 3421 03534 1045 TAD WORD ; get the number entered 3422 03535 3773 DCA @[RDUNIT] ; and set the RAM disk unit number 3423 03536 1045 TAD WORD ; ... 3424 03537 3774 DCA @[DKPART] ; and the IDE disk partition number 3425 03540 6201 CDF 0 ; back to our field now 3426 3427 ; Here to read another disk page of data from the host... 3428 03541 1051 DLOAD1: TAD RECSIZ ; pass the block size in the AC 3429 03542 6205 .PUSHJ @[LDBUF] ; load the disk buffer from the serial port 03543 5767 3430 03544 6211 CDF 1 ; (disk data lives in field 1) 3431 03545 3512 DCA @ZDKRBN ; save the address of the block we read 3432 03546 1512 TAD @ZDKRBN ; ... 3433 03547 3511 DCA @ZRDPAGE ; and the page number too 3434 03550 6201 CDF 0 ; (back to our field now) 3435 03551 4502 JMS @ZPUSHJ1 ; (call field 1 routine) 3436 03552 2024 PNLBUF ; set the disk buffer to DSKBUF 3437 03553 1051 TAD RECSIZ ; pass the record size to the I/O routine 3438 03554 4502 JMS @ZPUSHJ1 ; (call a field 1 routine) 3439 03555 WRPTR: .BLOCK 1 ; gets modified to either DISKWR or RAMDWR 3440 03556 7430 SZL ; were there any I/O errors? 3441 03557 5304 JMP DIOERR ; yes - go report that and quit 3442 03560 5341 JMP DLOAD1 ; go read another page 3443 03567 3653 03570 1220 03571 0411 03572 3600 03573 0020 03574 0036 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 82 RL and DL Commands - Load Disk (RAM and IDE) Records BTS6120.PLX 03575 1200 03576 2537 03577 0400 3444 03600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 83 Dump Disk Buffer on Console BTS6120.PLX 3445 .TITLE Dump Disk Buffer on Console 3446 3447 3448 ; This routine will dump the contents of DSKBUF on the console in ASCII. 3449 ; For each block dumped the output format consists of 33 lines of data, where 3450 ; the first 32 lines contain a disk address in the format "." 3451 ; (e.g. "0122.0160" is word 160 (octal) of block 122 (octal)) followed by 8 3452 ; words of data, also in octal. The 33rd line contains just a single octal 3453 ; number, a checksum of all 256 words in the block. 3454 ; 3455 ; This format is exactly the same input that's accepted by the LDBUF, which 3456 ; allows you to capture the output of a disk dump on a PC terminal emulator 3457 ; and then download the same data later to a different disk. This is the 3458 ; primary motivation for the checksum - it isn't too useful to humans, but 3459 ; it will guard against errors in the upload/download procedure. 3460 ; 3461 ; This routine should be called with the number of words to dump in the 3462 ; AC, which will normally be either -256 (to dump an IDE block) or -128 3463 ; (for a RAM disk page). 3464 03600 3252 DDBUF: DCA DDCNT ; save the count of words to dump 3465 03601 3047 DCA COUNT ; and clear the current word count 3466 03602 1377 TAD [DSKBUF-1] ; set up X1 to point to the buffer 3467 03603 3010 DCA X1 ; ... 3468 03604 3031 DCA CHKSUM ; and clear the checksum 3469 3470 ; Start a new line of data... 3471 03605 6211 DDBUF2: CDF 1 ; ... 3472 03606 1512 TAD @ZDKRBN ; get the page/block number we're dumping 3473 03607 6201 CDF 0 ; ... 3474 03610 6205 .PUSHJ @ZTOCT4 ; type it in octal 03611 5456 3475 03612 6205 .PUSHJ @[TDOT] ; then type the separator 03613 5776 3476 03614 1047 TAD COUNT ; then type the offset 3477 03615 6205 .PUSHJ @[TOCT3] ; ... 03616 5775 3478 03617 6205 .PUSHJ @[TSLASH] ; another separator character 03620 5774 3479 03621 6205 .PUSHJ @ZTSPACE ; ... 03622 5455 3480 3481 ; Dump eight words of data, in octal... 3482 03623 6211 DDBUF3: CDF 1 ; the disk buffer is in field 1 3483 03624 1410 TAD @X1 ; get another word 3484 03625 6201 CDF 0 ; and go back to our field 3485 03626 3027 DCA VALUE ; save it for a minute 3486 03627 1027 TAD VALUE ; get it back 3487 03630 1031 TAD CHKSUM ; and accumulate a checksum 3488 03631 3031 DCA CHKSUM ; ... 3489 03632 1027 TAD VALUE ; now we're ready to type the data 3490 03633 6205 .PUSHJ @ZTOCT4S ; in octal, with a space 03634 5460 3491 03635 2047 ISZ COUNT ; count the number we've done 3492 03636 1047 TAD COUNT ; ... 3493 03637 0105 AND ZK7 ; have we done a complete row of eight? 3494 03640 7640 SZA CLA ; ??? 3495 03641 5223 JMP DDBUF3 ; no - keep going 3496 3497 ; Here after we've finished a line of eight data words... 3498 03642 6205 .PUSHJ @ZCRLF ; start a new line 03643 5461 3499 03644 1047 TAD COUNT ; see if we've done the whole page/block 3500 03645 1252 TAD DDCNT ; compare to the block size 3501 03646 7640 SZA CLA ; ??? 3502 03647 5205 JMP DDBUF2 ; not there yet - keep dumping PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 84 Dump Disk Buffer on Console BTS6120.PLX 3503 03650 1031 TAD CHKSUM ; type just the checksum 3504 03651 5457 JMP @ZTOCT4C ; in octal, with a CRLF, and we're done 3505 3506 3507 ; Local storage for DDBUF... 3508 03652 DDCNT: .BLOCK 1 ; the number of words in this buffer PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 85 Load Disk Buffer from Console BTS6120.PLX 3509 .TITLE Load Disk Buffer from Console 3510 3511 3512 ; This routine loads the disk buffer with data from a disk block image 3513 ; transmitted over the console port. The format of the data expected is 3514 ; identical that that generated by the DDBUF routine, which makes it possible 3515 ; to upload a disk image to the PC and then later download the same image back 3516 ; to the SBC6120 with DL. Since all the data is simple printing ASCII text, 3517 ; any terminal emulator program can be used to capture and replay the data. 3518 ; 3519 ; LDBUF prompts for each line of data with a ":", and most terminal emulator 3520 ; programs for the PC can be set to look for this prompting character before 3521 ; transmitting the next line. This eliminates the need to insert fixed delays 3522 ; to avoid overrunning the SBC6120. Since LDBUF reads only printing ASCII 3523 ; characters, a download can be aborted at any time just by typing a control-C 3524 ; and there's no need for a timeout the way there is with loading paper tape 3525 ; images. 3526 ; 3527 ; The expected block size, either -128. for RAM disk or -256. for IDE disk, 3528 ; should be passed in the AC. The data read is left in DSKBUF, and the 3529 ; page/block number, extracted from the data, is left in LDPAGE. Note that 3530 ; in the event a checksum or syntax error is found, LDBUF prints an error 3531 ; message and restarts the command scanner. In that case control never 3532 ; returns to the caller! 3533 03653 3252 LDBUF: DCA DDCNT ; save the expected block size 3534 03654 1377 TAD [DSKBUF-1] ; initialize X1 to point at our buffer 3535 03655 3010 DCA X1 ; ... 3536 03656 3047 DCA COUNT ; count the data words read here 3537 03657 7240 STA ; the current disk page is unknown 3538 03660 3364 DCA LDPAGE ; ... 3539 03661 3031 DCA CHKSUM ; clear the checksum accumulator 3540 3541 ; Read the next line of data... 3542 03662 1373 LDBUF2: TAD [":"] ; prompt for data with a ":" 3543 03663 6205 .PUSHJ @[INCHWL] ; and read an entire line of data 03664 5772 3544 03665 1047 TAD COUNT ; see how many words we've read so far 3545 03666 1252 TAD DDCNT ; is it time for the checksum? 3546 03667 7650 SNA CLA ; ??? 3547 03670 5346 JMP LDBUF5 ; yes - go parse a checksum record 3548 3549 ; First parse the disk page number and offset. The offset has to match the 3550 ; number of words we've already read, but the disk address is slightly more 3551 ; complicated. For the first data record in a page we allow the address to 3552 ; be anything, and that tells us which disk page is to be written. Each data 3553 ; record after that up to the end of the page has to have the same disk 3554 ; address as the first one. This allows disk pages to be loaded in any random 3555 ; order and, more importantly, it allows unused pages to be skipped. 3556 03671 6205 .PUSHJ @ZOCTNW ; go read an octal number 03672 5471 3557 03673 1045 TAD WORD ; get the value we scanned 3558 03674 7041 CIA ; compare it to LDPAGE 3559 03675 1364 TAD LDPAGE ; ??? 3560 03676 7650 SNA CLA ; do they match ? 3561 03677 5304 JMP LDBUF3 ; yes - all is well 3562 03700 2364 ISZ LDPAGE ; no - is this the first data record? 3563 03701 5500 JMP @ZCOMERR ; not that either - the data is corrupt 3564 03702 1045 TAD WORD ; yes - just use this page number without 3565 03703 3364 DCA LDPAGE ; ... question 3566 03704 1033 LDBUF3: TAD SAVCHR ; get the separator character 3567 03705 1371 TAD [-"."] ; it has to be a "." 3568 03706 7640 SZA CLA ; ??? 3569 03707 5500 JMP @ZCOMERR ; nope - bad load format 3570 03710 6205 .PUSHJ @ZOCTNW ; now read the relative offset within the page 03711 5471 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 86 Load Disk Buffer from Console BTS6120.PLX 3571 03712 1045 TAD WORD ; ... 3572 03713 7041 CIA ; it has to match our data count 3573 03714 1047 TAD COUNT ; does it? 3574 03715 7640 SZA CLA ; ??? 3575 03716 5500 JMP @ZCOMERR ; nope - more bad data 3576 03717 1033 TAD SAVCHR ; one last test 3577 03720 1370 TAD [-"/"] ; the separator this time has to be a slash 3578 03721 7640 SZA CLA ; ??? 3579 03722 5500 JMP @ZCOMERR ; another corrupted data record 3580 3581 ; Now read the rest of the data record, which should consist of exactly 3582 ; eight data words, in octal... 3583 03723 6205 LDBUF4: .PUSHJ @ZOCTNW ; scan the next data word 03724 5471 3584 03725 1045 TAD WORD ; get the value we read 3585 03726 6211 CDF 1 ; remember that the disk buffer is in field 1 3586 03727 3410 DCA @X1 ; and store the data word 3587 03730 1045 TAD WORD ; accumulate a checksum of the data words 3588 03731 1031 TAD CHKSUM ; ... we read 3589 03732 3031 DCA CHKSUM ; ... 3590 03733 6201 CDF 0 ; back to home ground 3591 03734 2047 ISZ COUNT ; count the number of words we've read 3592 03735 1047 TAD COUNT ; let's have a look at it 3593 03736 0105 AND ZK7 ; have we read exactly eight words? 3594 03737 7640 SZA CLA ; skip if we have 3595 03740 5323 JMP LDBUF4 ; no - go read another data word 3596 03741 6205 .PUSHJ @ZGET ; yes - after eight data words 03742 5470 3597 03743 7640 SZA CLA ; ... the next thing should be the EOL 3598 03744 5500 JMP @ZCOMERR ; not EOL - this data is corrupted somehow 3599 03745 5262 JMP LDBUF2 ; this is the EOL - go read another record 3600 3601 ; We get here when we're read 128 or 256 words of data - the next thing we 3602 ; expect to find is a checksum record, which is a single octal number all by 3603 ; itself. This has to match the checksum we've calculated or the data is 3604 ; corrupted. 3605 03746 6205 LDBUF5: .PUSHJ @ZOCTNW ; scan an octal value 03747 5471 3606 03750 1045 TAD WORD ; and get what we found 3607 03751 7041 CIA ; ... 3608 03752 1031 TAD CHKSUM ; compare it to the checksum we accumulated 3609 03753 7640 SZA CLA ; they have to be the same! 3610 03754 5362 JMP DERCKS ; they aren't - bad checksum for data 3611 03755 1033 TAD SAVCHR ; get the next character 3612 03756 7640 SZA CLA ; it has to be the EOL 3613 03757 5500 JMP @ZCOMERR ; no - the syntax of this record is wrong 3614 3615 ; The checksum matches - all is well! 3616 03760 1364 TAD LDPAGE ; return the page number in the AC 3617 03761 6225 .POPJ ; ... 3618 3619 ; Here if the data checksum doesn't match... 3620 03762 4501 DERCKS: JMS @ZERROR ; print a message and restart 3621 03763 3661 ERRCKS ; ?DATA CHECKSUM MISMATCH 3622 3623 ; Local storage for LDBUF... 3624 03764 LDPAGE: .BLOCK 1 ; page number being read 3625 03770 7721 03771 7722 03772 7200 03773 0072 03774 7074 03775 6343 03776 7077 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 87 Load Disk Buffer from Console BTS6120.PLX 03777 7377 3626 04000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 88 PC Command - Copy an IDE Disk Partition BTS6120.PLX 3627 .TITLE PC Command - Copy an IDE Disk Partition 3628 3629 3630 ; The PC command will copy an entire disk partition to another partition. 3631 ; It's a convenient way to create backups of OS/8 partitions, especially since 3632 ; most modern IDE drives have room for thousands of OS/8 partitions! 3633 ; 3634 ; >PC ssss dddd - copy IDE partition ssss to partition dddd 3635 ; 3636 04000 6205 PCOPY: .PUSHJ @ZOCTNW ; read the source partition number 04001 5471 3637 04002 1045 TAD WORD ; ... 3638 04003 3023 DCA CPYSRC ; ... 3639 04004 6205 .PUSHJ @[SPATST] ; the next character has to be a space 04005 5777 3640 04006 6205 .PUSHJ @ZOCTNW ; then read the destination partition 04007 5471 3641 04010 1045 TAD WORD ; ... 3642 04011 3024 DCA CPYDST ; ... 3643 04012 6205 .PUSHJ @ZEOLTST ; that'd better be all there is 04013 5466 3644 3645 ; Ask for confirmation before overwriting the destination partition... 3646 04014 4462 JMS @ZINLMES ; say 3647 04015 4205 CCFMSG ; "Overwrite partition/unit " 3648 04016 1024 TAD CPYDST ; and then type the partition number 3649 04017 6205 .PUSHJ @ZTOCT4S ; ... 04020 5460 3650 04021 6205 .PUSHJ @[CONFRM] ; then wait for a "Y" or "N" 04022 5776 3651 04023 7620 SNL CLA ; did he answer yes??? 3652 04024 5477 JMP @ZRESTA ; nope - just quit now 3653 3654 ; Prepare to begin copying... 3655 04025 4462 JMS @ZINLMES ; say 3656 04026 4224 CP1MSG ; ... "Copying " 3657 04027 6211 CDF 1 ; reset the current block number 3658 04030 3512 DCA @ZDKRBN ; ... 3659 04031 6201 CDF 0 ; ... 3660 3661 ; Read the next block from the SRC partition... 3662 04032 4502 PCOPY1: JMS @ZPUSHJ1 ; (cross field call) 3663 04033 2024 PNLBUF ; setup a temporary disk buffer in panel memory 3664 04034 1023 TAD CPYSRC ; get the source partition 3665 04035 6211 CDF 1 ; ... 3666 04036 3775 DCA @[DKPART] ; and point DISKRD there 3667 04037 6201 CDF 0 ; ... 3668 04040 1110 TAD ZM256 ; the IDE record size is always 256 words 3669 04041 4502 JMS @ZPUSHJ1 ; (cross field call) 3670 04042 1200 DISKRD ; and go read a block from the disk 3671 04043 7430 SZL ; disk error ?? 3672 04044 5774 JMP @[DIOERR] ; yes - go report it and give up 3673 3674 ; And now write it to the destination... 3675 04045 4502 PCOPY2: JMS @ZPUSHJ1 ; (cross field call) 3676 04046 2024 PNLBUF ; setup the panel memory disk buffer 3677 04047 1024 TAD CPYDST ; change DKPART to the destination partition 3678 04050 6211 CDF 1 ; ... 3679 04051 3775 DCA @[DKPART] ; ... 3680 04052 6201 CDF 0 ; ... 3681 04053 1110 TAD ZM256 ; load the record size for DISKWR 3682 04054 4502 JMS @ZPUSHJ1 ; (cross field call) 3683 04055 1220 DISKWR ; and go write a block to the disk 3684 04056 7430 SZL ; any disk errors? 3685 04057 5774 JMP @[DIOERR] ; yes - give up PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 89 PC Command - Copy an IDE Disk Partition BTS6120.PLX 3686 3687 ; Print a dot every so often to make a simple "progress bar"... 3688 04060 6211 PCOPY3: CDF 1 ; ... 3689 04061 2773 ISZ @[DKRBN] ; increment the block number 3690 04062 7410 SKP ; still more to go 3691 04063 5275 JMP PCOPY4 ; we've done all 4096 blocks! 3692 04064 1110 TAD ZM256 ; the format command uses the record size as 3693 04065 7040 CMA ; a mask for printing the progress bar 3694 04066 0773 AND @[DKRBN] ; and so we will too 3695 04067 6201 CDF 0 ; ... 3696 04070 7640 SZA CLA ; time for another dot?? 3697 04071 5232 JMP PCOPY1 ; nope - just keep copying 3698 04072 6205 .PUSHJ @[TDOT] ; print a dot to show our progress 04073 5772 3699 04074 5232 JMP PCOPY1 ; and another page or block 3700 3701 ; All done... 3702 04075 6201 PCOPY4: CDF 0 ; ... 3703 04076 4462 JMS @ZINLMES ; say 3704 04077 4151 CP2MSG ; " Done" 3705 04100 5461 JMP @ZCRLF ; and that's all! 3706 04172 7077 04173 0037 04174 3504 04175 0036 04176 7025 04177 0534 3707 04200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 90 Free Space for Future Expansion! BTS6120.PLX 3708 .TITLE Free Space for Future Expansion! 3709 3710 06200 .PAGE 31 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 91 Type ASCII Strings BTS6120.PLX 3711 .TITLE Type ASCII Strings 3712 3713 3714 ; This routine will type a ASCIZ string stored in field 1 using the standard 3715 ; OS/8 "3 for 2" packing system. This format is used by the monitor to store 3716 ; help and error messages. On call, the address of the string is passed in the 3717 ; AC and, on return, the AC will always be cleared. 3718 06200 1377 OUTSTR: TAD [-1] ; auto index registers pre-increment 3719 06201 3010 DCA X1 ; ... 3720 06202 7346 NLM3 ; load the AC with -3 3721 06203 3050 DCA DIGITS ; and initialize the character counter 3722 3723 ; Get the next character and output it... 3724 06204 6211 OUTST1: CDF 1 ; strings always live in field 1 3725 06205 2050 ISZ DIGITS ; which character are we on? 3726 06206 5227 JMP OUTST2 ; first or second - they're easy 3727 3728 ; Extract the third character from a triplet... 3729 06207 7346 NLM3 ; re-initialize the character counter 3730 06210 3050 DCA DIGITS ; ... 3731 06211 7344 NLM2 ; then load the AC with -2 3732 06212 1010 TAD X1 ; and backup the string pointer 3733 06213 3010 DCA X1 ; ... 3734 06214 1410 TAD @X1 ; get the first word of the pair 3735 06215 0110 AND ZK7400 ; get the upper four bits of the word 3736 06216 7002 BSW ; position them in the upper bits of the byte 3737 06217 7106 CLL RTL ; ... 3738 06220 7421 MQL ; save it in the MQ for a while 3739 06221 1410 TAD @X1 ; then get the second word again 3740 06222 0110 AND ZK7400 ; the upper four bits again 3741 06223 7002 BSW ; become the lower for bits of the byte 3742 06224 7112 CLL RTR ; ... 3743 06225 7501 MQA ; put the byte together 3744 06226 5230 JMP OUTST3 ; and type it normally 3745 3746 ; Here for the first or second character of a triplet... 3747 06227 1410 OUTST2: TAD @X1 ; get the character 3748 06230 0103 OUTST3: AND ZK177 ; trim it to just seven bits 3749 06231 6201 CDF 0 ; restore the original data field 3750 06232 7450 SNA ; end of string ? 3751 06233 6225 .POPJ ; yes - we can quit now 3752 06234 6205 .PUSHJ @ZOUTCHR ; nope - type this one too 06235 5454 3753 06236 5204 JMP OUTST1 ; and go do the next 3754 3755 ; This routine does exactly the same thing as OUTSTR, except that it allows 3756 ; the message pointer to be passed in line, via a JMS instruction 3757 06237 0000 INLMES: 0 ; call here via a JMS instruction 3758 06240 7200 CLA ; ... 3759 06241 1637 TAD @INLMES ; fetch the string address 3760 06242 6205 .PUSHJ OUTSTR ; type it out 06243 5200 3761 06244 2237 ISZ INLMES ; skip over the address 3762 06245 5637 JMP @INLMES ; and return 3763 3764 ; This routine will type an ASCIZ string, packed one character per word and 3765 ; terminated with a null character, on the terminal. The address of the 3766 ; string, -1, should be loaded into the AC before calling this routine, and 3767 ; the AC will always be cleared on return. 3768 06246 3010 TASCIZ: DCA X1 ; save the pointer to the string 3769 06247 1410 TASCI1: TAD @X1 ; and get the first character 3770 06250 7450 SNA ; is this the end of the string ?? 3771 06251 6225 .POPJ ; yes -- quit now 3772 06252 6205 .PUSHJ @ZOUTCHR ; no -- type this character 06253 5454 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 92 Type ASCII Strings BTS6120.PLX 3773 06254 5247 JMP TASCI1 ; and then loop until the end 3774 3775 ; This routine is identical to TASCIZ, except that the string is stored in 3776 ; field 1, rather than field 0... 3777 06255 3010 TASZF1: DCA X1 ; save the pointer to the string 3778 06256 6211 CDF 1 ; the string is in field 1 3779 06257 1410 TAD @X1 ; and get the next character 3780 06260 6201 CDF 0 ; back to our field 3781 06261 7450 SNA ; is this the end of the string ?? 3782 06262 6225 .POPJ ; yes -- quit now 3783 06263 6205 .PUSHJ @ZOUTCHR ; no -- type this character 06264 5454 3784 06265 5256 JMP TASZF1+1 ; and then loop until the end PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 93 Type SIXBIT Words, and Characters BTS6120.PLX 3785 .TITLE Type SIXBIT Words, and Characters 3786 3787 3788 ; This routine will type the two character SIXBIT word contained in the AC. 3789 ; It always types exactly two characters, so if the second character is a null 3790 ; (00), then a trailing blank appears. The AC is cleared on return. 3791 06266 3045 TSIXW: DCA WORD ; Save the 2 characters 3792 06267 1045 TAD WORD ; And get them back 3793 06270 7002 BSW ; Position the first one 3794 06271 6205 .PUSHJ TSIXC ; And type it out 06272 5274 3795 06273 1045 TAD WORD ; No -- get the second character 3796 ; And fall into the TSIXC routine 3797 3798 ; This routine will type a single SIXBIT character from the right 3799 ; byte of the AC. The AC will be cleared on return. 3800 06274 0376 TSIXC: AND [77] ; Trim the character to just 6 bits 3801 06275 1375 TAD [" "] ; No -- convert the character to ASCII 3802 06276 5774 JMP @[THCHAR] ; And type it out PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 94 Type Decimal Numbers BTS6120.PLX 3803 .TITLE Type Decimal Numbers 3804 3805 3806 ; This routine will type the contents of the AC in decimal. It always 3807 ; treats the AC as an unsigned quantity and will type numbers from 0 to 4095. 3808 ; It uses locations WORD and COUNT and the AC is always cleared on return. 3809 06277 3045 TDECNW: DCA WORD ; remember the number to be typed 3810 06300 3050 DCA DIGITS ; and clear the quotient 3811 06301 1045 TAD WORD ; get the dividend back again 3812 3813 ; Divide by 10 via repeated subtraction... 3814 06302 7100 TDECN1: CLL ; make sure the LINK is clear 3815 06303 1373 TAD [-10.] ; subtract 10 from the dividend 3816 06304 7420 SNL ; did it fit ??? 3817 06305 5310 JMP TDECN2 ; no -- go get the remainder 3818 06306 2050 ISZ DIGITS ; yes -- increment the quotient 3819 06307 5302 JMP TDECN1 ; and keep dividing 3820 3821 ; Now figure the remainder... 3822 06310 1372 TDECN2: TAD [10.] ; correct the remainder 3823 06311 6215 .PUSH ; and save it on the stack 3824 06312 7200 CLA ; get the quotient 3825 06313 1050 TAD DIGITS ; ... 3826 06314 7450 SNA ; is it zero ??? 3827 06315 5320 JMP TDECN3 ; yes -- proceed 3828 06316 6205 .PUSHJ TDECNW ; no type that part first 06317 5277 3829 3830 ; Here to type the digit and return... 3831 06320 6235 TDECN3: .POP ; restore the remainder 3832 06321 5771 JMP @[TDIGIT] ; type it in ASCII and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 95 Type Octal Numbers BTS6120.PLX 3833 .TITLE Type Octal Numbers 3834 3835 3836 ; This routine will type a 4 digit octal number passed in the AC. It always 3837 ; prints exactly four digits, with leading zeros added as necessary. The AC 3838 ; will be cleared on return. 3839 06322 3045 TOCT4: DCA WORD ; save the number to type 3840 06323 1370 TAD [-4] ; and get the number of iterations 3841 06324 3050 TOCTN: DCA DIGITS ; ... 3842 3843 ; Extract one digit and print it... 3844 06325 1045 TOCTL: TAD WORD ; get the remaining bits 3845 06326 7106 CLL RTL ; shift them left 2 bits 3846 06327 7006 RTL ; and then 2 more (remember the link!) 3847 06330 3033 DCA SAVCHR ; remember that for a later 3848 06331 1033 TAD SAVCHR ; and we also need it now 3849 06332 7010 RAR ; restore the extra bit (in the link) 3850 06333 3045 DCA WORD ; then remember the remaining bits 3851 06334 1033 TAD SAVCHR ; get the digit back 3852 06335 0105 AND ZK7 ; trim it to just 3 bits 3853 06336 6205 .PUSHJ @[TDIGIT] ; type it out 06337 5771 3854 3855 ; Here after we have typed another digit... 3856 06340 2050 ISZ DIGITS ; is this enough ?? 3857 06341 5325 JMP TOCTL ; no -- keep typing 3858 06342 6225 .POPJ ; yes -- quit now 3859 3860 ; This routine is identical to TOCT4, except that it types only three digits 3861 ; with leading zeros. It's useful for printing eight bit quantities... 3862 06343 7014 TOCT3: R3L ; throw away the most significant digit 3863 06344 3045 DCA WORD ; save the value to be typed 3864 06345 7346 NLM3 ; get the number of iterations 3865 06346 5324 JMP TOCTN ; and join the regular code 3866 3867 ; This small routine will type an octal number in the AC followed by a space. 3868 06347 6205 TOCT4S: .PUSHJ TOCT4 ; then type the data in octal 06350 5322 3869 06351 5455 JMP @ZTSPACE ; finally type a space and return 3870 3871 ; This small routine will type an octal number from the AC followed by a CRLF. 3872 06352 6205 TOCT4C: .PUSHJ TOCT4 ; and type that in octal 06353 5322 3873 06354 5461 JMP @ZCRLF ; finish with a CRLF 3874 06370 7774 06371 7102 06372 0012 06373 7766 06374 7427 06375 0040 06376 0077 06377 7777 3875 06400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 96 Type 15 Bit Addresses BTS6120.PLX 3876 .TITLE Type 15 Bit Addresses 3877 3878 3879 ; This routine will type a 15 bit address, passed in location ADDR, and with 3880 ; the field is in location ADRFLD. The address will be typed as a 5 digit 3881 ; octal number, and then followed by a "/" character and a space. The initial 3882 ; contents of the AC are ignored and the AC is always cleared on return. 3883 06400 7200 TADDR: CLA ; ... 3884 06401 1021 TAD ADRFLD ; get the high 3 bits of the address 3885 06402 6205 .PUSHJ @[TFIELD] ; type that out 06403 5777 3886 06404 1020 TAD ADDR ; then get the address 3887 06405 6205 .PUSHJ @ZTOCT4 ; and type all 12 bits of that 06406 5456 3888 06407 6205 .PUSHJ @[TSLASH] ; type a slash as a separator 06410 5776 3889 06411 5455 JMP @ZTSPACE ; finish with a space 3890 3891 ; This routine will type a single octal digit which represents a memory 3892 ; field. The field should be passed in the AC. 3893 06412 7010 TFIELD: RAR ; right justify the field number 3894 06413 7012 RTR ; ... 3895 06414 0105 AND ZK7 ; trim it to just 3 bits 3896 06415 5775 JMP @[TDIGIT] ; and fall into TDIGIT... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 97 Scan Addresses BTS6120.PLX 3897 .TITLE Scan Addresses 3898 3899 3900 ; This routine will read a 15 bit address into registers ADDR and ADRFLD. 3901 06416 6205 RDADDR: .PUSHJ @[OCTNF] ; read the 15 bit address 06417 5774 3902 06420 1045 TAD WORD ; get the low order bits 3903 06421 3020 DCA ADDR ; and put them in ADDR 3904 06422 6225 .POPJ ; that's it... 3905 3906 ; This routine will read a 15 bit address into registers HIGH and HGHFLD. 3907 06423 6205 RDHIGH: .PUSHJ RDADDR ; read a 15 bit address 06424 5216 3908 06425 1020 TAD ADDR ; get the low order bits 3909 06426 3023 DCA HIGH ; into HIGH 3910 06427 1021 TAD ADRFLD ; get the field 3911 06430 3025 DCA HGHFLD ; into HGHFLD 3912 06431 6225 .POPJ ; and that's all 3913 3914 ; This routine will read a 15 bit address into registers LOW AND LOWFLD. 3915 06432 6205 RDLOW: .PUSHJ RDADDR ; the same thing as before 06433 5216 3916 06434 1020 TAD ADDR ; ... 3917 06435 3024 DCA LOW ; only the names have changed 3918 06436 1021 TAD ADRFLD ; ... 3919 06437 3026 DCA LOWFLD ; ... 3920 06440 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 98 Scan an Address Range BTS6120.PLX 3921 .TITLE Scan an Address Range 3922 3923 3924 ; This routine will read either one or two octal numbers which describe a 3925 ; range of memory addresses. A range may be a single number (in which case 3926 ; the starting and ending values are the same) or two numbers with a space 3927 ; character between them (in which case the first number is the starting value 3928 ; and the last is the ending value). The starting value is always returned in 3929 ; locations LOW/LOWFLD and ADDR/ADRFLD, and the ending value is placed in 3930 ; HIGH/HGHFLD. If two addresses were seen, the LINK will be set upon return; 3931 ; it is cleared if only one address was found. 3932 06441 6205 RANGE: .PUSHJ RDLOW ; first read the low part of the range 06442 5232 3933 06443 6205 .PUSHJ @ZSPACM0 ; get the next non-space character 06444 5464 3934 06445 1373 TAD [-"-"] ; is it a range delimiter ?? 3935 06446 7640 SZA CLA ; ??? 3936 06447 5265 JMP RANGE1 ; no -- this must be the single address type 3937 3938 ; Here for a two address range... 3939 06450 6205 .PUSHJ RDHIGH ; go read the high order part of the range 06451 5223 3940 06452 1024 TAD LOW ; make ADDR point to the starting point 3941 06453 3020 DCA ADDR ; ... 3942 06454 1026 TAD LOWFLD ; ... 3943 06455 3021 DCA ADRFLD ; ... 3944 06456 6205 .PUSHJ TSTADR ; then be sure the numbers are in order 06457 5306 3945 06460 7020 CML ; ... 3946 06461 7630 SZL CLA ; ??? 3947 06462 6225 .POPJ ; yes -- return with the link set 3948 06463 4501 JMS @ZERROR ; no -- this isn't legal 3949 06464 3621 ERRRAN ; ?WRONG ORDER 3950 3951 ; Here for a single address range... 3952 06465 1024 RANGE1: TAD LOW ; set the high equal to the low 3953 06466 3023 DCA HIGH ; ... 3954 06467 1026 TAD LOWFLD ; ... 3955 06470 3025 DCA HGHFLD ; ... 3956 06471 7100 CLL ; Then return with the link cleared 3957 06472 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 99 Address Arithmetic BTS6120.PLX 3958 .TITLE Address Arithmetic 3959 3960 3961 ; This routine will increment the 15 bit address contained in registers 3962 ; ADDR and ADRFLD. If the address increments past 77777, the link will be 3963 ; 1 on return; otherwise it is always 0. 3964 06473 7300 NXTADR: CLA CLL ; ... 3965 06474 2020 ISZ ADDR ; increment the address 3966 06475 6225 .POPJ ; no wrap around -- leave the field alone 3967 06476 1021 TAD ADRFLD ; wrap around -- increment the field too 3968 06477 1372 TAD [-70] ; are we already in field 7 ?? 3969 06500 7510 SPA ; ??? 3970 06501 7020 CML ; no -- make the LINK be cleared on return 3971 06502 1371 TAD [70+10] ; restore and increment the field 3972 06503 0104 AND ZK70 ; only allow these bits in the result 3973 06504 3021 DCA ADRFLD ; and put it back 3974 06505 6225 .POPJ ; ... 3975 3976 ; This routine will compare the 15 bit address in registers ADDR and 3977 ; ADRFLD to the address in registers HIGH and HGHFLD. If ADDR/ADRFLD 3978 ; is less than HIGH/HGHFLD, the link will be zero on return. If ADDR/ADRFLD 3979 ; is greater then or equal to HIGH/HGHFLD, the link will be one. 3980 06506 7300 TSTADR: CLA CLL ; clear the AC and set L = 0 3981 06507 1021 TAD ADRFLD ; get the field 3982 06510 7061 CMA IAC CML ; negate the field and set L = 1 3983 06511 1025 TAD HGHFLD ; compare to the high field 3984 06512 7640 SZA CLA ; are they equal ?? 3985 06513 6225 .POPJ ; no -- the LINK has the correct status 3986 06514 1023 TAD HIGH ; yes -- compare the addresses 3987 06515 7041 CMA CIA ; L = 0 now 3988 06516 1020 TAD ADDR ; ... 3989 06517 7200 CLA ; clear the AC 3990 06520 6225 .POPJ ; but return the status in the LINK 3991 3992 ; This routine will swap the 15 bit address in ADDR/ADRFLD with the the 3993 ; 15 bit address in LOW/LOWFLD. The AC is always cleared. 3994 06521 7200 SWPADR: CLA ; ... 3995 06522 1024 TAD LOW ; get one value 3996 06523 7421 MQL ; and save it in the MQ 3997 06524 1020 TAD ADDR ; then get the other 3998 06525 3024 DCA LOW ; move it to the other place 3999 06526 7501 MQA ; and get the original one back 4000 06527 3020 DCA ADDR ; it goes in the second location 4001 06530 1026 TAD LOWFLD ; now do the same thing for fields 4002 06531 7421 MQL ; ... 4003 06532 1021 TAD ADRFLD ; ... 4004 06533 3026 DCA LOWFLD ; ... 4005 06534 7501 MQA ; ... 4006 06535 3021 DCA ADRFLD ; ... 4007 06536 6225 .POPJ ; that's all there is to it 4008 06571 0100 06572 7710 06573 7723 06574 7004 06575 7102 06576 7074 06577 6412 4009 06600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 100 Scan a Command Name BTS6120.PLX 4010 .TITLE Scan a Command Name 4011 4012 4013 ; This routine will scan a command or register name for the monitor. Names 4014 ; are always alphabetic, may not contain any digits, and are limited to one or 4015 ; two letters. The result is stored, in SIXBIT, in location NAME. One letter 4016 ; commands are left justified and padded on the right with zeros. If the end 4017 ; of line is the next character, then this routine will return with NAME set 4018 ; to zero and no error. If, however, there is a least one character out there 4019 ; and it is not a letter, then COMERR will be called... 4020 06600 7200 NAMENW: CLA ; be sure the AC is zero 4021 06601 3030 DCA NAME ; and clear the resulting name 4022 06602 6205 .PUSHJ @ZSPACMP ; get the next character, whatever it is 06603 5463 4023 06604 7450 SNA ; is there anything there ?? 4024 06605 6225 .POPJ ; no -- just give up now 4025 06606 6205 .PUSHJ ALPHA ; see if it is a letter 06607 5227 4026 06610 7420 SNL ; was it a letter ?? 4027 06611 5500 JMP @ZCOMERR ; no -- this isn't legal 4028 06612 1106 TAD ZMSPACE ; yes -- convert it to SIXBIT 4029 06613 7002 BSW ; left justify it 4030 06614 3030 DCA NAME ; and store it in word 4031 4032 ; Check for a second letter in the name... 4033 06615 6205 .PUSHJ @ZGET ; get the next character 06616 5470 4034 06617 6205 .PUSHJ ALPHA ; is this a letter ?? 06620 5227 4035 06621 7420 SNL ; ??? 4036 06622 5465 JMP @ZBACKUP ; no -- put it back and return 4037 06623 1106 TAD ZMSPACE ; yes -- convert it to SIXBIT too 4038 06624 1030 TAD NAME ; put both letters together 4039 06625 3030 DCA NAME ; ... 4040 06626 6225 .POPJ ; then that's all 4041 4042 ; This routine will return with the LINK bit set if the AC holds a letter, 4043 ; and with the LINK reset if it does not. In either case the AC is not 4044 ; disturbed... 4045 06627 7120 ALPHA: STL ; be sure the link starts in a known state 4046 06630 1377 TAD [-"A"] ; compare it to the first letter 4047 06631 7500 SMA ; skip if it isn't a letter 4048 06632 5235 JMP ALPHA1 ; it might be -- look further 4049 06633 1376 TAD ["A"] ; it's not a letter -- restore the AC 4050 06634 6225 .POPJ ; and quit (the link is zero now !!) 4051 4052 ; Here if it might be a letter (the link is also zero now)... 4053 06635 1375 ALPHA1: TAD ["A"-"Z"-1] ; now compare it to the other end 4054 06636 7500 SMA ; skip if it is a letter 4055 06637 7020 CML ; it isn't a letter -- set the link to a 0 4056 06640 1374 TAD ["Z"+1] ; restore the character and the link 4057 06641 6225 .POPJ ; then that's all PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 101 Command Lookup and Dispatch BTS6120.PLX 4058 .TITLE Command Lookup and Dispatch 4059 4060 4061 ; This routine will lookup a command or register name in a table and then 4062 ; dispatch to the corresponding routine. The address of the table, should 4063 ; be passed in the AC. The table is formatted as two word entries - the first 4064 ; word of a pair is the SIXBIT name of the command or register, and the second 4065 ; word is the address of the routine to call. As soon as this routine finds a 4066 ; first word that matches the value currently in NAME, it will jump to the 4067 ; routine indicated by the second word. The table ends with a zero word 4068 ; followed by the address of an error routine - the zero word always matches 4069 ; the current name and the error routine will be called. 4070 ; 4071 ; NOTE: Command tables are always stored in field one, however the addresses 4072 ; of all the routines they reference are always in field zero! 4073 ; 4074 ; NOTE: Auto index registers pre-decrement, so the address -1 of the table 4075 ; must be passed in the AC! 4076 06642 3010 MATCH: DCA X1 ; save the pointer to the table 4077 06643 6211 CDF 1 ; command tables are stored in field 1 4078 4079 ; Search for a name which matches... 4080 06644 1410 MATCH1: TAD @X1 ; pick up the name (from field 1) 4081 06645 7450 SNA ; is this the end of the table ?? 4082 06646 5255 JMP MATCH2 ; yes -- this always matches 4083 06647 7041 CIA ; make the word negative 4084 06650 1030 TAD NAME ; and compare it to the desired value 4085 06651 7650 SNA CLA ; ??? 4086 06652 5255 JMP MATCH2 ; a match !! 4087 06653 2010 ISZ X1 ; no match -- skip over the address 4088 06654 5244 JMP MATCH1 ; and keep looking 4089 4090 ; Here when we find a match... 4091 06655 1410 MATCH2: TAD @X1 ; get the address of the routine 4092 06656 3261 DCA MATCH3 ; put that in a safe place 4093 06657 6201 CDF 0 ; change back to the usual data field 4094 06660 5661 JMP @MATCH3 ; then branch to the right routine 4095 4096 ; Temporary storage for MATCH... 4097 06661 MATCH3: .BLOCK 1 ; address of the matching routine PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 102 Scan Decimal Numbers BTS6120.PLX 4098 .TITLE Scan Decimal Numbers 4099 4100 4101 ; This routine will read a decimal number from the command line and return 4102 ; its value in location WORD. The value is limited to 12 bits and overflows 4103 ; are not detected. At least one decimal digit must be found on the command 4104 ; line or COMERR will be called, and the first non-digit character found will 4105 ; be returned in location SAVCHR. 4106 06662 7200 DECNW: CLA ; ignore the AC initially 4107 06663 3045 DCA WORD ; clear the total 4108 06664 3050 DCA DIGITS ; and the digit counter 4109 06665 6205 .PUSHJ @ZSPACMP ; ignore any leading blanks 06666 5463 4110 4111 ; Check for a decimal digit... 4112 06667 1373 DECNW1: TAD [-"0"] ; compare it to zero 4113 06670 7510 SPA ; ??? 4114 06671 5313 JMP DECNW2 ; it's not a digit -- quit 4115 06672 1372 TAD [-9.] ; then compare it to the other end 4116 06673 7740 SMA SZA CLA ; ??? 4117 06674 5313 JMP DECNW2 ; still not a digit 4118 4119 ; Accumulate another decimal digit... 4120 06675 1045 TAD WORD ; get the old total 4121 06676 7104 CLL RAL ; multiply it by two 4122 06677 3045 DCA WORD ; and save that 4123 06700 1045 TAD WORD ; ... 4124 06701 7104 CLL RAL ; then multiply it by 4 more 4125 06702 7104 CLL RAL ; (for a total of 8) 4126 06703 1045 TAD WORD ; because 8x + 2x = 10x 4127 06704 1033 TAD SAVCHR ; then add the new digit 4128 06705 1373 TAD [-"0"] ; and correct for ASCII characters 4129 06706 3045 DCA WORD ; remember that for next time 4130 4131 ; Read the next digit and proceed... 4132 06707 2050 ISZ DIGITS ; remember one more digit processed 4133 06710 6205 .PUSHJ @ZGET ; get the next character 06711 5470 4134 06712 5267 JMP DECNW1 ; then keep trying 4135 4136 ; Here when we find something which isn't a digit... 4137 06713 7200 DECNW2: CLA ; ... 4138 06714 1050 TAD DIGITS ; get the digit count 4139 06715 7650 SNA CLA ; it has to be at least one 4140 06716 5500 JMP @ZCOMERR ; that's an error if it isn't 4141 06717 6225 .POPJ ; and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 103 Scan Octal Numbers BTS6120.PLX 4142 .TITLE Scan Octal Numbers 4143 4144 4145 ; This routine will read an octal number from the command line and return 4146 ; its value in location WORD. The value is usually limited to twelve bits, 4147 ; however any overflow bits will be left in location WORDH. This is intended 4148 ; for use by the OCTNF routine to extract the field from a 15 bit address. 4149 ; At least one octal digit must be found on the command line or COMERR will be 4150 ; called, and the first non-digit character found will be returned in location 4151 ; SAVCHR. 4152 06720 7200 OCTNW: CLA ; remove any junk 4153 06721 3045 DCA WORD ; clear the partial total 4154 06722 3050 DCA DIGITS ; we haven't read any digits yet 4155 06723 6205 .PUSHJ @ZSPACMP ; ignore any leading spaces 06724 5463 4156 4157 ; Check for an octal digit next... 4158 06725 1373 OCTN1: TAD [-"0"] ; compare it to a zero 4159 06726 7510 SPA ; ??? 4160 06727 5350 JMP OCTN2 ; this one isn't a digit 4161 06730 1371 TAD [-7] ; now compare to the high end of the range 4162 06731 7740 SMA SZA CLA ; ??? 4163 06732 5350 JMP OCTN2 ; still not a digit 4164 4165 ; Now accumulate another digit. 4166 06733 1045 TAD WORD ; get the previous total 4167 06734 3046 DCA WORDH ; and remember that for OCTNF 4168 06735 1045 TAD WORD ; then again 4169 06736 7006 RTL ; shift it left 3 bits 4170 06737 7004 RAL ; ... 4171 06740 0370 AND [7770] ; then insure that no junk has wrapped around 4172 06741 1033 TAD SAVCHR ; add the next digit 4173 06742 1373 TAD [-"0"] ; and correct for ASCII values 4174 06743 3045 DCA WORD ; remember the new total 4175 06744 2050 ISZ DIGITS ; also remember how many digits we read 4176 06745 6205 .PUSHJ @ZGET ; read the next character 06746 5470 4177 06747 5325 JMP OCTN1 ; then go look for more 4178 4179 ; Here when we find something which isn't a digit... 4180 06750 7200 OCTN2: CLA ; ... 4181 06751 1050 TAD DIGITS ; see how many digits we've read 4182 06752 7650 SNA CLA ; there must be at least one 4183 06753 5500 JMP @ZCOMERR ; nope -- this isn't legal 4184 06754 6225 .POPJ ; and return that in the AC 4185 06770 7770 06771 7771 06772 7767 06773 7720 06774 0133 06775 7746 06776 0101 06777 7677 4186 07000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 104 Scan 15 Bit Addresses BTS6120.PLX 4187 .TITLE Scan 15 Bit Addresses 4188 4189 4190 ; This routine will read a 15 bit address from the command. The lower 12 4191 ; bits of the address are always left in location WORD, and the upper 3 bits 4192 ; will be in location ADRFLD, properly justified. If the user types 5 or more 4193 ; digits in the octal address, the lower 12 bits becomes the address, and the 4194 ; next 3 most significant bits are the field. If his octal number has 4 or 4195 ; fewer digits, the field will be the current data field instead. For example, 4196 ; (assume that the current DF is 3): 4197 ; 4198 ; 1234 --> Location 1234, field 3 4199 ; 01234 --> Location 1234, field 0 4200 ; 41234 --> Location 1234, field 4 4201 ; 5641234 --> Location 1234, field 4 4202 ; 4203 ; Like the OCTNW routine, this routine will return the low order 12 bits 4204 ; in location WORD. There is an alternate entry point at location OCTNI; this 4205 ; is identical to OCTNF, except that the instruction field, not the data field, 4206 ; provides the default field number... 4207 4208 ; Here to read an address in the instruction field... 4209 07000 7200 OCTNI: CLA ; ... 4210 07001 1002 TAD UFLAGS ; use the instruction field as default 4211 07002 0104 AND ZK70 ; ... 4212 07003 5210 JMP OCTNF1 ; then proceed normally 4213 4214 ; Here to read an address in the data field... 4215 07004 7200 OCTNF: CLA ; ... 4216 07005 1002 TAD UFLAGS ; use the data field as the default 4217 07006 7014 R3L ; ... 4218 07007 0104 AND ZK70 ; ... 4219 07010 3021 OCTNF1: DCA ADRFLD ; and save the default for later 4220 07011 6205 .PUSHJ @ZOCTNW ; read a normal octal number 07012 5471 4221 07013 7200 CLA ; we don't care about this part 4222 07014 1050 TAD DIGITS ; see how many digits there were 4223 07015 1377 TAD [-5] ; we need at least 5 4224 07016 7710 SPA CLA ; ??? 4225 07017 6225 .POPJ ; there weren't that many -- use the default 4226 4227 ; Extract the upper 3 bits of the address... 4228 07020 1046 TAD WORDH ; get the high order bits 4229 07021 7002 BSW ; then put the upper 3 bits in the right place 4230 07022 0104 AND ZK70 ; trim it to just the important bits 4231 07023 3021 DCA ADRFLD ; then that is the new data field (temporarily) 4232 07024 6225 .POPJ ; that's all folks PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 105 Ask For Confirmation BTS6120.PLX 4233 .TITLE Ask For Confirmation 4234 4235 4236 ; This routine will type a question mark and then wait for the operator to 4237 ; enter a "Y" (or "y") to confirm. It's used by exceptionally dangerous 4238 ; commands, like FORMAT, and normally the caller will type a short string 4239 ; (e.g. "Format unit 0" before actually calling this function. If the 4240 ; operator does confirm, it will return with the link set. If the operator 4241 ; types anything other than "Y" or "y", it will return with the link clear. 4242 ; Note that it's also acceptable to just type Control-C to abort! 4243 07025 6205 CONFRM: .PUSHJ @[TQUEST] ; type a question mark 07026 5776 4244 07027 6205 CONF1: .PUSHJ @[INCHRS] ; go get a character of input 07030 5775 4245 07031 7450 SNA ; did we get anything ? 4246 07032 5227 JMP CONF1 ; nope - keep waiting 4247 07033 3033 DCA SAVCHR ; we got a real character - save it 4248 07034 1033 TAD SAVCHR ; and echo it back to the terminal 4249 07035 6205 .PUSHJ @ZOUTCHR ; ... 07036 5454 4250 07037 6205 .PUSHJ @ZCRLF ; followed by a CRLF 07040 5461 4251 4252 ; See what his answer was... 4253 07041 1033 TAD SAVCHR ; get the answer once more 4254 07042 1374 TAD [-"Y"] ; is it a "Y" 4255 07043 7450 SNA ; ??? 4256 07044 5252 JMP CONF2 ; yes - return with the link set 4257 07045 1373 TAD ["Y"-"y"] ; or a "y"? 4258 07046 7450 SNA ; ??? 4259 07047 5252 JMP CONF2 ; yes - same thing 4260 07050 7300 CLA CLL ; nope - return FALSE 4261 07051 6225 .POPJ 4262 4263 ; Here if he answered "Y" or "y"... 4264 07052 7320 CONF2: CLA STL ; return TRUE 4265 07053 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 106 Type Special Characters BTS6120.PLX 4266 .TITLE Type Special Characters 4267 4268 4269 ; This routine will simulate a TAB on the terminal, which it does by typing 4270 ; spaces until the horizontal position reaches a multiple of 8 characters. 4271 ; Note that this routine will always type at least one space. The AC is 4272 ; always cleared by this routine. 4273 07054 6205 TTABC: .PUSHJ TSPACE ; Always type at least one space 07055 5263 4274 07056 1036 TAD HPOS ; Get the current horizontal position 4275 07057 0105 AND ZK7 ; Is it a multiple of 8 ?? 4276 07060 7640 SZA CLA ; ??? 4277 07061 5254 JMP TTABC ; No -- keep typing 4278 07062 6225 .POPJ ; Yes -- we can stop now 4279 4280 ; This routine will type a space on the terminal. 4281 07063 7200 TSPACE: CLA ; Clear the AC 4282 07064 1372 TAD [" "] ; And load a space character 4283 07065 5771 JMP @[THCHAR] ; Then type it and return 4284 4285 ; This routine will type a question mark on the terminal. 4286 07066 7200 TQUEST: CLA ; ... 4287 07067 1370 TAD ["?"] ; ... 4288 07070 5771 JMP @[THCHAR] ; ... 4289 4290 ; This routine will type a BELL character on the terminal. 4291 07071 7200 TBELL: CLA ; ... 4292 07072 1367 TAD [CHBEL] ; Get a bell character 4293 07073 5766 JMP @[TFCHAR] ; Then type it out 4294 4295 ; Type a slash (used as an address separator) on the terminal. 4296 07074 7200 TSLASH: CLA ; ... 4297 07075 1365 TAD ["/"] ; ... 4298 07076 5771 JMP @[THCHAR] ; ... 4299 4300 ; Type a dot (used for decimal numbers and disk addresses) on the terminal. 4301 07077 7200 TDOT: CLA ; ... 4302 07100 1364 TAD ["."] ; ... 4303 07101 5771 JMP @[THCHAR] ; ... 4304 4305 ; Convert the value in the AC to a decimal digit and type it... 4306 07102 1363 TDIGIT: TAD ["0"] ; make it ASCII 4307 07103 5771 JMP @[THCHAR] ; type it and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 107 Type Carriage Return, Line Feed and Backspace BTS6120.PLX 4308 .TITLE Type Carriage Return, Line Feed and Backspace 4309 4310 4311 ; This routine will type a carriage return, line feed pair on the terminal 4312 ; and it will correctly update HPOS to show that the cursor is now at the left 4313 ; margin. In addition, it will keep count of the number of CRLFs output in 4314 ; location VPOS, and when the terminal's screen is full (as indicated by VPOS 4315 ; equals LENGTH) it will cause an automatic XOFF. The AC is always cleared 4316 ; on return. 4317 07104 7200 CRLF: CLA ; be sure the AC is cleared 4318 07105 1362 TAD [CHCRT] ; get a return character 4319 07106 6205 .PUSHJ @[TFCHAR] ; and type that out 07107 5766 4320 07110 3036 DCA HPOS ; remember that the cursor is in column zero 4321 4322 ; Now check the vertical position of the cursor... 4323 07111 2037 ISZ VPOS ; increment the current position 4324 07112 7000 NOP ; ... 4325 07113 1041 TAD LENGTH ; get the size of the screen 4326 07114 7450 SNA ; is it zero ?? 4327 07115 5327 JMP CRLF1 ; yes -- never stop 4328 07116 7041 CIA ; no -- make it negative 4329 07117 1037 TAD VPOS ; and compare it to the current location 4330 07120 7710 SPA CLA ; is the screen full ?? 4331 07121 5327 JMP CRLF1 ; no -- proceed 4332 07122 3037 DCA VPOS ; yes -- clear the vertical position 4333 07123 6205 .PUSHJ @[TBELL] ; type a bell character 07124 5761 4334 07125 7240 STA ; then load a -1 into the AC 4335 07126 3035 DCA XOFF ; and cause an automatic XOFF 4336 4337 ; Type the line feed next... 4338 07127 1360 CRLF1: TAD [CHLFD] ; now get a line feed 4339 07130 5766 JMP @[TFCHAR] ; type that and return 4340 4341 ; This routine will type a BACKSPACE character on the terminal and update 4342 ; HPOS to show the new cursor position. It will not allow you to backspace 4343 ; beyond the left margin of the temrinal. The AC is always cleared on return. 4344 07131 7240 TBACKS: STA ; load the AC with -1 4345 07132 1036 TAD HPOS ; and decrement HPOS 4346 07133 7510 SPA ; are we going to pass the left margin ?? 4347 07134 5341 JMP BACKS1 ; yes -- don't type anything 4348 07135 3036 DCA HPOS ; no -- update HPOS 4349 07136 1357 TAD [CHBSP] ; then get a backspace character 4350 07137 6205 .PUSHJ @[TFCHAR] ; and type that out 07140 5766 4351 07141 7200 BACKS1: CLA ; clear the AC 4352 07142 6225 .POPJ ; and that's all 4353 07157 0010 07160 0012 07161 7071 07162 0015 07163 0060 07164 0056 07165 0057 07166 7444 07167 0007 07170 0077 07171 7427 07172 0040 07173 7740 07174 7647 07175 7477 07176 7066 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 108 Type Carriage Return, Line Feed and Backspace BTS6120.PLX 07177 7773 4354 07200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 109 Read Command Lines BTS6120.PLX 4355 .TITLE Read Command Lines 4356 4357 4358 ; This routine will read a single command line from the user and store the 4359 ; text of the line, one character per word and terminated by a null character, 4360 ; in the array at CMDBUF. The size of CMDBUF, and therefore the maximum 4361 ; length of a command, is given by MAXCMD and is normally a page (128 words). 4362 ; An auto-index register, L, is set aside just for the purpose of indexing the 4363 ; command buffer and when it returns this routine will always leave L set up 4364 ; to point to the beginning of the command. 4365 ; 4366 ; While it is reading the command, this routine will recognize these control 4367 ; characters: 4368 ; 4369 ; Control-C --> Abort the command 4370 ; Control-R --> Retype the current line, including corrections 4371 ; Control-U --> Erase the current line and start over again 4372 ; DELETE --> Erase the last character (echos the last character typed) 4373 ; BACKSPACE --> Erase the last character on a CRT 4374 ; Return --> Terminates the current command 4375 ; Line Feed --> " " " " 4376 ; ESCAPE --> " " " " 4377 ; 4378 ; When this routine is called, the AC should contain the prompting 4379 ; character. 4380 ; 4381 07200 3357 INCHWL: DCA PROMPT ; remember the prompt character 4382 07201 1377 TAD [CMDBUF-1] ; point to the line buffer 4383 07202 3013 DCA L ; and initialize the pointer 4384 07203 3356 DCA CMDLEN ; say that this command is zero characters 4385 07204 3035 DCA XOFF ; clear the XOFF and 4386 07205 3034 DCA CTRLO ; control-O flags... 4387 07206 1357 TAD PROMPT ; get the prompting address back again 4388 07207 6205 .PUSHJ @ZOUTCHR ; and type out the character 07210 5454 4389 4390 ; Read and process the next character... 4391 07211 6205 INCHW1: .PUSHJ @[INCHRS] ; try to read something from the console 07212 5776 4392 07213 7450 SNA ; did we get anything ?? 4393 07214 5211 JMP INCHW1 ; no -- wait for it 4394 07215 3033 DCA SAVCHR ; save this character for a while 4395 07216 3035 DCA XOFF ; then clear the XOFF, 4396 07217 3034 DCA CTRLO ; control-O, and 4397 07220 3037 DCA VPOS ; automatic XOFF flags 4398 07221 1033 TAD SAVCHR ; get the character back 4399 07222 1106 TAD ZMSPACE ; compare this to a space 4400 07223 7510 SPA ; ??? 4401 07224 5243 JMP INCHW3 ; this is a control character 4402 07225 1375 TAD [" "-177] ; is this a DELETE character ? 4403 07226 7650 SNA CLA ; ??? 4404 07227 5335 JMP INCHW8 ; yes -- go do that 4405 4406 ; Here to process a normal character... 4407 07230 1356 INCHW2: TAD CMDLEN ; get the length of this line 4408 07231 1374 TAD [-MAXCMD] ; and compare to the maximum 4409 07232 7700 SMA CLA ; are we already full ?? 4410 07233 5353 JMP INCH10 ; yes -- don't store this character 4411 07234 1033 TAD SAVCHR ; get the character back 4412 07235 6205 .PUSHJ @ZOUTCHR ; and echo it to the terminal 07236 5454 4413 07237 1033 TAD SAVCHR ; get the character again 4414 07240 3413 DCA @L ; store it in the line 4415 07241 2356 ISZ CMDLEN ; the command is one character longer now 4416 07242 5211 JMP INCHW1 ; and go get the next one PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 110 Read Command Lines BTS6120.PLX 4417 4418 ; Here to handle a control-R command... 4419 07243 1373 INCHW3: TAD [" "-CHCTR] ; is this really a control-R ?? 4420 07244 7440 SZA ; ??? 4421 07245 5265 JMP INCHW4 ; no -- Proceed 4422 07246 3413 DCA @L ; yes -- close the command buffer 4423 07247 1372 TAD [CHCTR] ; get the control-R character back 4424 07250 6205 .PUSHJ @ZOUTCHR ; and echo that to the terminal 07251 5454 4425 07252 6205 .PUSHJ @ZCRLF ; start a new line 07253 5461 4426 07254 1357 TAD PROMPT ; get the prompt character first 4427 07255 6205 .PUSHJ @ZOUTCHR ; and always type that too 07256 5454 4428 07257 1377 TAD [CMDBUF-1] ; point to the current command 4429 07260 6205 .PUSHJ @[TASCIZ] ; and echo the entire line back 07261 5771 4430 07262 6205 .PUSHJ @ZBACKUP ; backup L over the null we put there 07263 5465 4431 07264 5211 JMP INCHW1 ; finally continue typing 4432 4433 ; Here to handle a Control-U character... 4434 07265 1370 INCHW4: TAD [CHCTR-CHCTU] ; is this really a Control-U character ?? 4435 07266 7440 SZA ; ??? 4436 07267 5276 JMP INCHW5 ; no -- keep trying 4437 07270 1367 TAD [CHCTU] ; yes -- get the character back again 4438 07271 6205 .PUSHJ @ZOUTCHR ; and echo that to the operator 07272 5454 4439 07273 6205 .PUSHJ @ZCRLF ; then start on a new line 07274 5461 4440 07275 5201 JMP INCHWL+1 ; and go start all over again 4441 4442 ; Here to handle a BACKSPACE character... 4443 07276 1366 INCHW5: TAD [CHCTU-CHBSP] ; is that what this is ?? 4444 07277 7440 SZA ; ??? 4445 07300 5313 JMP INCHW6 ; nope, not yet 4446 07301 1356 TAD CMDLEN ; yes -- get the length of this command 4447 07302 7650 SNA CLA ; is it a null line ?? 4448 07303 5211 JMP INCHW1 ; yes -- there's nothing to delete 4449 07304 6205 .PUSHJ @[TBACKS] ; yes, type a backspace 07305 5765 4450 07306 6205 .PUSHJ @ZTSPACE ; then type a space 07307 5455 4451 07310 6205 .PUSHJ @[TBACKS] ; and another backspace 07311 5765 4452 07312 5345 JMP INCHW9 ; finally join with the DELETE code 4453 4454 ; Here to check for line terminators... 4455 07313 1364 INCHW6: TAD [CHBSP-CHCRT] ; is this a return ?? 4456 07314 7450 SNA ; ??? 4457 07315 5327 JMP INCHW7 ; yes -- this line is done 4458 07316 1363 TAD [CHCRT-CHLFD] ; no -- Is it a line feed then ? 4459 07317 7450 SNA ; ??? 4460 07320 5327 JMP INCHW7 ; yes -- That's just as good 4461 07321 1362 TAD [CHLFD-CHESC] ; no -- How about an escape ? 4462 07322 7640 SZA CLA ; ??? 4463 07323 5230 JMP INCHW2 ; no -- just store this control character 4464 4465 ; Here to finish a command... 4466 07324 1361 TAD [CHESC] ; get the ESCAPE code back 4467 07325 6205 .PUSHJ @ZOUTCHR ; and echo that to the terminal 07326 5454 4468 07327 6205 INCHW7: .PUSHJ @ZCRLF ; then close the input line 07330 5461 4469 07331 3413 DCA @L ; end the command with a null byte PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 111 Read Command Lines BTS6120.PLX 4470 07332 1377 TAD [CMDBUF-1] ; and then backup the pointer 4471 07333 3013 DCA L ; to the start of the command 4472 07334 6225 .POPJ ; that's all there is to it 4473 4474 ; Here to process a DELETE character... 4475 07335 1356 INCHW8: TAD CMDLEN ; get the command length 4476 07336 7650 SNA CLA ; is this a null command ?? 4477 07337 5211 JMP INCHW1 ; yes -- there's nothing to delete 4478 07340 6205 .PUSHJ @ZBACKUP ; decrement the line pointer 07341 5465 4479 07342 1413 TAD @L ; get the last character stored 4480 07343 6205 .PUSHJ @ZOUTCHR ; and echo that for the DELETE 07344 5454 4481 4482 ; Now delete the last character typed... 4483 07345 6205 INCHW9: .PUSHJ @ZBACKUP ; decrement the line pointer 07346 5465 4484 07347 7240 STA ; then fix the command length too 4485 07350 1356 TAD CMDLEN ; ... 4486 07351 3356 DCA CMDLEN ; ... 4487 07352 5211 JMP INCHW1 ; finally go get the next character 4488 4489 ; Here if the command line is full -- echo a bell instead... 4490 07353 6205 INCH10: .PUSHJ @[TBELL] ; go type a bell character 07354 5760 4491 07355 5211 JMP INCHW1 ; then go wait for something to do 4492 4493 ; Local storage for INCHWL... 4494 07356 CMDLEN: .BLOCK 1 ; the length of the current line 4495 07357 PROMPT: .BLOCK 1 ; the prompting character 4496 07360 7071 07361 0033 07362 7757 07363 0003 07364 7773 07365 7131 07366 0015 07367 0025 07370 7775 07371 6246 07372 0022 07373 0016 07374 7631 07375 7641 07376 7477 07377 0230 4497 07400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 112 Terminal Output Primitives BTS6120.PLX 4498 .TITLE Terminal Output Primitives 4499 4500 4501 ; This routine will type the character in the AC on on the terminal. If the 4502 ; character is a printing character, it will be typed normally. If this 4503 ; character is happens to be a DELETE or NULL code (ASCII codes 00 and 7F), 4504 ; it will be ignored. If the character is a TAB, it is simulated by calling 4505 ; the TTABC routine. Finally, if it is any other control character, it is 4506 ; converted to the familiar ^x representation (unless it is an ESCAPE code, 4507 ; which, by tradition, is typed as $). This routine cannot be used to type 4508 ; carriage returns, line feeds, bells, or other control characters that are 4509 ; to be output literally. The AC is always cleared on return. 4510 07400 7450 OUTCHR: SNA ; first see if this character is a null 4511 07401 6225 .POPJ ; just drop it if it is 4512 07402 1106 TAD ZMSPACE ; see if this is a control character 4513 07403 7500 SMA ; skip if it is a control code 4514 07404 5226 JMP OUTCH3 ; just type a normal character 4515 4516 ; Here to type a TAB character... 4517 07405 1377 TAD [" "-CHTAB] ; is this really a TAB character at all ?? 4518 07406 7440 SZA ; ??? 4519 07407 5211 JMP OUTCH1 ; no -- check further 4520 07410 5776 JMP @[TTABC] ; yes -- type a TAB and return 4521 4522 ; Here to print an ESCAPE character... 4523 07411 1375 OUTCH1: TAD [CHTAB-CHESC] ; is this an ESCAPE character ?? 4524 07412 7440 SZA ; ??? 4525 07413 5216 JMP OUTCH2 ; no -- go type the ^x form instead 4526 07414 1374 TAD ["$"] ; yes -- type a dollar sign for an ESCAPE 4527 07415 5227 JMP THCHAR ; then type it and return 4528 4529 ; Here to print a control character... 4530 07416 6215 OUTCH2: .PUSH ; save the character for a while 4531 07417 7200 CLA ; and get the flag character 4532 07420 1373 TAD ["^"] ; ... 4533 07421 6205 .PUSHJ TFCHAR ; type that first 07422 5244 4534 07423 6235 .POP ; then get the character back 4535 07424 1372 TAD [CHESC+"@"] ; convert it to a printing character 4536 07425 5227 JMP THCHAR ; type that and return 4537 4538 ; Here to print a normal character... 4539 07426 1371 OUTCH3: TAD [" "] ; restore the original character 4540 ; and fall into THCHAR 4541 4542 4543 ; This routine will type a printing character and, while doing this, it will 4544 ; keep track of the horizontal position of the cursor. If it passes the line 4545 ; length of the terminal, a free carriage return is also typed. The terminal's 4546 ; horizontal position (HPOS) is also used for the tab simulation. The 4547 ; character to be typed should be in the AC, the AC will be cleared on return. 4548 07427 6215 THCHAR: .PUSH ; save the character for a while 4549 07430 2036 ISZ HPOS ; and incrment the horizontal position 4550 07431 7200 CLA ; get the maximum width allowed 4551 07432 1040 TAD WIDTH ; ... 4552 07433 7450 SNA ; is it zero ?? 4553 07434 5243 JMP THCHA1 ; yes -- no automatic carriage returns, then 4554 07435 7041 CMA CIA ; make it negative 4555 07436 1036 TAD HPOS ; and compare to the terminal cursor position 4556 07437 7710 SPA CLA ; have we reached the end of the line ?? 4557 07440 5243 JMP THCHA1 ; no -- proceed normally 4558 07441 6205 .PUSHJ @ZCRLF ; yes -- force a carriage return first 07442 5461 4559 07443 6235 THCHA1: .POP ; then get the character back 4560 ; and fall into TFCHAR PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 113 Terminal Output Primitives BTS6120.PLX 4561 4562 4563 ; This routine will type a single character from the AC on the terminal. 4564 ; Before it types the character, this routine will check the state of the 4565 ; CNTRLO and XOFF flags. If a Control-O has been typed, the character is 4566 ; discarded and not typed on the terminal. If an XOFF has been typed, the 4567 ; output will be suspended until the user types an XON character (or a 4568 ; Control-O or Control-C). 4569 07444 6215 TFCHAR: .PUSH ; save the character for a while 4570 07445 6205 TFCHA1: .PUSHJ INCHRS ; check the operator for input 07446 5277 4571 07447 7200 CLA ; we don't care if anything was typed 4572 07450 1034 TAD CTRLO ; get the Control-O flag byte 4573 07451 7640 SZA CLA ; is it zero ?? 4574 07452 5260 JMP TFCHA2 ; no -- just throw this character away 4575 07453 1035 TAD XOFF ; now test the XOFF flag 4576 07454 7640 SZA CLA ; is the output suspended ?? 4577 07455 5245 JMP TFCHA1 ; wait for something to happen if we are XOFFed 4578 4579 ; Here when it is OK to type the character... 4580 07456 6235 .POP ; get the character back 4581 07457 5263 JMP CONOUT ; and send it to the UART 4582 4583 ; Here to return without typing anything... 4584 07460 6235 TFCHA2: .POP ; clean up the stack 4585 07461 7200 CLA ; but always return zero 4586 07462 6225 .POPJ ; and just quit 4587 4588 ; This routine will output a character from the AC to the terminal, with no 4589 ; no special processing of any kind. It simply waits for the console flag to 4590 ; set and then send the character. However, If the flag does not set in a 4591 ; reasonable amount of time then this routine will force the character out 4592 ; anyway. This prevents the monitor from hanging if the terminal flag is 4593 ; cleared by the user's program. 4594 ; 4595 ; The timeout loop requires 26 minor cycles which, with a 4.9152Mhz clock, 4596 ; takes 10.5 microseconds. If we simply clear the timeout counter when we 4597 ; start we'll get a timeout after 4096 counts, or about 43 milliseconds. 4598 ; If we assume that 300 baud is the slowest console we'll ever use, then 4599 ; that's just about right (at 300 baud a character takes about 33 milliseconds 4600 ; to transmit!). 4601 ; 4602 07463 3276 CONOUT: DCA CONCHR ; remember the character to send 4603 07464 3042 DCA IRMA ; and clear the timeout timer 4604 4605 ; See if the flag is set and send the character if so... 4606 07465 6041 CONOU1: TSF ; [9] is the flag set ??? 4607 07466 5273 JMP CONOU3 ; [4] no -- go check the timeout 4608 07467 1276 CONOU2: TAD CONCHR ; yes -- get the character 4609 07470 6046 TLS ; and send it to the console 4610 07471 7200 CLA ; a _real_ TLS doesn't clear the AC!! 4611 07472 6225 .POPJ ; ... 4612 4613 ; Here if the flag is not yet set... 4614 07473 2042 CONOU3: ISZ IRMA ; [9] have we waited long enough ??? 4615 07474 5265 JMP CONOU1 ; [4] no -- wait a little longer 4616 07475 5267 JMP CONOU2 ; yes -- force the character out anyway 4617 4618 ; Temporary storage for the CONOUT routine... 4619 07476 CONCHR: .BLOCK 1 ; a place to save the console character PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 114 Terminal Input Primitives BTS6120.PLX 4620 .TITLE Terminal Input Primitives 4621 4622 4623 ; This routine is called to check for operator input. It will test to see 4624 ; if the operator has typed a character. If he has not, this routine returns 4625 ; with the AC cleared and nothing else happens. If he has, this routine checks 4626 ; to see if the character is one of Control-C, Control-O, Control-S or 4627 ; Control-Q because these characters have special meaning and are acted upon 4628 ; immediately. If the input character is anything else, the character is 4629 ; returned in the AC. 4630 07477 6205 INCHRS: .PUSHJ CONIN ; try to read a character from the terminal 07500 5350 4631 07501 0103 AND ZK177 ; ignore the parity bit here 4632 07502 7450 SNA ; is this a null character ?? 4633 07503 6225 .POPJ ; yes -- just ignore it 4634 4635 ; Here process a control-C character -- restart the monitor... 4636 07504 1370 TAD [-CHCTC] ; is this really a control-C ?? 4637 07505 7440 SZA ; ??? 4638 07506 5315 JMP INCHR1 ; no -- proceed 4639 07507 3034 DCA CTRLO ; yes -- clear the control-O 4640 07510 3035 DCA XOFF ; and XOFF flags 4641 07511 1367 TAD [CHCTC] ; get another control-C character 4642 07512 6205 .PUSHJ @ZOUTCHR ; echo it to the terminal 07513 5454 4643 07514 5477 JMP @ZRESTA ; and go restart the monitor 4644 4645 ; Here to check for a control-O character... 4646 07515 1366 INCHR1: TAD [CHCTC-CHCTO] ; compare to a control-O character 4647 07516 7440 SZA ; is this it ?? 4648 07517 5332 JMP INCHR2 ; no -- keep checking 4649 07520 3035 DCA XOFF ; control-O always clears the XOFF flag 4650 07521 1365 TAD [CHCTO] ; get another control-O character 4651 07522 6205 .PUSHJ @ZOUTCHR ; and echo that 07523 5454 4652 07524 6205 .PUSHJ @ZCRLF ; then close the line 07525 5461 4653 07526 1034 TAD CTRLO ; get the current state of the control-O flag 4654 07527 7040 CMA ; and complement it 4655 07530 3034 DCA CTRLO ; that's the new value 4656 07531 6225 .POPJ ; return with the AC cleared 4657 4658 ; Here to check for a control-S character... 4659 07532 1364 INCHR2: TAD [CHCTO-CHXOF] ; is this a control-S ?? 4660 07533 7440 SZA ; ??? 4661 07534 5340 JMP INCHR3 ; nope, try again 4662 07535 7240 STA ; yes -- get a -1 into the AC 4663 07536 3035 DCA XOFF ; and set the XOFF flag 4664 07537 6225 .POPJ ; return with the AC cleared 4665 4666 ; Here to check for a control-Q character... 4667 07540 1363 INCHR3: TAD [CHXOF-CHXON] ; is this a control-Q ?? 4668 07541 7440 SZA ; ??? 4669 07542 5346 JMP INCHR4 ; no -- just give up 4670 07543 3035 DCA XOFF ; yes -- clear the XOFF flag 4671 07544 3037 DCA VPOS ; also clear the automatic XOFF counter 4672 07545 6225 .POPJ ; return with the AC cleared 4673 4674 ; Here if the character is nothing special... 4675 07546 1362 INCHR4: TAD [CHXON] ; restore the state of the AC 4676 07547 6225 .POPJ ; and return the character in the AC 4677 4678 4679 ; This routine will read a single character from the console UART. If no 4680 ; character is currently ready, it will return a null (zero) byte in the AC, PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 115 Terminal Input Primitives BTS6120.PLX 4681 ; but otherwise the character read is left in the AC... 4682 07550 7200 CONIN: CLA ; be sure the AC is cleared 4683 07551 6031 KSF ; is a character ready ?? 4684 07552 6225 .POPJ ; no -- just return zero 4685 07553 6036 KRB ; yes -- read it into the AC 4686 07554 6225 .POPJ ; then return that in the AC 4687 07562 0021 07563 0002 07564 7774 07565 0017 07566 7764 07567 0003 07570 7775 07571 0040 07572 0133 07573 0136 07574 0044 07575 7756 07576 7054 07577 0027 4688 07600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 116 Control Panel Entry Points BTS6120.PLX 4689 .TITLE Control Panel Entry Points 4690 4691 07600 .ORG 7600 4692 4693 ; There's a little bit of chicanery that goes on here (when have you seen 4694 ; a PDP-8 program without that???). After a power on clear or a hard reset, 4695 ; the HM6120 starts executing at location 7777 of panel memory which, in 4696 ; the case of the SBC6120, is part of the EPROM. The EPROM code at this 4697 ; location always jumps to the system initialization routine without even 4698 ; trying to figure out why we entered panel mode. 4699 ; 4700 ; The system initialization code copies all of the EPROM contents to panel 4701 ; RAM and then disables the EPROM forever. After that it actually changes 4702 ; the vector at location 7777 to point to the CPSAVE routine, which is the 4703 ; normal panel entry point for traps, halts, etc. 4704 7600 .VECTOR CPBOOT ; set the 6120 start up vector at 7777 4705 07600 6213 CPBOOT: CXF 1 ; the startup code lives in field 1 4706 07601 5776 JMP @[SYSINI] ; and away we go! 4707 4708 4709 ; Excluding a hardware reset, the 6120 will enter control panel mode for any 4710 ; of three other reasons: 4711 ; 4712 ; * any of the PR0..PR3 instructions were executed in main memory 4713 ; * the CPU was halted, either by a HLT instruction or by the RUN/HLT input 4714 ; * a panel interrupt was requested by the CPREQ pin 4715 ; 4716 ; In all the these cases, the 6120 was presumably executing some important 4717 ; program in main memory before it was interrupted, and we need to save the 4718 ; state of that program before doing anything else. When the 6120 enters 4719 ; panel mode it saves the last main memory PC in panel memory location 0 and 4720 ; then starts executing instructions in panel memory at 7777. The remainder of 4721 ; the main memory context (e.g. AC, MQ, flags, etc) we have to save manually. 4722 07602 3001 CPSAVE: DCA UAC ; save the AC 4723 07603 6256 GCF ; and the flags (including LINK, IF and DF) 4724 07604 3002 DCA UFLAGS ; ... 4725 07605 7501 MQA ; the MQ 4726 07606 3003 DCA UMQ ; ... 4727 07607 6207 RSP1 ; 6120 stack pointer #1 4728 07610 3004 DCA USP1 ; ... 4729 07611 6227 RSP2 ; " " " #2 4730 07612 3005 DCA USP2 ; .. 4731 4732 ; Now set up enough context so that this monitor can run. The CONT routine 4733 ; has saved in location STKSAV our last stack pointer before the main memory 4734 ; program was started and, if we're single stepping the main memory program, 4735 ; we're going to need that so that we can continue what we were doing. In 4736 ; the case of other traps the RESTA routine gets called which will reset the 4737 ; stack pointer. 4738 07613 1113 TAD STKSAV ; get the monitor's last known stack pointer 4739 07614 6217 LSP1 ; and restore that 4740 07615 6203 CXF 0 ; set both DF and IF to field zero 4741 07616 6276 SPD ; make indirect cycles access panel memory 4742 07617 3037 DCA VPOS ; reset the automatic XOFF line counter 4743 07620 6441 POST+1 ; show post code #1 4744 4745 ; Finally, we can determine the exact reason for entry into panel mode by 4746 ; reading the panel status flags with the PRS instruction, and that will tell 4747 ; us where to go next. Be careful, though, because executing PRS clears the 4748 ; flags so we only get to do it once! This code kind of assumes that only one 4749 ; of these flags can be set at any time - I believe that's true for the 6120. 4750 07621 6000 PRS ; get the reason for panel entry 4751 07622 7004 RAL ; check the BTSTRP flag first 4752 07623 7430 SZL ; ... this is set by an external CPREQ 4753 07624 5240 JMP BTSTRP ; yes PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 117 Control Panel Entry Points BTS6120.PLX 4754 07625 7004 RAL ; the next flag is PNLTRP 4755 07626 7430 SZL ; ... which is set by the PRn instructions 4756 07627 5242 JMP PNLTRP ; ... 4757 07630 7006 RTL ; next is PWRON (it skips a bit!) 4758 07631 7430 SZL ; ... which is only set by a hard reset 4759 07632 5236 JMP PWRON ; ... 4760 07633 7004 RAL ; and lastly is the HLTFLG 4761 07634 7430 SZL ; ... which is set any time the CPU halts 4762 07635 5276 JMP HALTED ; ... 4763 4764 ; If we get here, none of the known panel status bits are set. I don't 4765 ; know what this means, but it can't be good! We also jump here if the 4766 ; PWRON status bit is set. Since this bit can only be set by a hardware 4767 ; reset, and since in the SBC6120 this automatically maps EPROM instead 4768 ; of RAM, we should never see this happen. 4769 07636 4304 PWRON: JMS TRAP ; print a generic 4770 07637 4004 TRPMSG ; "% UNKNOWN TRAP AT ..." message 4771 4772 ; The BTSTRP flag indicates a transition of the CPREQ line. In the 4773 ; SBC6120 this is conected to the console UART framing error output, so 4774 ; entering a BREAK on the terminal causes a console trap. In other hardware 4775 ; this might also be used to trap various IOT instructions and emulate them, 4776 ; but not in the SBC6120... 4777 07640 4304 BTSTRP: JMS TRAP ; print 4778 07641 3750 BRKMSG ; "% BREAK AT ..." and restart 4779 4780 ; The PNLTRP flag indicates that one of the PR0 thru PR3 instructions has 4781 ; been executed, but unfortunately the only way to find out which is to 4782 ; use the last main memory PC to fetch the instruction from memory. Remember 4783 ; that the 6120 will have already incremented the PC by the time we get here, 4784 ; so it's actually one _more_ than the location we want. Currently the PR3 4785 ; instruction is used as a breakpoint trap and PR0 is a generic ROM "monitor 4786 ; call". The other two, PR1 and PR2, are unused. 4787 07642 7240 PNLTRP: STA ; decrement the PC 4788 07643 1000 TAD UPC ; so it points at the actual instruction 4789 07644 3000 DCA UPC ; that caused the trap 4790 07645 1002 TAD UFLAGS ; get the IF at the time of the trap 4791 07646 0104 AND ZK70 ; ... 4792 07647 1256 TAD PNLCDF ; make a CDF instruction out of that 4793 07650 3251 DCA .+1 ; and execute it 4794 07651 7000 NOP ; ... gets overwritten with a CDF ... 4795 07652 6266 CPD ; address main memory with indirect cycles 4796 07653 1400 TAD @UPC ; get the opcode that caused the trap 4797 07654 3006 DCA UIR ; and save it for later 4798 07655 6276 SPD ; back to panel memory 4799 07656 6201 PNLCDF: CDF 0 ; always field zero 4800 4801 ; See which instruction it was... 4802 07657 1006 TAD UIR ; get the opcode 4803 07660 1375 TAD [-BPT] ; is it PR3 ?? 4804 07661 7450 SNA ; ??? 4805 07662 5272 JMP BPTTRP ; yes - handle a break point trap 4806 07663 1374 TAD [BPT-PR0] ; no - is it PR0? 4807 07664 6213 CXF 1 ; (the ROM call handler lives in field 1) 4808 07665 7450 SNA ; ??? 4809 07666 5773 JMP @[MCALL] ; yes - handle a monitor call 4810 07667 6203 CXF 0 ; ... 4811 07670 4304 JMS TRAP ; for any others just print a generic 4812 07671 3760 PRNMSG ; "% PANEL TRAP AT ..." message 4813 4814 ; Here for a breakpoint trap... 4815 07672 4304 BPTTRP: JMS TRAP ; print 4816 07673 3713 BPTMSG ; "% BREAKPOINT AT ..." and proceed 4817 4818 ; Here (from field 1) for an illegal PR0 call... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 118 Control Panel Entry Points BTS6120.PLX 4819 07674 4304 ILLPR0: JMS TRAP ; say 4820 07675 3726 PR0MSG ; "? ILLEGAL PR0 FUNCTION AT ..." 4821 4822 ; We get here when the 6120 halts, but unfortunately there are no less than 4823 ; three different reasons why it night have done this. The first is that the 4824 ; main memory program has executed a HLT (7402, or any microcoded combination 4825 ; there of) instruction. Or, it could be that the 6120 was halted externally 4826 ; by a transition on the HLTREQ input pin, however the SBC6120 has no hardware 4827 ; to do this. Lastly, it could be that the HALT flag was already set when 4828 ; we restarted the main memory program - in this case the 6120 will execute 4829 ; one instruction and trap back here. 4830 ; 4831 ; We use this situation intentionally to single step main memory programs, 4832 ; and we can tell when this happens by checking the SIMFLG flag in memory. 4833 ; This flag is normally cleared, but will be set by the SINGLE routine when we 4834 ; want to single step. In that case the monitor's stack is valid (it was 4835 ; saved to STKSAV by the CONT routine before switching context) and all we 4836 ; have to do is execute a .POPJ to return to the routine that originally 4837 ; called SINGLE. Keep your fingers crossed. 4838 07676 7200 HALTED: CLA ; ... 4839 07677 1032 TAD SIMFLG ; did we execute a single instruction? 4840 07700 7640 SZA CLA ; ??? 4841 07701 6225 .POPJ ; yes - return from the SINGLE routine now! 4842 07702 4304 JMS TRAP ; otherwise just say 4843 07703 3773 HLTMSG ; "% HALTED AT ..." and restart 4844 4845 ; This routine does most of the generic work of handling traps to panel 4846 ; memory. It prints a message, which is passed inline via a JMS instruction, 4847 ; prints the PC, removes any breakpoints from the program and then restarts 4848 ; the monitor... 4849 07704 0000 TRAP: 0 ; call here with a JMS instruction 4850 07705 6205 .PUSHJ @ZCRLF ; be sure we start on a new line 07706 5461 4851 07707 1704 TAD @TRAP ; get the address of the message 4852 07710 6205 .PUSHJ @[OUTSTR] ; and print that 07711 5772 4853 07712 1002 TAD UFLAGS ; then get the field of the trap 4854 07713 0104 AND ZK70 ; ... 4855 07714 6205 .PUSHJ @[TFIELD] ; and type that 07715 5771 4856 07716 1000 TAD UPC ; then the PC too 4857 07717 6205 .PUSHJ @ZTOCT4C ; type that and a CRLF 07720 5457 4858 07721 6205 .PUSHJ @[REGLSC] ; type the registers on the next line 07722 5770 4859 07723 6205 .PUSHJ @[BPTRMV] ; remove any breakpoints 07724 5767 4860 07725 5477 JMP @ZRESTA ; and restart the monitor 4861 07767 2123 07770 1240 07771 6412 07772 6200 07773 0201 07774 0030 07775 1542 07776 0001 07777 5200 4862 10200 .FIELD 1 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 119 Field 1 Variables BTS6120.PLX 4863 .TITLE Field 1 Variables 4864 4865 4866 ; This page defines all the page zero variables used by the code in field 4867 ; one. The system initialization code, part 1, at SYSINI: also lives in page 4868 ; zero of field one, and then is overwritten by these variables after init- 4869 ; ialization is completed. As a consequence, none of these variables can 4870 ; have initial values the way their field zero counter parts do! 4871 4872 10000 .ORG 0000 4873 4874 ; Auto index registers... 4875 10010 .ORG 0010 4876 10010 RAMPTR: .BLOCK 1 ; address, within the RAM disk, for I/O 4877 10011 BUFPTR: .BLOCK 1 ; address of the caller's buffer for I/O 4878 10012 XX1: .BLOCK 1 ; generic auto index register for field 1 4879 10013 XX2: .BLOCK 1 ; " " " " " " 4880 10020 .ORG 0020 4881 4882 ; RAM Disk I/O routine storage... 4883 10020 RDUNIT: .BLOCK 1 ; currently selected RAM disk unit for I/O 4884 10021 RDPAGE: .BLOCK 1 ; " " " " " " page number 4885 10022 RAMBUF: .BLOCK 3 ; a three byte "mini buffer" for 3 <-> 2 packing 4886 10025 RAMDAR: .BLOCK 1 ; RAM disk address register (written to LDAR) 4887 10026 BATTOK: .BLOCK 1 ; -1 if RAM backup battery is good 4888 10027 RDSIZE: .BLOCK 4 ; size of each RAM disk unit, in KB, or 0 if none 4889 10033 RAMSIZ: .BLOCK 1 ; total size of all RAM disks, in KB 4890 10034 SIZPTR: .BLOCK 1 ; pointer to the RDSIZE array 4891 10035 RAMUSZ: .BLOCK 1 ; - size of selected RAM disk chip 4892 4893 4894 ; IDE Disk I/O routine storage... 4895 10036 DKPART: .BLOCK 1 ; 12 bit disk partition number 4896 10037 DKRBN: .BLOCK 1 ; 12 bit sector relative block number 4897 10040 DKSIZE: .BLOCK 1 ; size of attached drive, in MB, or 0 if no drive 4898 10041 DKUNIT: .BLOCK 1 ; logical unit (partition) number for OS/8 4899 10042 PARMAP: .BLOCk 10 ; unit number to partition map for eight OS/8 units 4900 4901 ; ROM call arguments 4902 10052 MUUO: .BLOCK 1 ; ROM MCALL function code 4903 10053 ARGPTR: .BLOCK 1 ; pointer to MCALL (PR0) argument list 4904 10054 XFRCNT: .BLOCK 1 ; word count for I/O 4905 10055 BUFPNL: .BLOCK 1 ; -1 if the user buffer is in panel memory 4906 10056 BUFSIZ: .BLOCK 1 ; actual buffer size for RDIBUF/WRIBUF 4907 10057 RWCNT: .BLOCK 1 ; number of pages to be transferred 4908 4909 10200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 120 ROM Calls (PR0 Instructions) BTS6120.PLX 4910 .TITLE ROM Calls (PR0 Instructions) 4911 4912 10200 .ORG 0200 4913 4914 ; The PDP2HEX program (which converts BIN files into ROM images in Intel 4915 ; HEX format) stores a checksum of ROM field 1 in location 10200. This is 4916 ; used by the POST and the VE (version) command. 4917 10200 ROMCK1: .BLOCK 1 4918 4919 ; This routine is called by CPSAVE when it detects a panel entry caused by 4920 ; a PR0 instruction. Main memory programs can use this instruction to 4921 ; communicate with the ROM firmware and, in particular, the OS/8 device driver 4922 ; for the RAM disk uses PR0 to transfer data. At this point all of the main 4923 ; memory program's registers have been saved and our original monitor stack 4924 ; has been restored. The data and instruction field are both one and the 4925 ; 6120 panel data flag is set (so indirect references go to panel memory). 4926 ; That's about all we can depend on. 4927 ; 4928 ; There are a couple of subtle points to watch out for here. One simple 4929 ; one is that, to save time, break points are not removed from the caller's 4930 ; program while we interpret a PR0. That means we have to be sure and return 4931 ; to main memory by jumping to CONT1, not CONT, since the latter will attempt 4932 ; to reinstall breakpoints _again_ and forever loose the original contents 4933 ; of those locations. 4934 ; 4935 ; The other thing to remember is that CONT and CPSAVE conspire to preserve 4936 ; the monitor's stack, so that it can return to the correct place while single 4937 ; stepping. That means we want to be sure and JMP to CONT1, not .PUSHJ to it, 4938 ; because otherwise it'll just return back to us the next time we enter panel 4939 ; mode! 4940 ; 4941 ; The convention is that the first word after PR0 is a function code to 4942 ; select the firmware routine. This routine also preserves the contents of 4943 ; the AC both ways - that is, whatever was in the user's AC when the PR0 was 4944 ; executed will be in the AC when our monitor call function is invoked, and 4945 ; whatever our monitor call function returns in the AC will be placed in the 4946 ; user's AC when control returns from the PR0. Anything more than that is up 4947 ; to the specific function invoked. 4948 4949 ; Get the first agument (the function code) and use it to determine the 4950 ; address of a ROM routine to handle it... 4951 10201 6205 MCALL: .PUSHJ GETARG ; CPSAVE leaves the PC pointing at the PR0 10202 5241 4952 ; so do a dummy GETARG to skip it 4953 10203 6205 .PUSHJ GETARG ; then get a real PR0 argument from main memory 10204 5241 4954 10205 3052 DCA MUUO ; this is always the function code 4955 10206 1052 TAD MUUO ; see if it's in range 4956 10207 7100 CLL ; be sure the link is in a known state 4957 10210 1377 TAD [-MAXFUN-1] ; check against the maximum function 4958 10211 7630 SZL CLA ; if it's legal, skip 4959 10212 5237 JMP MCALL2 ; nope - go print an error message... 4960 10213 1052 TAD MUUO ; it's legal - use it 4961 10214 1376 TAD [FUNTBL] ; index into the function dispatch table 4962 10215 3052 DCA MUUO ; ... 4963 10216 1452 TAD @MUUO ; get the address of the function routine 4964 10217 3052 DCA MUUO ; finally - that's what we wanted to know! 4965 4966 ; Invoke the monitor routine, preserving the AC in both directions. In 4967 ; addition, the LINK bit is commonly used as an error flag (i.e. the LINK 4968 ; set on return indicates an error), so it is preserved on return only. 4969 10220 6201 CDF 0 ; the user's context lives in field 0 4970 10221 1775 TAD @[UAC] ; get the user's AC 4971 10222 6211 CDF 1 ; all ROM call routines live in field 1 4972 10223 6205 .PUSHJ @MUUO ; call routine to execute the ROM call PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 121 ROM Calls (PR0 Instructions) BTS6120.PLX 10224 5452 4973 10225 6201 MCALL1: CDF 0 ; address the user's context again 4974 10226 3775 DCA @[UAC] ; return whatever's in the AC 4975 10227 7010 RAR ; put the link bit in AC0 4976 10230 3052 DCA MUUO ; save it for a minute 4977 10231 7350 NL3777 ; then mask off the LINK bit 4978 10232 0774 AND @[UFLAGS] ; in the user's flags 4979 10233 1052 TAD MUUO ; and put ours in there instead 4980 10234 3774 DCA @[UFLAGS] ; ... 4981 10235 6203 CXF 0 ; CONT1 lives in field 1 4982 10236 5773 JMP @[CONT1] ; and then return to main memory 4983 4984 ; Here when an illegal PR0 function is invoked. 4985 10237 6203 MCALL2: CXF 0 ; say 4986 10240 5772 JMP @[ILLPR0] ; "?Illegal PR0 function at ..." PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 122 Fetch PR0 Arguments BTS6120.PLX 4987 .TITLE Fetch PR0 Arguments 4988 4989 4990 ; This routine fetches an argument for PR0 from the main memory program. 4991 ; Since arguments are always stored in line after the PR0, the next argument 4992 ; is in the instruction field and pointed to by the last main memory PC. 4993 ; After the argument is fetched the main memory PC is always incremented so 4994 ; that we'll skip over the argument when we return - you have to be careful 4995 ; about this, since it means this routine can only be called ONCE to fetch 4996 ; any given argument! The PR0 argument is returned in the AC. 4997 10241 7200 GETARG: CLA ; just in case 4998 10242 6201 CDF 0 ; BEWARE - UFLAGS and UPC are both in field 0! 4999 10243 1771 TAD @[UPC] ; get the user's PC from field 0 5000 10244 3053 DCA ARGPTR ; save it in field 1 for a moment 5001 10245 2771 ISZ @[UPC] ; and increment it to skip over the argument 5002 10246 7000 NOP ; this really shouldn't ever happen! 5003 10247 1774 TAD @[UFLAGS] ; get the last known user (main memory) flags 5004 10250 0370 AND [70] ; then get the IF at the time of the trap 5005 10251 1367 TAD [CDF 0] ; make a CDF instruction 5006 10252 3253 DCA .+1 ; change to the correct field 5007 10253 7000 NOP ; ... gets overwritten with a CDF ... 5008 10254 6266 CPD ; always fetch from main memory 5009 10255 1453 TAD @ARGPTR ; get the next word from user program space 5010 10256 6276 SPD ; back to panel memory 5011 10257 6211 CDF 1 ; and back to our field 5012 10260 6225 .POPJ ; return the PR0 argument in the AC PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 123 ROM Call Table BTS6120.PLX 5013 .TITLE ROM Call Table 5014 5015 5016 ; This is what you've really been waiting for - the table of ROM firmware 5017 ; function codes and routine addresses. 5018 10261 0272 FUNTBL: GETVER ; 0 - get ROM version 5019 10262 0277 RAMDRW ; 1 - read/write RAM disk 5020 10263 1000 GETRDS ; 2 - return RAM disk size 5021 10264 0552 GETBAT ; 3 - return RAM disk battery status 5022 10265 1634 DISKRW ; 4 - read/write IDE disk 5023 10266 1123 GETDKS ; 5 - return IDE disk size 5024 10267 1600 SETPMP ; 6 - set disk partition mapping 5025 10270 1617 GETPMP ; 7 - get disk partition mapping 5026 10271 2044 MEMMOV ; 10 - copy memory 5027 0010 MAXFUN=.-FUNTBL-1 5028 5029 5030 ; PR0 function zero returns the current firmware version in the AC... 5031 10272 7300 GETVER: CLA CLL ; ... 5032 10273 1366 TAD [VERSION] ; get our version number 5033 10274 6225 .POPJ ; MCALL will store it in the caller's AC PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 124 ROM Call Table BTS6120.PLX 5034 5035 .TITLE Return from Routines in Field 1 5036 5037 5038 ; This routine is the other half of the code at PUSHJ1:, and it allows 5039 ; routines in field one which were called from field zero to return to 5040 ; field zero. It only needs to do two instructions, but those instructions 5041 ; have to be somewhere in field one! 5042 10275 6203 POPJ1: CXF 0 ; return to field zero 5043 10276 6225 .POPJ ; the address is already on the stack PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 125 RAM Disk support BTS6120.PLX 5044 .TITLE RAM Disk support 5045 5046 5047 ; The SBC6120 contains a DS1221 SRAM controller with Li battery backup and 5048 ; sockets for up to four byte wide SRAM chips. Each socket can contain either 5049 ; a HM628512 512Kx8 SRAM or a HM628128 128Kx8 SRAM or, of course, nothing. 5050 ; Additionally, the last socket has two jumpers which permit a 512K byte 5051 ; CMOS EPROM to be used if desired. The maximum capacity of the RAM disk 5052 ; array is thus 2Mb - a pretty respectable sized disk (almost as big as a 5053 ; RK05J!) for OS/8. 5054 ; 5055 ; The SBC6120 maps these RAM chips into panel memory via the memory decode 5056 ; GAL and, when memory map 3 (MM3) is enabled, all indirect references to panel 5057 ; memory will access the RAM disk array. Since the RAM disk is only a byte 5058 ; wide, write operations discard the upper four bits of a twelve bit word, and 5059 ; when reading these bits are undefined and should be masked off by the 5060 ; software. 5061 ; 5062 ; Addressing the RAM disk is a little tricky, since a 2Mb memory requires 5063 ; a total of 21 address bits - quite a bit more than a PDP-8 can manage. 5064 ; RAM disk address bits 0..11 (the low order bits, contrary to the PDP-8 5065 ; convention) are supplied by the HM6120 MA11-0. The remaining 7 bits needed 5066 ; by each 512K SRAM come from a special register, the Disk Address Register, 5067 ; which can be loaded via the LDAR IOT. The final two bits needed by the 5068 ; DS1221 to select one of the four SRAM chips come from DF0 and DF1 (DF2 is 5069 ; not used at the moment). 5070 ; 5071 ; Put more simply, the DF selects the SRAM chip used, the DAR selects the 5072 ; 4K byte "bank" within the chip, and the normal memory address selects the 5073 ; individual byte within the bank. 5074 ; 5075 ; For the purposes of writing an OS/8 device handler, each 4K RAM disk bank 5076 ; contains 21 pages of 128 twelve bit words, packed using the standard OS/8 5077 ; "three for two" scheme. A 512K SRAM chip can hold 128 of these banks, 5078 ; corresponding to DAR addresses 0..127, for a total capacity of 2688 PDP-8 5079 ; pages or 1344 OS/8 blocks. A 128K SRAM would contain only 32 banks, for a 5080 ; total of 672 PDP-8 pages or 336 OS/8 blocks. 5081 ; 5082 ; Sixty-four bytes are wasted in each bank by this packing scheme, which 5083 ; works out to about 21 OS/8 blocks lost in a 512K SRAM. More clever software 5084 ; could reclaim these, but it would require that the three-for-two packing 5085 ; algorithm split PDP-8 pages across RAM disk banks. 5086 ; 5087 ; The SRAMs are optional, and this SBC6120 may have all, only some, or even 5088 ; none installed. Since each SRAM chip is treated as a separate OS/8 unit, 5089 ; this makes it easy to handle the situation where some chips are not missing - 5090 ; these units are simply "off line". 5091 5092 ; RAM disk "geometry" constants... 5093 5200 RAM512=2688. ; size of a 512K RAM disk, in pages 5094 1240 RAM128=672. ; " " " 128K " " " " 5095 0025 BANKSZ=21. ; pages per bank of RAM disk memory 5096 5097 ; Special IOTs for the RAM disk hardware... 5098 6410 LDAR=6410 ; Load RAM disk address register PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 126 RAM Disk Read/Write ROM Call BTS6120.PLX 5099 .TITLE RAM Disk Read/Write ROM Call 5100 5101 5102 ; The calling sequence for the PR0 RAM disk R/W function is: 5103 ; 5104 ; PR0 5105 ; 0001 / panel function code for RAMDISK I/O 5106 ; / R/W bit, page count, buffer field and unit 5107 ; / buffer address 5108 ; / starting page number (not block number!) 5109 ; / AC == 0 if success; AC != 0 if error 5110 ; 5111 ; The error codes currently returned by RAMDRW are: 5112 ; 5113 ; 0001 - unit > 3 or SRAM chip not installed 5114 ; 0002 - page number > 2688 5115 ; 5116 ; If this looks a lot like an OS/8 handler call, that's no accident! 5117 10277 6205 RAMDRW: .PUSHJ @[SETBUF] ; set up MUUO, BUFPTR, BUFCDF and RWCNT 10300 5765 5118 10301 6205 .PUSHJ GETARG ; and lastly get the disk page number 10302 5241 5119 10303 3021 DCA RDPAGE ; ... 5120 5121 ; Select (after first ensuring that it exists!) the correct unit... 5122 10304 1052 TAD MUUO ; next get the unit number 5123 10305 0364 AND [7] ; ... 5124 10306 3020 DCA RDUNIT ; ... 5125 10307 6205 .PUSHJ @[RAMSEL] ; setup RAMCDF to select the correct "unit" 10310 5763 5126 10311 7630 SZL CLA ; was the unit number illegal ? 5127 10312 5762 JMP @[RAMER1] ; yes - give the error return 5128 5129 ; This loop reads or writes pages 'till we've done all we're supposed to... 5130 10313 6205 RDRW1: .PUSHJ @[SETDAR] ; calculate the RAM disk address and bank 10314 5761 5131 10315 7630 SZL CLA ; was the page number valid? 5132 10316 5760 JMP @[RAMER2] ; nope - give the bad page error return 5133 10317 1052 TAD MUUO ; get the function code again 5134 10320 7700 SMA CLA ; should we read (0) or write (1) ? 5135 10321 5325 JMP RDRW2 ; ... read 5136 10322 6205 .PUSHJ @[PACK] ; transfer a page from memory to RAM disk 10323 5757 5137 10324 5327 JMP RDRW3 ; and continue 5138 10325 6205 RDRW2: .PUSHJ @[UNPACK] ; transfer a page from RAM disk to memory 10326 5756 5139 10327 2021 RDRW3: ISZ RDPAGE ; if we need more, continue on the next page 5140 10330 2057 ISZ RWCNT ; have we done enough pages? 5141 10331 5313 JMP RDRW1 ; nope - keep going 5142 10332 7200 CLA ; all done with the RAMDRW call 5143 10333 6225 .POPJ ; return status code zero (no error) PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 127 RAM Disk Primary Bootstrap BTS6120.PLX 5144 .TITLE RAM Disk Primary Bootstrap 5145 5146 5147 ; This routine will read page zero from RAM disk unit zero into page 5148 ; zero of field zero of main memory. The next step in the usual boot 5149 ; sequence would be to start the secondary bootstrap, but that's up to 5150 ; the caller... 5151 10334 7240 RDBOOT: STA ; point the buffer to page 0 5152 10335 3011 DCA BUFPTR ; ... 5153 10336 1367 TAD [CDF 0] ; of field zero 5154 10337 3755 DCA @[BUFCDF+1] ; ... 5155 10340 3055 DCA BUFPNL ; of main memory 5156 10341 3020 DCA RDUNIT ; read RAM disk unit zero 5157 10342 3021 DCA RDPAGE ; page zero 5158 10343 5754 JMP @[RAMDRD] ; ... 5159 10354 0400 10355 2036 10356 0427 10357 0471 10360 0424 10361 0600 10362 0422 10363 0635 10364 0007 10365 2000 10366 0215 10367 6201 10370 0070 10371 0000 10372 7674 10373 2222 10374 0002 10375 0001 10376 0261 10377 7767 5160 10400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 128 Read and Write RAM Disk Pages BTS6120.PLX 5161 .TITLE Read and Write RAM Disk Pages 5162 5163 5164 ; This routine will read a single page from RAM disk to a buffer in memory. 5165 ; The caller must set up RDUNIT and RDPAGE with the desired RAM disk unit 5166 ; and page, and BUFPTR, BUFCDF and BUFPNL with the address of a 128 word 5167 ; buffer in 6120 memory. If any errors are encountered, this routine will 5168 ; return with the LINK set and an error status in the AC. 5169 10400 6205 RAMDRD: .PUSHJ @[RAMSEL] ; select the unit in RDUNIT 10401 5777 5170 10402 7430 SZL ; was it invalid?? 5171 10403 5222 JMP RAMER1 ; yes - return error code 1 5172 10404 6205 .PUSHJ @[SETDAR] ; calculate the necessary disk address 10405 5776 5173 10406 7430 SZL ; is the page number invalid? 5174 10407 5224 JMP RAMER2 ; yes - return error code 2 5175 10410 5775 JMP @[UNPACK] ; unpack RAM disk data to the buffer and return 5176 5177 5178 ; This routine will write a single page from 6120 memory to RAM disk. Except 5179 ; for the direction of data flow, it's identical to RAMDRD, including all the 5180 ; parameters and error returns. 5181 10411 6205 RAMDWR: .PUSHJ @[RAMSEL] ; select the unit 10412 5777 5182 10413 7430 SZL ; was it invalid?? 5183 10414 5222 JMP RAMER1 ; yes - return error code 1 5184 10415 6205 .PUSHJ @[SETDAR] ; calculate the disk address 10416 5776 5185 10417 7430 SZL ; invalid page number?? 5186 10420 5224 JMP RAMER2 ; yes - return error code 2 5187 10421 5774 JMP @[PACK] ; pack buffer data into the RAM disk and return 5188 5189 5190 ; Here if the unit number is invalid... 5191 10422 7321 RAMER1: CLA CLL CML IAC ; return LINK = 1 and AC = 1 5192 10423 6225 .POPJ ; ... 5193 5194 ; Here if the page number is invalid... 5195 10424 7326 RAMER2: NL0002 ; return AC = 2 5196 10425 7120 STL ; and LINK = 1 5197 10426 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 129 Unpack RAM Disk Pages BTS6120.PLX 5198 .TITLE Unpack RAM Disk Pages 5199 5200 5201 ; This routine will read one page (aka a sector) of 128 PDP-8 words from 5202 ; the RAM disk to a buffer anywhere in main memory or panel memory. The 5203 ; address of the disk page read is selected by the RAMCDF and RAMPTR locations 5204 ; and the DAR register, which should be set up by prior calls to the RAMUNI 5205 ; and SETDAR routines. The address of the buffer written is selected by the 5206 ; BUFPTR, BUFCDF and BUFPNL locations, which must be set up by the caller 5207 ; before invoking this routine. Exactly 128 words are always transferred, 5208 ; without fail! 5209 10427 7200 UNPACK: CLA ; ... 5210 10430 1373 TAD [-64.] ; one page is 128 words, or 64 word pairs 5211 10431 3054 DCA XFRCNT ; ... 5212 5213 ; Fetch the next three bytes (two words) from the SRAM chip. Note that 5214 ; the SRAMs are only eight bits wide, so we'll read indeterminate garbage for 5215 ; the upper four bits of each word. Those have to be masked off on the first 5216 ; two bytes, but for the third one it doesn't matter - it gets masked to two 5217 ; four bit pieces later anyway... 5218 10432 4772 UNPAC1: JMS @[RAMCDF] ; change the DF to the RAM disk unit 5219 10433 6403 MM3 ; and enable the RAM disk chips 5220 10434 1410 TAD @RAMPTR ; fetch three bytes from RAM disk 5221 10435 0371 AND [377] ; eight bits only, please 5222 10436 3022 DCA RAMBUF ; ... 5223 10437 1410 TAD @RAMPTR ; ... 5224 10440 0371 AND [377] ; ... 5225 10441 3023 DCA RAMBUF+1 ; ... 5226 10442 1410 TAD @RAMPTR ; ... 5227 10443 3024 DCA RAMBUF+2 ; ... 5228 10444 6402 MM2 ; restore the default memory map 5229 10445 6211 CDF 1 ; and field 5230 5231 ; Pack the three bytes into two words and store them in main/panel memory... 5232 10446 4770 JMS @[BUFCDF] ; change DF to the buffer field 5233 10447 1024 TAD RAMBUF+2 ; the upper 4 bits of the first word are here 5234 10450 7002 BSW ; shift them left six 5235 10451 7106 CLL RTL ; ... then eight bits 5236 10452 0367 AND [7400] ; and isolate just those four bits 5237 10453 1022 TAD RAMBUF ; assemble the first word 5238 10454 3411 DCA @BUFPTR ; and store it in main memory 5239 10455 1024 TAD RAMBUF+2 ; now do the upper 4 bits of the second word 5240 10456 7106 CLL RTL ; shift them left two 5241 10457 7106 CLL RTL ; ... then four bits 5242 10460 0367 AND [7400] ; and isolate just those four bits 5243 10461 1023 TAD RAMBUF+1 ; reassemble the second word 5244 10462 3411 DCA @BUFPTR ; store that in main memory too 5245 10463 6276 SPD ; return to panel memory 5246 10464 6211 CDF 1 ; and our own memory field 5247 10465 2054 ISZ XFRCNT ; have we done a full page? 5248 10466 5232 JMP UNPAC1 ; nope - keep copying 5249 10467 7100 CLL ; be sure the LINK is cleared for success 5250 10470 6225 .POPJ ; yes - we're outta here! PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 130 Pack RAM Disk Pages BTS6120.PLX 5251 .TITLE Pack RAM Disk Pages 5252 5253 5254 ; This routine will write one page of 128 PDP-8 words from a buffer anywhere 5255 ; in either panel or main memory to RAM disk. It's the exact complement of 5256 ; UNPACK, and expects exactly the same things to be set up. 5257 10471 7200 PACK: CLA ; don't assume anything! 5258 10472 1373 TAD [-64.] ; do 64 word pairs, or 128 words 5259 10473 3054 DCA XFRCNT ; ... 5260 5261 ; Grab the next two twelve bit words from the buffer... 5262 10474 4770 PACK1: JMS @[BUFCDF] ; change DF to the buffer's field 5263 10475 1411 TAD @BUFPTR ; get a word from the buffer 5264 10476 3022 DCA RAMBUF ; save it for the computation of byte 3 5265 10477 1411 TAD @BUFPTR ; do the same with the second word 5266 10500 3023 DCA RAMBUF+1 ; ... 5267 10501 6276 SPD ; back to panel memory addressing 5268 5269 ; Store bytes 1 and 2 (they're easy) and calculate byte three. Note that 5270 ; the SRAM will ignore the upper four bits when writing (there's no hardware 5271 ; there!) so there's no need to worry about masking them out first... 5272 10502 4772 JMS @[RAMCDF] ; select the correct SRAM "unit" 5273 10503 6403 MM3 ; and enable the SRAM chips 5274 10504 1022 TAD RAMBUF ; store byte 1 5275 10505 3410 DCA @RAMPTR ; ... 5276 10506 1023 TAD RAMBUF+1 ; and byte 2 5277 10507 3410 DCA @RAMPTR ; ... 5278 10510 1022 TAD RAMBUF ; byte 3 has the top four bits of word 1 5279 10511 0367 AND [7400] ; ... 5280 10512 7002 BSW ; ... in bits 8..11 of the byte 5281 10513 7112 CLL RTR ; ... 5282 10514 3022 DCA RAMBUF ; save that for a moment 5283 10515 1023 TAD RAMBUF+1 ; and the top four bits of word 2 5284 10516 0367 AND [7400] ; ... 5285 10517 7112 CLL RTR ; in bits 4..7 5286 10520 7112 CLL RTR ; ... 5287 10521 1022 TAD RAMBUF ; ... 5288 10522 3410 DCA @RAMPTR ; ... 5289 10523 6402 MM2 ; return to the default memory map 5290 10524 6211 CDF 1 ; and field 5291 10525 2054 ISZ XFRCNT ; have we done a whole page? 5292 10526 5274 JMP PACK1 ; nope - keep going 5293 10527 7100 CLL ; be sure the LINK is cleared for success 5294 10530 6225 .POPJ ; all done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 131 Test RAM Disk Batteries BTS6120.PLX 5295 .TITLE Test RAM Disk Batteries 5296 5297 5298 ; This routine tests the status of the RAM disk backup batteries. The 5299 ; DS1221 doesn't have a status bit to give us the battery state directly, but 5300 ; it does have a clever hack to allow us to infer what we want to know. If 5301 ; the batteries have failed, then the DS1221 will inhibit all chip select 5302 ; outputs on the _second_ memory cycle (but not the first!). We can use this 5303 ; by 1) reading any location and saving its value, 2) writing any different 5304 ; value to the same location, and 3) reading it back again. If the batteries 5305 ; are dead, the second cycle will be inhibited, and the value read in step 3 5306 ; will be the same as 1. Of course, this presupposes that there's functional 5307 ; memory installed in the first place, if there isn't then this algorithm will 5308 ; erroneously report that the batteries are dead. 5309 ; 5310 ; WARNING - because of the way the DS1221 battery test works, this function 5311 ; MUST be called before any other RAM disk accesses. 5312 ; 5313 ; NOTE: At this point, DF is 1, which selects RAM disk unit zero! 5314 10531 7240 BATTST: STA ; ... 5315 10532 3026 DCA BATTOK ; assume batteries are OK for now 5316 10533 6410 LDAR ; and select SRAM bank zero 5317 10534 6403 MM3 ; enable RAM disk access 5318 10535 1766 TAD @[7777] ; (1) read the last byte of this bank 5319 10536 3351 DCA BATTMP ; save it for a minute 5320 10537 1351 TAD BATTMP ; ... 5321 10540 7041 CIA ; make it negative 5322 10541 3766 DCA @[7777] ; (2) and write it back 5323 10542 1351 TAD BATTMP ; get the original data 5324 10543 1766 TAD @[7777] ; (3) add what should be the complement 5325 10544 0371 AND [377] ; ignore all but the bottom eight bits 5326 10545 7640 SZA CLA ; if it's not zero then the second cycle was 5327 10546 3026 DCA BATTOK ; ... inhibited because the batteries are dead 5328 10547 6402 MM2 ; back to the default memory map 5329 10550 6225 .POPJ ; ... 5330 5331 ; Temporary storage for BATTST... 5332 10551 BATTMP: .BLOCK 1 ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 132 Get Battery Status ROM Call BTS6120.PLX 5333 .TITLE Get Battery Status ROM Call 5334 5335 5336 ; The Get Battery Status ROM call will return the status of the RAM disk 5337 ; lithium backup batteries. As long as either battery has sufficient 5338 ; voltage, -1 will be return in the AC. If both batteries have failed, then 5339 ; zero is returned. 5340 ; 5341 ; PR0 / call the SBC6120 ROM firmware 5342 ; 0003 / get backup battery status function code 5343 ; / return with AC == -1 if batteries are OK 5344 ; 5345 ; NOTE: Because of the way the DS1221 works, the battery status can only 5346 ; be tested after power up. It isn't possible to monitor the battery status 5347 ; in real time! 5348 10552 7300 GETBAT: CLA CLL ; this one's really easy! 5349 10553 1026 TAD BATTOK ; return the battery status in the AC 5350 10554 6225 .POPJ ; and that's it 5351 10566 7777 10567 7400 10570 2035 10571 0377 10572 0662 10573 7700 10574 0471 10575 0427 10576 0600 10577 0635 5352 10600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 133 Calculate RAM Disk Addresses BTS6120.PLX 5353 .TITLE Calculate RAM Disk Addresses 5354 5355 5356 ; This routine will calculate the RAM disk bank number and the relative 5357 ; offset within that bank, corresponding to a disk page number passed in 5358 ; location DKPAGE. The resulting bank number is simply loaded directly into 5359 ; the DAR via the LDAR IOT, and the offset is left in auto index location 5360 ; RAMPTR, where it can be used by the UNPACK and PACK routines. If the page 5361 ; number passed is illegal (i.e. greater than the size of the selected RAM 5362 ; disk unit) then the link will be set when this routine returns. 5363 10600 7300 SETDAR: CLA CLL ; make sure the link is in a known state 5364 10601 1021 TAD RDPAGE ; get the desired page 5365 10602 1035 TAD RAMUSZ ; compare it to the size of this unit 5366 10603 7630 SZL CLA ; is the page number legal? 5367 10604 6225 .POPJ ; no - return with the LINK set 5368 5369 ; Divide the page number by 21, the number of pages per bank, by repeated 5370 ; subtraction. This is kind of crude, but it only has to iterate 127 times, 5371 ; worst case, so the performance hit isn't that bad. We do have to be careful, 5372 ; though, because the largest legal page number is 2688, which is bigger than 5373 ; 2048. That means we have to treat the whole AC as a 12 bit UNSIGNED value! 5374 10605 3025 DCA RAMDAR ; clear the disk address (quotient) 5375 10606 1021 TAD RDPAGE ; get the selected RAM disk page number 5376 10607 7100 SETDA1: CLL ; make sure the link is clear before starting 5377 10610 1377 TAD [-BANKSZ] ; try to subtract another 21 5378 10611 7420 SNL ; did it fit? 5379 10612 5215 JMP SETDA2 ; nope - we can stop now 5380 10613 2025 ISZ RAMDAR ; yes - increment the disk address 5381 10614 5207 JMP SETDA1 ; and keep subtracting 5382 5383 ; We get here when we're done dividing, with the quotient in RAMDAR and the 5384 ; remainder in the AC. To calculate the byte offset within a bank, we need 5385 ; to multiply the remainder by 192 (the number of bytes per 128 word page). 5386 10615 1376 SETDA2: TAD [BANKSZ] ; restore the remainder 5387 10616 7002 BSW ; then multiply by 64 5388 10617 3010 DCA RAMPTR ; save offset*64 for a moment 5389 10620 1010 TAD RAMPTR ; ... 5390 10621 7104 CLL RAL ; then multiply by two again 5391 10622 1010 TAD RAMPTR ; 192*x = 128*x + 64*x 5392 10623 1375 TAD [-1] ; auto index registers pre-increment 5393 10624 3010 DCA RAMPTR ; that's the final offset 5394 5395 ; Set up the DAR with the bank number, from RAMDAR. Remember that for the 5396 ; 128K chips, we must always set A17 to enable the alternate chip select! 5397 10625 1035 TAD RAMUSZ ; get the size of the selected unit 5398 10626 1374 TAD [RAM128] ; ... 5399 10627 7650 SNA CLA ; is this a 128K ram chip ? 5400 10630 1373 TAD [32.] ; yes - always set A17 5401 10631 1025 TAD RAMDAR ; get the quotient from the division 5402 10632 6410 LDAR ; and load the disk address register 5403 10633 7300 CLA CLL ; LDAR doesn't clear the AC! 5404 10634 6225 .POPJ ; and we're done PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 134 Select RAM Disk Unit BTS6120.PLX 5405 .TITLE Select RAM Disk Unit 5406 5407 5408 ; This routine will set up the RAMCDF routine to select the desired RAM 5409 ; disk "unit". The unit number, 0..3, should be passed in RDUNIT. If the 5410 ; unit number given is illegal (i.e. greater than three) OR if there is no 5411 ; SRAM chip installed in the selected position, this routine will return 5412 ; with the link set. 5413 10635 7300 RAMSEL: CLL CLA ; make sure the link is in a known state 5414 10636 1020 TAD RDUNIT ; get the desired unit number 5415 10637 1372 TAD [-4] ; see if the unit is legal 5416 10640 7630 SZL CLA ; it must be less than 4 5417 10641 6225 .POPJ ; no - return with the link set 5418 10642 1020 TAD RDUNIT ; restore the original unit 5419 10643 7114 CLL R3L ; and position it for a CDF instruction 5420 10644 7104 CLL RAL ; (the link is zero for a success return!) 5421 10645 1371 TAD [CDF 0] ; make a CDF to the corresponding field 5422 10646 3263 DCA RAMCDF+1 ; and store that in the unit select routine 5423 5424 ; Now that we know the unit number is valid, verify that this chip is really 5425 ; installed by checking the RDSIZE array for a non-zero value. As a side 5426 ; effect of this, we always leave the size of the currently selected unit in 5427 ; location RAMUSZ, where it's used by SETDAR to determine whether the page 5428 ; addressed is actually legal. We always want to update RAMUSZ, even if the 5429 ; chip is not installed, because this will also cause SETDAR to fail if the 5430 ; caller ignores the our error return and attempts a read or write anyway. 5431 10647 1020 TAD RDUNIT ; get the unit number again 5432 10650 1370 TAD [RDSIZE] ; index into the RDSIZE array 5433 10651 3034 DCA SIZPTR ; ... 5434 10652 1434 TAD @SIZPTR ; to get the size of this chip 5435 10653 7041 CIA ; make it negative 5436 10654 3035 DCA RAMUSZ ; and save that for SETDAR 5437 10655 1035 TAD RAMUSZ ; ... 5438 10656 7100 CLL ; make sure the link is in a known state 5439 10657 7650 SNA CLA ; is this chip installed ? 5440 10660 7020 CML ; nope - give the error return 5441 10661 6225 .POPJ ; ... 5442 5443 ; This little routine can be called, via a JMS instruction (not a .PUSHJ!) 5444 ; to change the DF and select the last RAM disk unit set by a call to RAMSEL. 5445 10662 0000 RAMCDF: 0 ; call here via a JMS! 5446 10663 7000 NOP ; gets overwritten with a CDF instruction 5447 10664 5662 JMP @RAMCDF ; return... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 135 RAM Disk Diagnostics BTS6120.PLX 5448 .TITLE RAM Disk Diagnostics 5449 5450 5451 ; This routine will do a simple test of the RAM disk array to determine 5452 ; whether each SRAM chip, from 0 to 3, is installed. If a given chip is 5453 ; installed, then we do another simple test to determine whether it is a 5454 ; 512K or 128K device, and then update the RDSIZE array accordingly. 5455 ; Because of the way disk sectors are laid out, only the first 4032 bytes 5456 ; (21 * 192) of every 4Kb bank are actually used. The last 64 bytes of each 5457 ; bank are available to us to use any way we like, including as a RAM test. 5458 ; 5459 ; There's one nasty complication here - the pin that corresponds to A17 on 5460 ; the 512K SRAM chips is actually an alternate chip enable on the 128K chips. 5461 ; Worse, this alternate enable is active HIGH, which means that A17 must be 5462 ; one or 128K chips won't talk at all. Fortunately, the pin that corresponds 5463 ; to A18 is a no connect on the 128K chips, so we can safely leave it zero. 5464 ; This explains the strange bank numbers selected in this test! 5465 ; 5466 10665 3020 RDTEST: DCA RDUNIT ; start testing with unit zero 5467 10666 3033 DCA RAMSIZ ; clear the total RAM size 5468 10667 6205 RDTES0: .PUSHJ RAMSEL ; and set up RAMCDF and SIZPTR 10670 5235 5469 5470 ; First test to see if this chip is even installed by writing alternating 5471 ; bit patterns to the last two locations and reading them back. If that works, 5472 ; then there must be something there! 5473 10671 1373 TAD [32.] ; test bank 32 so that A17 will be set 5474 10672 6410 LDAR ; ... 5475 10673 7200 CLA ; (LDAR doesn't clear the AC!) 5476 10674 4262 JMS RAMCDF ; change the DF to select the unit 5477 10675 6403 MM3 ; and enable the SRAM array 5478 10676 1367 TAD [252] ; write alternating bits to the last two bytes 5479 10677 3766 DCA @[7776] ; ... 5480 10700 1365 TAD [125] ; ... 5481 10701 3775 DCA @[7777] ; ... 5482 10702 1766 TAD @[7776] ; now read 'em back 5483 10703 1775 TAD @[7777] ; and add them up 5484 10704 7001 IAC ; the sum should be 377, so make it 400 5485 10705 0364 AND [377] ; and remember RAM disk is only 8 bits wide 5486 10706 7640 SZA CLA ; did it work?? 5487 10707 5324 JMP RDTES1 ; no - this chip doesn't exist 5488 5489 ; Some kind of SRAM chip is installed, and now we need to decide whether its 5490 ; 128K or 512K. The 128K chips ignore A18, so one easy test is to select 5491 ; bank 96 (which, to a 128K chip is the same as bank 32), zero out a location 5492 ; that we just tested, and then go back to bank 32 to see if it changed. 5493 10710 1363 TAD [96.] ; select bank 96 5494 10711 6410 LDAR ; which doesn't exist in a 128K chip 5495 10712 7200 CLA ; (LDAR doesn't clear the AC!!) 5496 10713 3775 DCA @[7777] ; this location in bank 0 used to hold 125 5497 10714 1373 TAD [32.] ; back to bank 32 5498 10715 6410 LDAR ; ... 5499 10716 7200 CLA ; ... 5500 10717 1775 TAD @[7777] ; and see what we've got 5501 10720 0364 AND [377] ; remember RAM disk is only 8 bits wide 5502 10721 7640 SZA CLA ; if it's zero, then we have a 128K chip 5503 10722 1362 TAD [RAM512-RAM128]; nope - this must be a full 512K SRAM! 5504 10723 1374 TAD [RAM128] ; only 128K, but better than nothing 5505 5506 ; Store the chip size in RDSIZE and accumulate the total size... 5507 10724 6402 RDTES1: MM2 ; return to the default memory map 5508 10725 6211 CDF 1 ; and field 5509 10726 3434 DCA @SIZPTR ; store the size in RDSIZE[unit] 5510 10727 1434 TAD @SIZPTR ; ... 5511 10730 7450 SNA ; was there any chip here at all? PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 136 RAM Disk Diagnostics BTS6120.PLX 5512 10731 5337 JMP RDTES2 ; no - we can skip this part 5513 10732 7710 SPA CLA ; KLUDGE - skip if this was a 128K chip 5514 10733 1361 TAD [512.-128.] ; add 512K to the total RAM size 5515 10734 1360 TAD [128.] ; add 128K " " " " " 5516 10735 1033 TAD RAMSIZ ; ... 5517 10736 3033 DCA RAMSIZ ; ... 5518 5519 ; On to the next unit, if there are any more left... 5520 10737 2020 RDTES2: ISZ RDUNIT ; go on to the next unit 5521 10740 1020 TAD RDUNIT ; have we done all four ? 5522 10741 1372 TAD [-4] ; ??? 5523 10742 7640 SZA CLA ; ??? 5524 10743 5267 JMP RDTES0 ; no - keep checking 5525 10744 1033 TAD RAMSIZ ; yes - return the total RAM size in the AC 5526 10745 6225 .POPJ ; and that's it 5527 10760 0200 10761 0600 10762 3740 10763 0140 10764 0377 10765 0125 10766 7776 10767 0252 10770 0027 10771 6201 10772 7774 10773 0040 10774 1240 10775 7777 10776 0025 10777 7753 5528 11000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 137 Get RAM Disk Size ROM Call BTS6120.PLX 5529 .TITLE Get RAM Disk Size ROM Call 5530 5531 5532 ; PR0 function 2 will return the size of a RAM disk chip, in 128 word pages, 5533 ; in the AC. The AC should be loaded with the desired unit number, 0..3, 5534 ; before invoking PD0. If no chip is installed in the selected unit, zero 5535 ; will be returned in the AC. If the unit number is not in the range 0..3, 5536 ; then on return the LINK will be set to indicate an error. 5537 ; 5538 ; For example: 5539 ; TAD (unit / load the desired RAM disk unit, 0..3 5540 ; PR0 / call the ROM software 5541 ; 0002 / function code for Get RAM Disk Status 5542 ; / return the RAM disk size in the AC 5543 5544 ; It's tempting to use the RAMSEL routine here to save some steps, but be 5545 ; careful - RAMSEL will return with the LINK set (an error condition) if a 5546 ; valid unit number is selected but there is no SRAM chip installed there. 5547 ; That's not what we want for this ROM call, which should return an error only 5548 ; if the selected unit is > 3! 5549 11000 3020 GETRDS: DCA RDUNIT ; save the unit number 5550 11001 1020 TAD RDUNIT ; and get it back 5551 11002 7100 CLL ; be sure the link is in a known state 5552 11003 1377 TAD [-4] ; is it a legal unit number ? 5553 11004 7630 SZL CLA ; skip if so 5554 11005 6225 .POPJ ; no - return with the LINK set and AC clear 5555 11006 1020 TAD RDUNIT ; one more time 5556 11007 1376 TAD [RDSIZE] ; index the RDSIZE array 5557 11010 3034 DCA SIZPTR ; ... 5558 11011 1434 TAD @SIZPTR ; get the size of this disk 5559 11012 6225 .POPJ ; and return it with the LINK cleared PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 138 ATA Disk Support BTS6120.PLX 5560 .TITLE ATA Disk Support 5561 5562 5563 ; BTS6120 supports any standard ATA hard disk connected to the SBC6120 IDE 5564 ; interface. Nearly all hard disks with IDE interfaces are ATA; conversely, 5565 ; nearly all non-hard disk devices (e.g. CDROMs, ZIP drives, LS-120s, etc) 5566 ; with IDE interfaces are actually ATAPI and not ATA. ATAPI requires a 5567 ; completely different protocol, which BTS6120 does not support, and BTS6120 5568 ; will simply ignore any ATAPI devices connected to the IDE interface. 5569 ; BTS6120 supports only a single physical drive, which must be set up as the 5570 ; IDE master, and any IDE slave device will be ignored. 5571 ; 5572 ; Since BTS6120 does not support cylinder/head/sector (C/H/S) addressing, 5573 ; the hard disk used must support logical block addressing (LBA) instead. 5574 ; All modern IDE/ATA drives support LBA, as do most drives manufactured in the 5575 ; last five or six years, however some very old drives may not. If BTS6120 5576 ; detects an ATA drive that does not support LBA it will display the message 5577 ; "IDE: Not supported" during startup and there after ignore the drive. 5578 ; 5579 ; All IDE devices, regardless of vintage, transfer data in sixteen bit words 5580 ; and each sector on an ATA disk contains 512 bytes, or 256 sixteen bit words. 5581 ; When writing to the disk, BTS6120 converts twelve bit PDP-8 words to sixteen 5582 ; bits by adding four extra zero bits to the left and, when reading from the 5583 ; disk, BTS6120 converts sixteen bit words to twelve bits by simply discarding 5584 ; the most significant four bits. No packing is done. This conveniently 5585 ; means that each ATA sector holds 256 PDP-8 words, or exactly one OS/8 block. 5586 ; It also means that one quarter of the disk space is wasted, in this era of 5587 ; multi-gigabyte disks that hardly seems like an issue. 5588 ; 5589 ; OS/8 handlers and the OS/8 file system use a single twelve bit word to hold 5590 ; block numbers, which means that OS/8 mass storage devices are limited to a 5591 ; maximum of 4096 blocks . Using the BTS6120 non-packing scheme for storing 5592 ; data, 4096 PDP-8 blocks are exactly 2Mb. Clearly, if a single OS/8 device 5593 ; corresponds to an entire hard disk then nearly all of the disk space would 5594 ; be wasted. The normal solution is to partition the hard disk into many OS/8 5595 ; units, with each unit representing only a part of the entire disk. Since 5596 ; OS/8 cannot support a single unit larger than 2Mb there isn't any point in 5597 ; allowing partitions to be larger than that, and since the smallest drives 5598 ; available today can hold hundreds if not thousands of 2Mb partitions, there 5599 ; isn't much point in allowing a partition to be smaller than that, either. 5600 ; 5601 ; Because of this, BTS6120 supports only fixed size partitions of 2Mb each. 5602 ; This greatly simplifies the software since a twenty four bit disk sector 5603 ; number can now be calculated simply by concatenating a twelve bit partition 5604 ; number with the twelve bit OS/8 relative block number (RBN). No "super 5605 ; block" with a partition table is needed to keep track of the sizes and 5606 ; positions of each partition, and the OS/8 handler is simplified since each 5607 ; disk partition is always the same size. A twenty four bit sector address 5608 ; permits disks of up to 8Gb to be fully used, which seems more than enough 5609 ; for a PDP-8. 5610 ; 5611 ; Once again, in BTS6120 the partition number simply refers to the most 5612 ; significant twelve bits of a twenty-four bit disk address, and the OS/8 5613 ; block number is the least significant twelve bits. It's no more complicated 5614 ; than that! 5615 ; 5616 ; The ID01 is the OS/8 handler for the SBC6120 IDE/ATA disk. It supports 5617 ; eight units, IDA0 through IDA7, in a single page and may be assembled as 5618 ; either a system (IDSY) or non-system (IDNS) handler. The system handler 5619 ; version of the ID01 contains a secondary bootstrap that can be booted by 5620 ; the BTS6120 Boot command. The ID01 is a simple handler that uses HD-6120 5621 ; PR0 instruction to invoke BTS6120 functions for low level IDE disk access 5622 ; and data transfer. 5623 ; 5624 ; BTS6120 implements a partition map which defines the partition number PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 139 ATA Disk Support BTS6120.PLX 5625 ; corresponding to each OS/8 ID01 unit, and when an OS/8 program accesses an 5626 ; ID01 unit BTS6120 uses this table to determine the upper twelve bits of the 5627 ; LBA. At power on or after a MR command, BTS6120 initializes this partition 5628 ; map so that unit 0 accesses partition 0, unit 1 accesses partition 1, and 5629 ; so on up through unit 7 and partition 7. This mapping remains in effect 5630 ; until it is changed by either the PM command, or the Set IDE Disk Partition 5631 ; Mapping PR0 function. 5632 ; 5633 ; The largest mass storage device supported by OS/8 is actually only 4095 5634 ; blocks, not 4096, and so the last block of every 2Mb partition is never 5635 ; used by OS/8. This block can, however, be accessed via the Read/Write IDE 5636 ; disk PR0 function (section 6.5), and it can be used to store the name, 5637 ; creation date, and other information about that partition. The OS/8 PART 5638 ; program uses this to allow partitions to be mounted on ID01 logical units 5639 ; by name rather than partition number. Named partitions are strictly a 5640 ; function of the OS/8 PART program and BTS6120 knows nothing about them. PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 140 IDE Disk Interface BTS6120.PLX 5641 .TITLE IDE Disk Interface 5642 5643 5644 ; In the SBC6120, the IDE interface is implemented via a standard 8255 PPI, 5645 ; which gives us 24 bits of general purpose parallel I/O. Port A is connected 5646 ; the high byte (DD8..DD15) of the IDE data bus and port B is connected to 5647 ; the low byte (DD0..DD7). Port C supplies the IDE control signals as follow: 5648 ; 5649 ; C0..C2 -> DA0 .. 2 (i.e. device address select) 5650 ; C.3* -> DIOR L (I/O read) 5651 ; C.4* -> DIOW L (I/O write) 5652 ; C.5* -> RESET L 5653 ; C.6* -> CS1Fx L (chip select for the 1Fx register space) 5654 ; C.7* -> CS3Fx L ( " " " " 3Fx " " ) 5655 ; 5656 ; * These active low signals (CS1Fx, CS3Fx, DIOR, and DIOW) are inverted in 5657 ; the hardware so that writing a 1 bit to the register asserts the signal. 5658 ; 5659 ; One nice feature of the 8255 is that it allows bits in port C to be 5660 ; individually set or reset simply by writing the correct command word to the 5661 ; control register - it's not necessary to read the port, do an AND or OR, 5662 ; and write it back. We can use this feature to easily toggle the DIOR and 5663 ; DIOW lines with a single PWCR IOT. 5664 0222 IDEINP=222 ; set ports A and B as inputs, C as output 5665 0200 IDEOUT=200 ; set ports A and B (and C too) as outputs 5666 0007 SETDRD=007 ; assert DIOR L (PC.3) in the IDE interface 5667 0006 CLRDRD=006 ; clear " " " " " " " " 5668 0011 SETDWR=011 ; assert DIOW L (PC.4) in the IDE interface 5669 0010 CLRDWR=010 ; clear " " " " " " " " 5670 0013 SETDRE=013 ; assert DRESET L (PC.5) in the IDE interface 5671 0012 CLRDRE=012 ; clear " " " " " " " " 5672 5673 ; Standard IDE registers... 5674 ; (Note that these are five bit addresses that include the two IDE CS bits, 5675 ; CS3Fx (AC4) and CS1Fx (AC5). The three IDE register address bits, DA2..DA0 5676 ; correspond to AC9..AC11. 5677 0100 CS1FX=100 ; PC.6 selects the 1Fx register space 5678 0200 CS3FX=200 ; PC.7 " " 3Fx " " " 5679 0100 REGDAT=CS1FX+0 ; data (R/W) 5680 0101 REGERR=CS1FX+1 ; error (R/O) 5681 0102 REGCNT=CS1FX+2 ; sector count (R;W) 5682 0103 REGLB0=CS1FX+3 ; LBA byte 0 (or sector number) R/W 5683 0104 REGLB1=CS1FX+4 ; LBA byte 1 (or cylinder low) R/W 5684 0105 REGLB2=CS1FX+5 ; LBA byte 2 (or cylinder high) R/W 5685 0106 REGLB3=CS1FX+6 ; LBA byte 3 (or device/head) R/W 5686 0107 REGSTS=CS1FX+7 ; status (R/O) 5687 0107 REGCMD=CS1FX+7 ; command (W/O) 5688 5689 ; IDE status register (REGSTS) bits... 5690 0200 STSBSY=0200 ; busy 5691 0100 STSRDY=0100 ; device ready 5692 0040 STSDF= 0040 ; device fault 5693 0020 STSDSC=0020 ; device seek complete 5694 0010 STSDRQ=0010 ; data request 5695 0004 STSCOR=0004 ; corrected data flag 5696 0001 STSERR=0001 ; error detected 5697 5698 ; IDE command codes (or at least the ones we use!)... 5699 0220 CMDEDD=220 ; execute device diagnostic 5700 0354 CMDIDD=354 ; identify device 5701 0040 CMDRDS=040 ; read sectors with retry 5702 0060 CMDWRS=060 ; write sectors with retry 5703 0341 CMDSUP=341 ; spin up 5704 0340 CMDSDN=340 ; spin down PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 141 Initialize IDE Drive and Interface BTS6120.PLX 5705 .TITLE Initialize IDE Drive and Interface 5706 5707 5708 ; This routine will initialize the IDE interface by configuring the 8255 5709 ; PPI and then asserting the IDE RESET signal to the drive. It then selects 5710 ; the master drive and waits for it to become ready, after which it returns. 5711 ; If there is no drive attached, or if the hardware is broken, then we'll time 5712 ; out after approximately 30 seconds of waiting for the drive to signal a 5713 ; ready status. 5714 ; 5715 ; Normally this routine will return with the AC and LINK both cleared, but 5716 ; if the drive reports an error then on return the LINK will be set and the 5717 ; drive's error status will be in the AC. In the case of a timeout, the 5718 ; LINK will be set and the AC will be -1 on return. 5719 11013 7200 IDEINI: CLA ; ... 5720 11014 3040 DCA DKSIZE ; zero means no disk is installed 5721 11015 1375 TAD [IDEINP] ; PPI ports A and B are input and C is output 5722 11016 6477 PWCR ; ... 5723 11017 6476 PWPC ; clear all port C control lines 5724 11020 1374 TAD [SETDRE] ; set RESET L 5725 11021 6477 PWCR ; ... 5726 11022 1373 TAD [-10] ; according to the ATA specification, 5727 11023 7001 IAC ; ... we must leave RESET asserted for at 5728 11024 7440 SZA ; ... least 25 microseconds 5729 11025 5223 JMP .-2 ; 5730 11026 1372 TAD [CLRDRE] ; deassert RESET L 5731 11027 6477 PWCR ; ... 5732 11030 1371 TAD [340] ; select the master drive, 512 byte sectors, 5733 11031 4770 JMS @[IDEWRR] ; ... and logical block addressing (LBA) mode 5734 11032 0106 REGLB3 ; ... 5735 11033 5767 JMP @[WREADY] ; wait for the drive ready and return PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 142 Identify IDE/ATA Device BTS6120.PLX 5736 .TITLE Identify IDE/ATA Device 5737 5738 5739 ; This routine will execute the ATA IDENTIFY DEVICE command and store the 5740 ; first 256 bytes of the result, in byte mode, in the panel memory buffer at 5741 ; DSKBUF. One thing to keep in mind is that ATAPI devices (e.g. CDROMs, ZIP 5742 ; disks, etc) ignore this command completely and respond to the ATAPI IDENTIFY 5743 ; PACKET DEVICE command instead. This means that if there are any ATAPI 5744 ; devices attached we'll never see them, which is fine since we don't 5745 ; understand how to talk to ATAPI devices anyway! 5746 ; 5747 ; The drive's response to IDENTIFY DEVICE will be 256 words of sixteen bit 5748 ; data full of device specific data - model number, manufacturer, serial 5749 ; number, drive geometry, maximum size, access time, and tons of other cool 5750 ; stuff. The RDIBUF routine would pack this sixteen bit data into twelve bit 5751 ; words by throwing away the upper four bits of each word, but that doesn't 5752 ; make sense in this case since we'd be destroying most of the useful 5753 ; information. Instead, this routine reads the data in an unpacked format and 5754 ; stores one eight bit byte per PDP-8 word. 5755 ; 5756 ; Unfortunately this would mean that we need a 512 word buffer to store the 5757 ; response, which is too big for our DSKBUF in panel memory. We're in luck, 5758 ; however, because of the 256 words (512 bytes) returned by this command the 5759 ; ATA specification only defines the first 128 - the remaining half of the 5760 ; data is "vendor specific" and undefined. This routine simply throws this 5761 ; part away, and only the first 128 words (256 bytes) of the drive's response 5762 ; are actually returned in the buffer. 5763 ; 5764 ; Like all the disk I/O routines, in the case of an error the LINK will 5765 ; be set and the contents of the drive's error register returned in the AC. 5766 11034 6205 DISKID: .PUSHJ @[WREADY] ; (just in case the drive is busy now) 11035 5767 5767 11036 7430 SZL ; any errors? 5768 11037 6225 .POPJ ; yes - we can go home early! 5769 11040 1366 TAD [CMDIDD] ; send the ATA identify device command 5770 11041 4770 JMS @[IDEWRR] ; by writing it to the command register 5771 11042 0107 REGCMD ; ... 5772 11043 6205 .PUSHJ @[WDRQ] ; the drive should ask to transfer data next 11044 5765 5773 11045 7430 SZL ; any errors? 5774 11046 6225 .POPJ ; yes - just give up 5775 5776 ; Get ready to ready to transfer data from the drive to our buffer... 5777 11047 1364 TAD [DSKBUF-1] ; setup BUFPTR to point to DSKBUF 5778 11050 3011 DCA BUFPTR ; ... 5779 11051 1363 TAD [-128.] ; transfer 128 words this time 5780 11052 3054 DCA XFRCNT ; ... 5781 11053 1375 TAD [IDEINP] ; set PPI ports A and B to input mode 5782 11054 6477 PWCR ; ... 5783 11055 1362 TAD [REGDAT] ; make sure the IDE data register is selected 5784 11056 6476 PWPC ; ... 5785 5786 ; Read 256 bytes into the caller's buffer, one byte per word. Big endian 5787 ; ordering (i.e. high byte first) is defined by the ATA specification to give 5788 ; the correct character order for ASCII strings in the device data (e.g. model 5789 ; number, serial number, manufacturer, etc). 5790 11057 1361 IDDEV1: TAD [SETDRD] ; assert DIOR 5791 11060 6477 PWCR ; ... 5792 11061 6470 PRPA ; read port A (the high byte) first 5793 11062 0360 AND [377] ; only eight bits are valid 5794 11063 3411 DCA @BUFPTR ; and store it in the buffer 5795 11064 6471 PRPB ; then read port B (the low byte) 5796 11065 0360 AND [377] ; ... 5797 11066 3411 DCA @BUFPTR ; ... 5798 11067 1357 TAD [CLRDRD] ; deassert DIOR PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 143 Identify IDE/ATA Device BTS6120.PLX 5799 11070 6477 PWCR ; ... 5800 11071 2054 ISZ XFRCNT ; have we done all 256 bytes? 5801 11072 5257 JMP IDDEV1 ; nope - keep reading 5802 5803 ; We've read our 256 bytes, but the drive still has another 256 more waiting 5804 ; in the buffer. We need to read those and throw them away... 5805 11073 1363 TAD [-128.] ; we still need to read 128 more words 5806 11074 3054 DCA XFRCNT ; ... 5807 11075 1361 IDDEV2: TAD [SETDRD] ; assert DIOR 5808 11076 6477 PWCR ; ... 5809 11077 7000 NOP ; make sure the DIOR pulse is wide enough 5810 11100 7000 NOP ; ... 5811 11101 1357 TAD [CLRDRD] ; and then clear DIOR 5812 11102 6477 PWCR ; ... 5813 11103 2054 ISZ XFRCNT ; have we done all 128? 5814 11104 5275 JMP IDDEV2 ; nope - keep reading 5815 5816 ; Drives report the total number of LBA addressable sectors in words 5817 ; 60 and 61. Sectors are 512 bytes, so simply dividing this value by 2048 5818 ; gives us the total drive size in Mb. This code patches together twelve 5819 ; bits out of the middle of this doubleword, after throwing away the least 5820 ; significant 11 bits to divide by 2048. This allows us to determine the 5821 ; size of drives up to 4Gb in a single 12 bit word. 5822 11105 1756 TAD @[DSKBUF+170] ; get the high byte of the low word 5823 11106 7010 RAR ; throw away the 3 least significant 5824 11107 7012 RTR ; ... 5825 11110 0355 AND [37] ; keep just 5 bits from this byte 5826 11111 3040 DCA DKSIZE ; save it for a minute 5827 11112 1754 TAD @[DSKBUF+173] ; get the low byte of the high word 5828 11113 7006 RTL ; left justify the seven MSBs of it 5829 11114 7006 RTL ; ... 5830 11115 7004 RAL ; ... 5831 11116 0353 AND [7740] ; ... 5832 11117 1040 TAD DKSIZE ; put together all twelve bits 5833 11120 3040 DCA DKSIZE ; ... 5834 5835 ; All done - return success... 5836 11121 7300 CLA CLL ; return with the AC and LINK clear 5837 11122 6225 .POPJ ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 144 Get IDE Disk Size ROM Call BTS6120.PLX 5838 .TITLE Get IDE Disk Size ROM Call 5839 5840 5841 ; The get IDE disk size call will return the size of the attached IDE/ATA 5842 ; disk, in megabytes. This call never fails - if no disk is attached it 5843 ; simply returns zero... 5844 ; 5845 ;CALL: 5846 ; PR0 / call SBC6120 ROM firmware 5847 ; 5 / subfunction for get disk size 5848 ; 5849 ; 5850 11123 7300 GETDKS: CLA CLL ; ignore anything in the AC 5851 11124 1040 TAD DKSIZE ; and return the disk size 5852 11125 6225 .POPJ ; that's all there is to it! PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 145 IDE Disk Primary Bootstrap BTS6120.PLX 5853 .TITLE IDE Disk Primary Bootstrap 5854 5855 5856 ; This routine will read block zero from IDE disk partition zero into page 5857 ; zero of field zero of main memory. The next step in the usual boot sequence 5858 ; would be to start the secondary bootstrap, but that's up to the caller... 5859 11126 7240 IDBOOT: STA ; point the buffer to page 0 5860 11127 3011 DCA BUFPTR ; ... 5861 11130 1352 TAD [CDF 0] ; of field zero 5862 11131 3751 DCA @[BUFCDF+1] ; ... 5863 11132 3055 DCA BUFPNL ; of main memory 5864 11133 3036 DCA DKPART ; read IDE disk partition zero 5865 11134 3037 DCA DKRBN ; block zero 5866 11135 1363 TAD [-128.] ; we only need the first 1/2 of the block 5867 11136 5750 JMP @[DISKRD] ; ... 5868 11150 1200 11151 2036 11152 6201 11153 7740 11154 7573 11155 0037 11156 7570 11157 0006 11160 0377 11161 0007 11162 0100 11163 7600 11164 7377 11165 1337 11166 0354 11167 1311 11170 1701 11171 0340 11172 0012 11173 7770 11174 0013 11175 0222 11176 0027 11177 7774 5869 11200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 146 Read and Write IDE Sectors BTS6120.PLX 5870 .TITLE Read and Write IDE Sectors 5871 5872 5873 ; This routine will read a single sector from the attached IDE drive. 5874 ; The caller should set up DKPART and DKRBN with the disk partition and 5875 ; sector number, and BUFPTR, BUFCDF and BUFPNL with the address of a 5876 ; buffer in 6120 memory. If any errors are encountered, this routine will 5877 ; return with the LINK set and the drive's error status in the AC... 5878 11200 3056 DISKRD: DCA BUFSIZ ; save the buffer size 5879 11201 6205 .PUSHJ WREADY ; wait for the drive to become ready 11202 5311 5880 11203 7430 SZL ; any errors detected?? 5881 11204 6225 .POPJ ; yes - quit now 5882 11205 6205 .PUSHJ SETLBA ; set up the disk's LBA registers 11206 5254 5883 11207 1377 TAD [CMDRDS] ; read sector with retry command 5884 11210 4776 JMS @[IDEWRR] ; write that to the command register 5885 11211 0107 REGCMD ; ... 5886 11212 6205 .PUSHJ WDRQ ; now wait for the drive to finish 11213 5337 5887 11214 7430 SZL ; any errors detected? 5888 11215 6225 .POPJ ; yes - quit now 5889 11216 1056 TAD BUFSIZ ; no - transfer data 5890 11217 5775 JMP @[RDIBUF] ; ... from the sector buffer to memory 5891 5892 5893 ; This routine will write a single sector to the attached IDE drive. Except 5894 ; for the direction of data transfer, it's basically the same as DISKRD, 5895 ; including all parameters and error returns. 5896 11220 3056 DISKWR: DCA BUFSIZ ; save the caller's record size 5897 11221 6205 .PUSHJ WREADY ; wait for the drive to become ready 11222 5311 5898 11223 7430 SZL ; did we encounter an error ? 5899 11224 6225 .POPJ ; yes - just give up now 5900 11225 6205 .PUSHJ SETLBA ; set up the disk address registers 11226 5254 5901 11227 1374 TAD [CMDWRS] ; write sector with retry command 5902 11230 4776 JMS @[IDEWRR] ; write that to the command register 5903 11231 0107 REGCMD ; ... 5904 11232 6205 .PUSHJ WDRQ ; wait for the drive to request data 11233 5337 5905 11234 7430 SZL ; did the drive detect an error instead? 5906 11235 6225 .POPJ ; yes - just give up 5907 11236 1056 TAD BUFSIZ ; nope - transfer the data 5908 11237 6205 .PUSHJ @[WRIBUF] ; ... to the sector buffer from memory 11240 5773 5909 5910 ; There's a subtle difference in the order of operations between reading and 5911 ; writing. In the case of writing, we send the WRITE SECTOR command to the 5912 ; drive, transfer our data to the sector buffer, and only then does the 5913 ; drive actually go out and access the disk. This means we have to wait 5914 ; one more time for the drive to actually finish writing, because only then 5915 ; can we know whether it actually worked or not! 5916 11241 5311 JMP WREADY ; wait for the drive to finish writing PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 147 Spin Up and Spin Down IDE Drive BTS6120.PLX 5917 .TITLE Spin Up and Spin Down IDE Drive 5918 5919 5920 ; This routine will send a spin up command to the IDE drive and then wait 5921 ; for it to finish. This command will take a fairly long time under normal 5922 ; conditions. Worse, since this is frequently the first command we send to 5923 ; a drive, if there's no drive attached at all we'll have to wait for it 5924 ; to time out. If any errors are encountered then the LINK will be set on 5925 ; return and the contents of the drive's error register will be in the AC. 5926 11242 7200 SPINUP: CLA ; ... 5927 11243 1372 TAD [CMDSUP] ; send the spin up command to the drive 5928 11244 4776 JMS @[IDEWRR] ; by writing it to the command register 5929 11245 0107 REGCMD ; ... 5930 11246 5311 JMP WREADY ; wait for the drive to become ready 5931 5932 5933 ; This routine will send a spin down command. Drives are not required by 5934 ; the standard to implement this command, so there's no guarantee that any 5935 ; thing will actually happen! 5936 11247 7200 SPINDN: CLA ; ... 5937 11250 1371 TAD [CMDSDN] ; send the spin down command to the drive 5938 11251 4776 JMS @[IDEWRR] ; ... 5939 11252 0107 REGCMD ; ... 5940 11253 5311 JMP WREADY ; and wait for it to finish PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 148 Setup IDE Unit, LBA and Sector Count Registers BTS6120.PLX 5941 .TITLE Setup IDE Unit, LBA and Sector Count Registers 5942 5943 5944 ; This routine will set up the IDE logical block address (LBA) registers 5945 ; according to the current disk address in locations DKPART and DKRBN. On IDE 5946 ; drives the sector number is selected via the cylinder and sector registers in 5947 ; the register file, but in the case of LBA mode these registers simply form a 5948 ; 24 bit linear sector number. In this software the disk partition number, in 5949 ; DKPART, gives the upper twelve bits of the address and the current sector 5950 ; number, in DKRBN, gives the lower twelve bits. 5951 ; 5952 ; This routine does not detect any error conditions... 5953 11254 7200 SETLBA: CLA ; just in case! 5954 11255 1037 TAD DKRBN ; get the lower 12 bits of of the LBA 5955 11256 4776 JMS @[IDEWRR] ; and write the lowest 8 bits to LBA0 5956 11257 0103 REGLB0 ; (the upper 4 bits are ignored) 5957 11260 1037 TAD DKRBN ; now get the upper 4 bits of the sector number 5958 11261 7002 BSW ; shift right eight bits 5959 11262 7012 RTR ; ... 5960 11263 0370 AND [17] ; get rid of the extra junk 5961 11264 3310 DCA LBATMP ; ... 5962 11265 1036 TAD DKPART ; get the disk partition number 5963 11266 7006 RTL ; shift them left four bits 5964 11267 7006 RTL ; ... 5965 11270 0367 AND [360] ; and isolate just four bits of that 5966 11271 1310 TAD LBATMP ; and build the middle byte of the LBA 5967 11272 4776 JMS @[IDEWRR] ; set that register next 5968 11273 0104 REGLB1 ; ... 5969 11274 1036 TAD DKPART ; get the partition one more time 5970 11275 7012 RTR ; shift it right four more bits 5971 11276 7012 RTR ; ... 5972 11277 4776 JMS @[IDEWRR] ; to make the upper byte of the 24 bit LBA 5973 11300 0105 REGLB2 ; ... 5974 5975 ; Note that the final four bits of the LBA are in LBA3 (the head and drive 5976 ; select register). Since we can only support 24 bit LBAs, these are unused. 5977 ; The IDEINI routine initializes them to zero at the same time it selects the 5978 ; master drive, and we never change 'em after that. At the same time, IDEINI 5979 ; also selects LBA addressing mode (which is obviously very important to us!) 5980 ; and 512 byte sectors. 5981 11301 1371 TAD [340] ; select the master drive, 512 byte sectors, 5982 11302 4776 JMS @[IDEWRR] ; ... and logical block addressing (LBA) mode 5983 11303 0106 REGLB3 ; ... 5984 5985 ; Always load the sector count register with one... 5986 11304 7201 NL0001 ; write 1 5987 11305 4776 JMS @[IDEWRR] ; ... 5988 11306 0102 REGCNT ; to the sector count register 5989 11307 6225 .POPJ ; that's all we have to do 5990 5991 ; Temporary storage for SETLBA... 5992 11310 LBATMP: .BLOCK 1 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 149 Wait for IDE Drive Ready BTS6120.PLX 5993 .TITLE Wait for IDE Drive Ready 5994 5995 5996 ; This routine tests for the DRIVE READY bit set in the status register and 5997 ; at the same time for the DRIVE BUSY bit to be clear. READY set means that 5998 ; the drive has power and is spinning, and BUSY clear means that it isn't 5999 ; currently executing a command. The combination of these two conditions means 6000 ; that the drive is ready to accept another command. Normally this routine 6001 ; will return with both the AC and the LINK cleared, however if the drive sets 6002 ; the ERROR bit in its status register then it will return with the LINK set 6003 ; and the contents of the drive's error register in the AC. 6004 ; 6005 ; If there is no drive connected, or if the drive fails for some reason, 6006 ; then there is the danger that this routine will hang forever. To avoid 6007 ; that it also implements a simple timeout, and if the drive doesn't become 6008 ; ready within a certain period of time it will return with the LINK set and 6009 ; the AC equal to -1. If the system has just been powered up, then we'll 6010 ; have to wait for the drive to spin up before it becomes ready, and that can 6011 ; take a fairly long time. To be safe, the timeout currently stands at a 6012 ; full 30 seconds! 6013 11311 1366 WREADY: TAD [7550] ; initialize the outer timeout counter 6014 11312 3336 DCA RDYTMO+1 ; ... 6015 11313 3335 DCA RDYTMO ; and the inner counter is always cleared 6016 11314 4765 WREAD1: JMS @[IDERDR] ; go read the status register 6017 11315 0107 REGSTS ; (register to read) 6018 11316 7110 CLL RAR ; test the error bit first (AC11) 6019 11317 7430 SZL ; ??? 6020 11320 5353 JMP DRVERR ; give up now if the drive reports an error 6021 11321 7004 RAL ; restore the original status 6022 11322 0364 AND [STSBSY+STSRDY] ; test both the READY and BUSY bits 6023 11323 1363 TAD [-STSRDY] ; is READY set and BUSY clear? 6024 11324 7020 CML ; (the last TAD will have set the link!) 6025 11325 7650 SNA CLA ; ??? 6026 11326 6225 .POPJ ; yes - return now with the AC and LINK clear 6027 11327 2335 ISZ RDYTMO ; increment the inner timeout counter 6028 11330 5314 JMP WREAD1 ; no overflow yet 6029 11331 2336 ISZ RDYTMO+1 ; when the inner counter overflows, increment 6030 11332 5314 JMP WREAD1 ; ... the outer counter too 6031 6032 ; Here in the case of a drive time out... 6033 11333 7360 CLA CLL CML CMA ; return with AC = -1 and the LINK set 6034 11334 6225 .POPJ ; ... 6035 6036 ; Temporary storage for WREADY... 6037 11335 RDYTMO: .BLOCK 2 ; a double word time out counter PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 150 Wait for IDE Data Request BTS6120.PLX 6038 .TITLE Wait for IDE Data Request 6039 6040 6041 ; This routine will wait for the DRQ bit to set in the drive status register. 6042 ; This bit true when the drive is ready to load or unload its sector buffer, 6043 ; and normally a call to this routine will be immediately followed by a call 6044 ; to ether RDIBUF or WRIBUF. Normally this routine will return with both the 6045 ; LINK and the AC cleared, however if the drive sets its error bit then the 6046 ; LINK will be 1 on return and the drive's error status will be in the AC. 6047 ; 6048 ; WARNING - unlike WREADY, this routine does not have a timeout! 6049 11337 4765 WDRQ: JMS @[IDERDR] ; read the drive status register 6050 11340 0107 REGSTS ; ... 6051 11341 7110 CLL RAR ; test the error bit (AC11) 6052 11342 7430 SZL ; is it set? 6053 11343 5353 JMP DRVERR ; yes - give the error return 6054 11344 7004 RAL ; no - restore the original status value 6055 11345 0362 AND [STSBSY+STSDRQ] ; and test the BUSY and DRQ flags 6056 11346 1361 TAD [-STSDRQ] ; wait for BUSY clear and DRQ set 6057 11347 7020 CML ; (the last TAD will have set the link!) 6058 11350 7640 SZA CLA ; well? 6059 11351 5337 JMP WDRQ ; nope - keep waiting 6060 11352 6225 .POPJ ; yes - return with AC and LINK cleared! 6061 6062 ; We get here if the drive sets the error flag in the status register. In 6063 ; this case we return with the link bit set and the contents of the drive 6064 ; error register in the AC. 6065 11353 4765 DRVERR: JMS @[IDERDR] ; read the drive error register 6066 11354 0101 REGERR ; ... 6067 11355 7120 STL ; and be sure the link is set 6068 11356 6225 .POPJ ; ... 6069 11361 7770 11362 0210 11363 7700 11364 0300 11365 1721 11366 7550 11367 0360 11370 0017 11371 0340 11372 0341 11373 1400 11374 0060 11375 1446 11376 1701 11377 0040 6070 11400 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 151 Write IDE Sector Buffer BTS6120.PLX 6071 .TITLE Write IDE Sector Buffer 6072 6073 6074 ; This routine will write PDP-8 twelve bit words to the IDE drive's sixteen 6075 ; bit data (sector) buffer. IDE drives naturally transfer data in sixteen bit 6076 ; words, and we simply store each twelve bit word zero extended. This wastes 6077 ; 25% of the drive's capacity, but in these days of multiple gigabyte disks, 6078 ; that hardly seems important. This also means that 256 PDP-8 words exactly 6079 ; fill one IDE sector, which is very convenient for OS/8! 6080 ; 6081 ; The caller is expected to set up BUFPTR, BUFCDF and BUFPNL to point to the 6082 ; buffer in 6120 memory. The negative of the buffer size should be passed in 6083 ; the AC, however we must always write exactly 256 words to the drive regard- 6084 ; less of the buffer size. If the buffer is smaller than that, then the last 6085 ; word is simply repeated until we've filled the entire sector. This is 6086 ; necessary for OS/8 handler "half block" writes. 6087 ; 6088 ; This routine does not wait for the drive to set DRQ, nor does it check the 6089 ; drive's status for errors. Those are both up to the caller. 6090 11400 3056 WRIBUF: DCA BUFSIZ ; save the actual buffer size 6091 11401 1377 TAD [-256.] ; but always transfer 256 words, regardless 6092 11402 3054 DCA XFRCNT ; ... 6093 11403 1376 TAD [IDEOUT] ; and set ports A and B to output mode 6094 11404 6477 PWCR ; ... 6095 11405 1375 TAD [REGDAT] ; make sure the IDE data register is addressed 6096 11406 6476 PWPC ; ... 6097 11407 4774 JMS @[BUFCDF] ; change to the buffer's field 6098 6099 ; Transfer 256 twelve bit words into 256 sixteen bit words... 6100 11410 1411 WRIBU1: TAD @BUFPTR ; and get the next data word 6101 11411 3312 DCA BUFTMP ; save it temporarily 6102 11412 1312 TAD BUFTMP ; ... 6103 11413 6475 PWPB ; write the lowest 8 bits to port B 6104 11414 1312 TAD BUFTMP ; then get the upper four bits 6105 11415 7002 BSW ; ... 6106 11416 7012 RTR ; ... 6107 11417 0373 AND [17] ; ensure that the extra bits are zero 6108 11420 6474 PWPA ; and write the upper four bits to port A 6109 11421 1372 TAD [SETDWR] ; assert DIOW 6110 11422 6477 PWCR ; ... 6111 11423 1371 TAD [CLRDWR] ; and then clear it 6112 11424 6477 PWCR ; ... 6113 11425 2054 ISZ XFRCNT ; have we done 256 words?? 6114 11426 7410 SKP ; no - keep going 6115 11427 5240 JMP WRIBU3 ; yes - always stop now 6116 11430 2056 ISZ BUFSIZ ; have we filled the buffer ? 6117 11431 5210 JMP WRIBU1 ; nope - keep copying 6118 6119 ; Here when we've emptied the 6120 buffer, but if we haven't done 256 words 6120 ; we have to keep going until we've filled the drive's sector buffer. All we 6121 ; need to do is to keep asserting DIOW, which simply repeats the last word 6122 ; written! 6123 11432 1372 WRIBU2: TAD [SETDWR] ; assert DIOW 6124 11433 6477 PWCR ; ... 6125 11434 1371 TAD [CLRDWR] ; and deassert DIOW 6126 11435 6477 PWCR ; ... 6127 11436 2054 ISZ XFRCNT ; have we finished the sector? 6128 11437 5232 JMP WRIBU2 ; nope 6129 6130 ; Restore the PPI ports to input mode and return. Note that some disk 6131 ; I/O routines JMP to WRIBUF as the last step, so it's important that we 6132 ; always return with the AC and LINK cleared to indicate success. 6133 11440 6211 WRIBU3: CDF 1 ; return to our field 6134 11441 6276 SPD ; and to panel memory 6135 11442 1370 TAD [IDEINP] ; reset ports A and B to input PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 152 Write IDE Sector Buffer BTS6120.PLX 6136 11443 6477 PWCR ; ... 6137 11444 7300 CLA CLL ; return success 6138 11445 6225 .POPJ ; all done here PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 153 Read IDE Sector Buffer BTS6120.PLX 6139 .TITLE Read IDE Sector Buffer 6140 6141 6142 ; This routine will read sixteen bit words from the IDE drive's sector 6143 ; buffer and store them in twelve bit PDP-8 memory words. Data is converted 6144 ; from sixteen to twelve bits by the simple expedient of discarding the upper 6145 ; four bits of each word - it can't get much easier than that! 6146 ; 6147 ; The caller is expected to set up BUFPTR, BUFCDF and BUFPNL to point to the 6148 ; buffer in 6120 memory. The negative of the buffer size should be passed in 6149 ; the AC. This is the number of words that will be stored in the buffer, 6150 ; however we'll always read exactly 256 words from the drive regardless of 6151 ; the buffer size. If the buffer is smaller than this then the extra words 6152 ; are simply discarded. This is necessary for OS/8 handler "half block" reads. 6153 ; 6154 ; Like WRIBUF, this routine does not wait for the drive to set DRQ, nor does 6155 ; it check the drive's status for errors. Those are both up to the caller. 6156 11446 3056 RDIBUF: DCA BUFSIZ ; save the actual buffer size 6157 11447 1377 TAD [-256.] ; but always transfer 256 words, regardless 6158 11450 3054 DCA XFRCNT ; ... 6159 11451 1370 TAD [IDEINP] ; and set ports A and B to input mode 6160 11452 6477 PWCR ; ... 6161 11453 1375 TAD [REGDAT] ; make sure the IDE data register is addressed 6162 11454 6476 PWPC ; ... 6163 11455 4774 JMS @[BUFCDF] ; change to the buffer's field 6164 6165 ; Transfer 256 twelve bit words... 6166 11456 1367 RDIBU1: TAD [SETDRD] ; assert DIOR 6167 11457 6477 PWCR ; ... 6168 11460 6471 PRPB ; capture the lower order byte 6169 11461 0366 AND [377] ; remove any junk bits, just in case 6170 11462 3312 DCA BUFTMP ; and save that for a minute 6171 11463 6470 PRPA ; then capture the high byte 6172 11464 0373 AND [17] ; we only want four bits from that 6173 11465 7002 BSW ; shift it left eight bits 6174 11466 7106 CLL RTL ; ... 6175 11467 1312 TAD BUFTMP ; assemble a complete twelve bit word 6176 11470 3411 DCA @BUFPTR ; and store it in the buffer 6177 11471 1365 TAD [CLRDRD] ; finally we can deassert DIOR 6178 11472 6477 PWCR ; ... 6179 11473 2054 ISZ XFRCNT ; have we done 256 words?? 6180 11474 7410 SKP ; no - keep going 6181 11475 5306 JMP RDIBU3 ; yes - always stop now 6182 11476 2056 ISZ BUFSIZ ; have we filled the buffer ? 6183 11477 5256 JMP RDIBU1 ; nope - keep copying 6184 6185 ; Here when we've filled the 6120 buffer, but if we haven't done 256 words 6186 ; we have to keep going until we've emptied the drive's sector buffer too. 6187 ; All we need to do is to keep asserting DIOR - there's no need to actually 6188 ; capture the data! 6189 11500 1367 RDIBU2: TAD [SETDRD] ; assert DIOR 6190 11501 6477 PWCR ; ... 6191 11502 1365 TAD [CLRDRD] ; and deassert DIOR 6192 11503 6477 PWCR ; ... 6193 11504 2054 ISZ XFRCNT ; have we finished the sector? 6194 11505 5300 JMP RDIBU2 ; nope 6195 6196 ; Restore the ROM field and memory space and return. Note that some disk 6197 ; I/O routines JMP to RDIBUF as the last step, so it's important that we 6198 ; always return with the AC and LINK cleared to indicate success. 6199 11506 6211 RDIBU3: CDF 1 ; ... 6200 11507 6276 SPD ; ... 6201 11510 7300 CLA CLL ; always return success 6202 11511 6225 .POPJ ; all done here 6203 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 154 Read IDE Sector Buffer BTS6120.PLX 6204 ; Temporary storage for RDIBUF and WRIBUF... 6205 11512 BUFTMP: .BLOCK 1 ; temporary for packing and unpacking PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 155 Initialize Disk Partition Map BTS6120.PLX 6206 .TITLE Initialize Disk Partition Map 6207 6208 6209 ; This routine will initialize the disk partition map so that unit 0 6210 ; maps to partition 0, unit 1 maps to partition 1, etc... This is the 6211 ; default partition mapping used after a power on and remains in effect 6212 ; until changed by an OS/8 program with the "Set Partition Mapping" PR0 6213 ; subfunction. 6214 11513 7300 INIPMP: CLA CLL ; just in case... 6215 11514 1364 TAD [PARMAP-1] ; set up an auto index register 6216 11515 3012 DCA XX1 ; ... to address the partition map 6217 11516 3036 DCA DKPART ; count partition/unit numbers here 6218 11517 1036 INIPM1: TAD DKPART ; get the current partition/unit 6219 11520 3412 DCA @XX1 ; and set the next entry in the map 6220 11521 1036 TAD DKPART ; see how many we've done 6221 11522 1363 TAD [-10] ; have we done all eight? 6222 11523 7630 SZL CLA ; skip if not 6223 11524 6225 .POPJ ; yes - we can quit now 6224 11525 2036 ISZ DKPART ; nope - do the next one 6225 11526 5317 JMP INIPM1 ; ... 6226 11563 7770 11564 0041 11565 0006 11566 0377 11567 0007 11570 0222 11571 0010 11572 0011 11573 0017 11574 2035 11575 0100 11576 0200 11577 7400 6227 11600 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 156 Get/Set Disk Partition Map ROM Call BTS6120.PLX 6228 .TITLE Get/Set Disk Partition Map ROM Call 6229 6230 6231 ; This routine handles the "Set Disk Partition Mapping" (6) PR0 subfunction, 6232 ; which simply sets the partition number for the specified OS/8 unit. This 6233 ; change takes effect immediately, so if you've booted from the IDE disk 6234 ; you'll want to be a little careful about remapping the system partition! 6235 ; This function returns with the LINK set if an error occurs, currently the 6236 ; only failure that can happen is if the unit number is .GT. 7. Note that 6237 ; no range checking is done on the partition number to ensure that it fits 6238 ; within the disk size - if it doesn't we'll simply get I/O errors when OS/8 6239 ; attempts to access that partition. 6240 ; 6241 ;CALL: 6242 ; TAD (part / load the partition number into the AC 6243 ; PR0 / invoke the ROM monitor 6244 ; 6 / subfunction for Set disk partition 6245 ; / OS/8 unit to be changed, 0..7 6246 ; / LINK set if unit .GT. 7 6247 ; 6248 11600 3036 SETPMP: DCA DKPART ; save the partition number for a minute 6249 11601 6205 .PUSHJ @[GETARG] ; and get the unit number 11602 5777 6250 11603 3041 DCA DKUNIT ; ... 6251 11604 1041 TAD DKUNIT ; ... 6252 11605 7100 CLL ; be sure the link is in a known state 6253 11606 1376 TAD [-10] ; see if the unit number is legal 6254 11607 7630 SZL CLA ; the link will be set if it isn't 6255 11610 6225 .POPJ ; take the error return w/o changing anything 6256 11611 1041 TAD DKUNIT ; construct an index to the partition map 6257 11612 1375 TAD [PARMAP-1] ; ... 6258 11613 3012 DCA XX1 ; ... 6259 11614 1036 TAD DKPART ; then get the desired partition number 6260 11615 3412 DCA @XX1 ; and change it 6261 11616 6225 .POPJ ; return with the LINK and AC both clear 6262 6263 6264 ; This routine handles the "Get Disk Partition Mapping" (7) PR0 subfunction, 6265 ; which simply returns the partition number currently associated with a 6266 ; specific OS/8 unit. The only way it can fail is if the unit number is 6267 ; greater than 7! 6268 ; 6269 ;CALL: 6270 ; PR0 / invoke the ROM monitor 6271 ; 7 / subfunction for get disk partition 6272 ; / OS/8 unit to be changed, 0..7 6273 ; / with partition number in the AC 6274 ; 6275 11617 6205 GETPMP: .PUSHJ @[GETARG] ; and get the unit number 11620 5777 6276 11621 3041 DCA DKUNIT ; ... 6277 11622 7100 CLL ; be sure the link is in a known state 6278 11623 1376 TAD [-10] ; see if the unit number is legal 6279 11624 1041 TAD DKUNIT ; ... 6280 11625 7630 SZL CLA ; the link will be set if it isn't 6281 11626 6225 .POPJ ; take the error return 6282 11627 1041 TAD DKUNIT ; construct an index to the partition map 6283 11630 1375 TAD [PARMAP-1] ; ... 6284 11631 3012 DCA XX1 ; ... 6285 11632 1412 TAD @XX1 ; and get the current partition 6286 11633 6225 .POPJ ; return with partition in the AC and LINK=0 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 157 IDE Disk Read/Write ROM Call BTS6120.PLX 6287 .TITLE IDE Disk Read/Write ROM Call 6288 6289 6290 ; The calling sequence for the PR0 IDE disk R/W function is: 6291 ; 6292 ; PR0 6293 ; 0004 / panel function code for IDE disk I/O 6294 ; / R/W bit, page count, buffer field and unit 6295 ; / buffer address 6296 ; / starting block number 6297 ; / if any errors occur, the LINK will be set and the 6298 ; / the drive's error register are in the AC 6299 ; 6300 ; Except for the function code, the use of block numbers instead of page 6301 ; numbers, and the error codes, this calling sequence is identical to the 6302 ; RAM disk I/O PR0 subfunction! 6303 ; 6304 11634 6205 DISKRW: .PUSHJ @[SETBUF] ; set up MUUO, BUFPTR, BUFCDF and RWCNT 11635 5774 6305 11636 6205 .PUSHJ @[GETARG] ; and lastly get the disk block 11637 5777 6306 11640 3037 DCA DKRBN ; ... 6307 6308 ; See if there really is a hard disk attached. If not, then immediately 6309 ; take the error return with the AC set to -1. 6310 11641 1040 TAD DKSIZE ; if there is a disk attached 6311 11642 7640 SZA CLA ; then DKSIZE will be non-zero 6312 11643 5246 JMP DKRW0 ; it is - it's safe to proceed 6313 11644 7360 CLA CLL CML CMA ; no disk - return LINK = 1 and AC = -1 6314 11645 6225 .POPJ ; and quit now 6315 6316 ; The unit number is really just an index into the partition table and, 6317 ; since it's limited to three bits and eight units are supported, there's 6318 ; no need to range check it! 6319 11646 1052 DKRW0: TAD MUUO ; get the unit number 6320 11647 0373 AND [7] ; ... 6321 11650 1375 TAD [PARMAP-1] ; create an index to the partition table 6322 11651 3012 DCA XX1 ; ... 6323 11652 1412 TAD @XX1 ; get the actual partition number 6324 11653 3036 DCA DKPART ; ... that's mapped to this unit 6325 6326 ; Set up a pointer to the I/O routine. All of the rest of this code is 6327 ; independent of the direction of data flow... 6328 11654 1052 TAD MUUO ; get the function code 6329 11655 7700 SMA CLA ; should we read (0) or write (1) ? 6330 11656 1372 TAD [DISKRD-DISKWR]; ... read 6331 11657 1371 TAD [DISKWR] ; ... write 6332 11660 3300 DCA DISKIO ; save the address of the routine 6333 6334 ; We must take a minute out to share a word about pages vs blocks. An OS/8 6335 ; handler call specifies the size of the data to be read or written in pages, 6336 ; which are 128 words or exactly 1/2 of a 256 word disk block. This raises 6337 ; the unfortunate possibility that a program could ask to transfer an odd 6338 ; number of pages, which would mean that we'd need to read or write half a 6339 ; block! We can't ignore this problem because it really does happen and there 6340 ; really are OS/8 programs that attempt to transfer an odd number of pages. 6341 ; 6342 ; This is primarily an issue for reading, because if an odd number of pages 6343 ; are to be read we must be very careful to stop copying data to memory after 6344 ; 128 words. If we don't, a page of memory will be corrupted by being over 6345 ; written with the second half of the last disk block! It's also permitted in 6346 ; OS/8 to write an odd number of pages, but since many OS/8 mass storage 6347 ; devices have 256 word sectors it isn't always possible to write half a 6348 ; block. In this case it's undefined what gets written to the last half of 6349 ; the final block - it could be zeros, random garbage, or anything else. PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 158 IDE Disk Read/Write ROM Call BTS6120.PLX 6350 6351 ; This loop reads or writes pages 'till we've done all we're supposed to... 6352 11661 2057 DKRW1: ISZ RWCNT ; is there an odd page left over? 6353 11662 7410 SKP ; nope - it's safe to do a full block 6354 11663 5276 JMP DKRW2 ; yes - go transfer a half block and quit 6355 11664 1370 TAD [-256.] ; transfer two pages this time 6356 11665 6205 .PUSHJ @DISKIO ; either read or write 11666 5700 6357 11667 7430 SZL ; were there any errors? 6358 11670 6225 .POPJ ; yes - just abort the transfer now 6359 11671 2037 ISZ DKRBN ; increment the block number for next time 6360 11672 7000 NOP ; (this should never happen, but...) 6361 11673 2057 ISZ RWCNT ; are there more pages left to do ? 6362 11674 5261 JMP DKRW1 ; yup - keep going 6363 11675 6225 .POPJ ; all done - return AC = LINK = 0 6364 6365 ; Here to transfer one, final, half block... 6366 11676 1367 DKRW2: TAD [-128.] ; only do a single page this time 6367 11677 5700 JMP @DISKIO ; transfer it and we're done 6368 6369 ; Local storage for DISKRW... 6370 11700 DISKIO: .BLOCK 1 ; gets a pointer to either DISKRD or DISKWR PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 159 Write IDE Register BTS6120.PLX 6371 .TITLE Write IDE Register 6372 6373 6374 ; This routine will write an eight bit value to any IDE drive register, 6375 ; except the data regsister, by toggling all the appropriate PPI port lines. 6376 ; The address of the register, which should include the CS1Fx and CS3Fx bits, 6377 ; is passed in line and the byte to be written is passed in the AC. Note that 6378 ; all IDE registers, with the exception of the data register, are eight bits 6379 ; wide so there's never a need to worry about the upper byte! 6380 ; 6381 ;CALL: 6382 ; TAD [value] ; eight bit value to write to the IDE register 6383 ; JMS IDEWRR 6384 ; xxxx ; IDE register number, plus CS1Fx and CS3Fx bits 6385 ; 6386 ; 6387 11701 0000 IDEWRR: 0 ; CALL HERE WITH A JMS!!! 6388 11702 3342 DCA IDETMP ; save the value to write for a minute 6389 11703 1366 TAD [IDEOUT] ; set ports A and B to output mode 6390 11704 6477 PWCR ; write the PPI control register 6391 11705 1701 TAD @IDEWRR ; get the IDE register address 6392 11706 2301 ISZ IDEWRR ; (skip it when we return) 6393 11707 6476 PWPC ; send the address to the drive via port C 6394 6395 ; Note that we don'e bother to drive the upper data byte (D8..D15) with any 6396 ; particular value. The PPI will have set these bits to zero when we changed 6397 ; the mode to output, but the drive will ignore them anyway. 6398 11710 1342 TAD IDETMP ; get the original data back 6399 11711 6475 PWPB ; (port B drives DD0..DD7) 6400 11712 1365 TAD [SETDWR] ; assert DIOW 6401 11713 6477 PWCR ; ... 6402 11714 1364 TAD [CLRDWR] ; and then clear it 6403 11715 6477 PWCR ; ... 6404 6405 ; We always leave our side of the PPI data bus (e.g. ports A and B) in 6406 ; input mode to avoid any accidental contention should the drive decide it 6407 ; wants to output data for some unknown reason. 6408 11716 1363 TAD [IDEINP] ; set ports A and B to input mode 6409 11717 6477 PWCR ; ... (but C is still an output) 6410 11720 5701 JMP @IDEWRR ; that's it! PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 160 Read IDE Register BTS6120.PLX 6411 .TITLE Read IDE Register 6412 6413 6414 ; This routine will read one IDE drive register and return the value in the 6415 ; AC. all IDE registers, with the exception of the data register, are always 6416 ; eight bits wide so there's no need to worry about the upper byte here. We 6417 ; simply ignore it. The address of the register to be read should be passed 6418 ; inline, following the call to this procedure. 6419 ; 6420 ;CALL 6421 ; JMS IDERDR 6422 ; xxxx ; IDE register number, including CS1Fx and CS3Fx bits 6423 ; 6424 ; 6425 11721 0000 IDERDR: 0 ; CALL HERE WITH A JMS!! 6426 11722 7200 CLA ; just in case... 6427 11723 1363 TAD [IDEINP] ; set ports A and B to input 6428 11724 6477 PWCR ; ... (this should be unnecessary, 6429 11725 1721 TAD @IDERDR ; get the IDE register address 6430 11726 2321 ISZ IDERDR ; (and don't forget to skip it!) 6431 11727 6476 PWPC ; send it to the drive via port C 6432 11730 1373 TAD [SETDRD] ; assert DIOR 6433 11731 6477 PWCR ; ... 6434 11732 7000 NOP ; give the drive and 8255 time to settle 6435 11733 6471 PRPB ; capture D0..D7 6436 11734 0362 AND [377] ; make sure we don't get noise in DX0..DX3 6437 11735 3342 DCA IDETMP ; and save that for a minute 6438 11736 1361 TAD [CLRDRD] ; now deassert DIOR 6439 11737 6477 PWCR ; ... 6440 11740 1342 TAD IDETMP ; get the data back 6441 11741 5721 JMP @IDERDR ; and return it in the AC 6442 6443 ; Local storage for RD/IDEWRR... 6444 11742 IDETMP: .BLOCK 1 ; a temporary for saving the AC 6445 11761 0006 11762 0377 11763 0222 11764 0010 11765 0011 11766 0200 11767 7600 11770 7400 11771 1220 11772 7760 11773 0007 11774 2000 11775 0041 11776 7770 11777 0241 6446 12000 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 161 I/O Buffer Management BTS6120.PLX 6447 .TITLE I/O Buffer Management 6448 6449 6450 ; This routine is used parse the argument list for ROM calls that take OS/8 6451 ; handler like argument lists, primarily the RAM disk and IDE disk I/O calls. 6452 ; It will do a GETARG and store the first argument, which contains the R/W 6453 ; bit, page count, buffer field and unit number, in MUUO. It extracts the 6454 ; buffer field from this argument, builds a CDF instruction, and stores that 6455 ; at BUFCDF for later use. It also extracts the page count from this 6456 ; argument, converts it to a negative number, and stores the result at RWCNT. 6457 ; Finally, it does another GETARG to fetch the address of the caller's buffer 6458 ; and stores that at BUFPTR. 6459 12000 6205 SETBUF: .PUSHJ @[GETARG] ; get the first argument 12001 5777 6460 12002 3052 DCA MUUO ; save that - it's got lots of useful bits! 6461 12003 1052 TAD MUUO ; get the field bits from MUUO 6462 12004 0376 AND [70] ; ... 6463 12005 1375 TAD [CDF 0] ; make a CDF instruction out of them 6464 12006 3236 DCA BUFCDF+1 ; and save them for later 6465 12007 1052 TAD MUUO ; get the page count from the call 6466 12010 0374 AND [3700] ; ... 6467 12011 7450 SNA ; is it zero ? 6468 12012 7330 NL4000 ; yes - that means to transfer a full 32 pages 6469 12013 7002 BSW ; right justify the page count 6470 12014 7041 CIA ; make it negative for an ISZ 6471 12015 3057 DCA RWCNT ; ... 6472 12016 6205 .PUSHJ @[GETARG] ; get the buffer pointer from the argument list 12017 5777 6473 12020 1373 TAD [-1] ; correct for pre-incrementing auto-index 6474 12021 3011 DCA BUFPTR ; and save that 6475 12022 3055 DCA BUFPNL ; this buffer is always in main memory 6476 12023 6225 .POPJ ; all done for now 6477 6478 6479 ; This routine will set up BUFPTR, BUFCDF, RWCNT and BUFPNL to point to 6480 ; our own internal buffer in panel memory at DSKBUF. This is used by the 6481 ; disk dump, disk load, format and boot commands when they need to read or 6482 ; write disk blocks without distrubing main memory. 6483 12024 1372 PNLBUF: TAD [DSKBUF-1] ; point to the disk buffer 6484 12025 3011 DCA BUFPTR ; set the buffer address for DISKRD/DISKWR 6485 12026 1371 TAD [CDF 1] ; this buffer lives in our field 1 6486 12027 3236 DCA BUFCDF+1 ; ... 6487 12030 7344 NLM2 ; the buffer size is always 2 pages 6488 12031 3057 DCA RWCNT ; ... 6489 12032 7240 NL7777 ; write this data to PANEL memory! 6490 12033 3055 DCA BUFPNL ; ... 6491 12034 6225 .POPJ ; and we're done 6492 6493 6494 ; This little routine is called, via a JMS instruction (not a .PUSHJ!) to 6495 ; change the DF to the field of the user's buffer. In addition, if the 6496 ; BUFPNL flag is not set, it will execute a CPD instruction so that buffer 6497 ; data is stored in main memory. This is the usual case. 6498 12035 0000 BUFCDF: 0 ; call here with a JMS 6499 12036 7000 NOP ; gets over written with a CDF instruction 6500 12037 7200 CLA ; just in case 6501 12040 1055 TAD BUFPNL ; is the panel buffer flag set? 6502 12041 7650 SNA CLA ; ??? 6503 12042 6266 CPD ; no - address main memory now 6504 12043 5635 JMP @BUFCDF ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 162 Copy Memory ROM Calls BTS6120.PLX 6505 .TITLE Copy Memory ROM Calls 6506 6507 6508 ; This ROM function can copy up to 4096 words from any field in either main 6509 ; or panel memory to any other address and field in either main or panel 6510 ; memory. It can be used to move data and/or code into panel memory and 6511 ; back again, or simply to move one part of main memory to another. 6512 ; 6513 ;CALL: 6514 ; PR0 6515 ; 0010 / copy memory subfunction 6516 ; p0n0 / source field and memory space 6517 ;
/ source address 6518 ; p0n0 / destination field and memory space 6519 ;
/ destination address 6520 ; / number of words to be transferred 6521 ; 6522 ; The source and destination field words each contain the field number in 6523 ; bits 6..8, and a flag in bit 0 which is one for panel memory and zero for 6524 ; main memory. The last word of the argument list is the number of words 6525 ; to be copied - a value of zero copies 4096 words. 6526 6527 ; Set up the source address... 6528 12044 6205 MEMMOV: .PUSHJ @[GETARG] ; get the source field 12045 5777 6529 12046 7100 CLL ; make sure the link is in a known state 6530 12047 1370 TAD [4000] ; put the panel/main memory flag in the LINK 6531 12050 0376 AND [70] ; make a CDF instruction 6532 12051 1375 TAD [CDF 0] ; ... 6533 12052 3306 DCA SRCCDF ; ... 6534 12053 1367 TAD [CPD] ; assume the source is in main memory 6535 12054 7430 SZL ; but is it really ? 6536 12055 1366 TAD [SPD-CPD] ; no - use panel memory 6537 12056 3307 DCA SRCSPD ; ... 6538 12057 6205 .PUSHJ @[GETARG] ; get the buffer address 12060 5777 6539 12061 1373 TAD [-1] ; correct for pre-increment auto index 6540 12062 3012 DCA XX1 ; ... 6541 6542 ; Set up the destination address... 6543 12063 6205 .PUSHJ @[GETARG] ; get the destination field 12064 5777 6544 12065 7100 CLL ; make sure the link is in a known state 6545 12066 1370 TAD [4000] ; put the panel/main memory flag in the LINK 6546 12067 0376 AND [70] ; make a CDF instruction 6547 12070 1375 TAD [CDF 0] ; ... 6548 12071 3311 DCA DSTCDF ; ... 6549 12072 1367 TAD [CPD] ; assume the destination is in main memory 6550 12073 7430 SZL ; but is it really ? 6551 12074 1366 TAD [SPD-CPD] ; no - use panel memory 6552 12075 3312 DCA DSTSPD ; ... 6553 12076 6205 .PUSHJ @[GETARG] ; get the buffer address 12077 5777 6554 12100 1373 TAD [-1] ; correct for pre-increment auto index 6555 12101 3013 DCA XX2 ; ... 6556 6557 ; And finally the word count... 6558 12102 6205 .PUSHJ @[GETARG] ; ... 12103 5777 6559 12104 7041 CIA ; make it negative for ISZ 6560 12105 3054 DCA XFRCNT ; ... 6561 6562 ; This loop does the actual work of copying data! 6563 12106 7000 SRCCDF: NOP ; over written with a CDF instruction 6564 12107 7000 SRCSPD: NOP ; over written with a SPD/CPD IOT PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 163 Copy Memory ROM Calls BTS6120.PLX 6565 12110 1412 TAD @XX1 ; get a word of source data 6566 12111 7000 DSTCDF: NOP ; over written with a CDF instruction 6567 12112 7000 DSTSPD: NOP ; overwritten with a SPD/CPD IOT 6568 12113 3413 DCA @XX2 ; and store the word 6569 12114 2054 ISZ XFRCNT ; have we done them all ? 6570 12115 5306 JMP SRCCDF ; no - keep copying 6571 6572 ; All done! 6573 12116 6276 SPD ; be sure the field and memory space are safe 6574 12117 6211 CDF 1 ; ... 6575 12120 7300 CLL CLA ; and always return success 6576 12121 6225 .POPJ ; ... 6577 12166 0010 12167 6266 12170 4000 12171 6211 12172 7377 12173 7777 12174 3700 12175 6201 12176 0070 12177 0241 6578 12200 .PAGE PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 164 Free Space for Future Expansion! BTS6120.PLX 6579 .TITLE Free Space for Future Expansion! 6580 6581 13400 .PAGE 16 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 165 Command Names Table BTS6120.PLX 6582 .TITLE Command Names Table 6583 6584 6585 ; This table gives the names of all the commands known to the monitor. Each 6586 ; entry consists of a one or two letter command name, in SIXBIT, followed by 6587 ; the address of a routine to execute it. Although this table is stored in 6588 ; field 1, all the command routines are implicitly in field zero! The zero 6589 ; entry at the end is a "catch all" that is called if none of the previous 6590 ; names match, and points to an error routine. With the exception of this last 6591 ; entry, the order of the table is not significant. 6592 13400 CMDTBL: 6593 13400 .SIXBIT /H / ; Help 6594 13401 0737 HELP ; ... 6595 13402 .SIXBIT /RP/ ; RePeat 6596 13403 0620 REPEAT ; ... 6597 13404 .SIXBIT /E / ; Examine 6598 13405 1002 EMEM ; ... 6599 13406 .SIXBIT /EP/ ; Examine Panel memory 6600 13407 1000 EPMEM ; ... 6601 13410 .SIXBIT /D / ; Deposit 6602 13411 1067 DMEM ; ... 6603 13412 .SIXBIT /DP/ ; Deposit Panel memory 6604 13413 1065 DPMEM ; ... 6605 13414 .SIXBIT /ER/ ; Examine Register 6606 13415 1114 EREG ; ... 6607 13416 .SIXBIT /DR/ ; Deposit Register 6608 13417 1132 DREG ; ... 6609 13420 .SIXBIT /BM/ ; Block Move 6610 13421 1400 BMOVE ; ... 6611 13422 .SIXBIT /CK/ ; ChecKsum 6612 13423 1442 CKMEM ; ... 6613 13424 .SIXBIT /WS/ ; Word Search 6614 13425 1600 SEARCH ; ... 6615 13426 .SIXBIT /CM/ ; Clear Memory 6616 13427 1507 CMEM ; ... 6617 13430 .SIXBIT /FM/ ; Fill Memory 6618 13431 1503 FLMEM ; ... 6619 13432 .SIXBIT /BL/ ; Breakpoint List 6620 13433 1674 BLIST ; ... 6621 13434 .SIXBIT /BP/ ; BreakPoint 6622 13435 2036 BPTCOM ; ... 6623 13436 .SIXBIT /BR/ ; Breakpoint Remove 6624 13437 2000 BREMOV ; ... 6625 13440 .SIXBIT /C / ; Continue 6626 13441 2214 CONTCM ; ... 6627 13442 .SIXBIT /SI/ ; Single Instruction with no trace 6628 13443 2200 SNCOM ; ... 6629 13444 .SIXBIT /ST/ ; STart 6630 13445 2241 START ; ... 6631 13446 .SIXBIT /P / ; Proceed 6632 13447 2207 PROCEE ; ... 6633 13450 .SIXBIT /TR/ ; single instruction with TRace 6634 13451 2144 SICOM ; ... 6635 13452 .SIXBIT /VE/ ; VErsion (of monitor) 6636 13453 0707 VECOM ; ... 6637 13454 .SIXBIT /TW/ ; Terminal Width 6638 13455 0645 TWCOM ; ... 6639 13456 .SIXBIT /TP/ ; Terminal Page 6640 13457 0667 TPCOM ; ... 6641 13460 .SIXBIT /EX/ ; EXECUTE (IOT instruction) 6642 13461 2315 XCTCOM ; ... 6643 13462 .SIXBIT /MR/ ; MASTER RESET 6644 13463 2270 CLRCOM ; ... 6645 13464 .SIXBIT /LP/ ; LOAD PAPER (tape from console) 6646 13465 3200 CONLOD ; ... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 166 Command Names Table BTS6120.PLX 6647 13466 .SIXBIT /DD/ ; Disk (IDE) Dump 6648 13467 3405 DDDUMP ; ... 6649 13470 .SIXBIT /RD/ ; Disk (RAM) Dump 6650 13471 3400 RDDUMP ; ... 6651 13472 .SIXBIT /DL/ ; Disk (IDE) Load 6652 13473 3521 DLLOAD ; ... 6653 13474 .SIXBIT /RL/ ; Disk (RAM) Load 6654 13475 3514 RLLOAD ; ... 6655 13476 .SIXBIT /DF/ ; Disk (IDE) Format 6656 13477 3072 DFRMAT ; ... 6657 13500 .SIXBIT /RF/ ; Disk (RAM) Format 6658 13501 3120 RFRMAT 6659 13502 .SIXBIT /B / ; Bootstrap ram disk 6660 13503 2426 BOOT 6661 13504 .SIXBIT /PM/ ; Partition Map 6662 13505 2600 PMEDIT ; ... 6663 13506 .SIXBIT /PC/ ; Partition Copy 6664 13507 4000 PCOPY ; ... 6665 13510 0000 0000 ; This must always be the last entry 6666 13511 0441 COMERR ; Where to go if none of the above matches PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 167 Argument Tables for Various Commands BTS6120.PLX 6667 .TITLE Argument Tables for Various Commands 6668 6669 6670 ; This table gives a list of the legal register names for the ER (Examine 6671 ; Register) command... 6672 13512 ENAMES: .SIXBIT /AC/ ; The AC 6673 13513 1252 TYPEAC 6674 13514 .SIXBIT /PC/ ; The PC 6675 13515 1255 TYPEPC 6676 13516 .SIXBIT /MQ/ ; The MQ 6677 13517 1260 TYPEMQ 6678 13520 .SIXBIT /PS/ ; The processor status 6679 13521 1266 TYPEPS 6680 13522 .SIXBIT /SR/ ; The switch register 6681 13523 1277 TYPESR 6682 13524 0000 0000 ; None of the above 6683 13525 0441 COMERR 6684 6685 ; This table gives a list of the legal register names for the DR (deposit 6686 ; register) command... 6687 13526 DNAMES: .SIXBIT /AC/ ; The AC 6688 13527 1200 DAC 6689 13530 .SIXBIT /PC/ ; The PC 6690 13531 1203 DPC 6691 13532 .SIXBIT /MQ/ ; The MQ 6692 13533 1206 DMQ 6693 13534 .SIXBIT /PS/ ; The flags 6694 13535 1211 DPS 6695 13536 .SIXBIT /SR/ ; The switch register 6696 13537 1221 DSR 6697 13540 0000 0000 ; None of the above 6698 13541 0441 COMERR 6699 6700 ; This table is a list of the arguments to the B (BOOT) command... 6701 13542 BNAMES: .SIXBIT /VM/ ; VMA0 6702 13543 2464 BTVMA0 6703 13544 .SIXBIT /ID/ ; IDA0 6704 13545 2500 BTIDA0 6705 13546 0000 0000 ; end of list 6706 13547 0441 COMERR PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 168 Messages BTS6120.PLX 6707 .TITLE Messages 6708 6709 ; General purpose messages... 6710 13550 CKSMSG: .TEXT /Checksum = / 6711 13561 MEMMSG: .TEXT /?Memory error at / 6712 13576 ERRILV: .TEXT /Illegal value/ 6713 13610 ERRSRF: .TEXT /Search fails/ 6714 13621 ERRRAN: .TEXT /Wrong order/ 6715 13632 ERRWRP: .TEXT /Wrap around/ 6716 13643 SKPMSG: .TEXT /Skip / 6717 13650 ERRDIO: .TEXT \?I/O Error \ 6718 13661 ERRCKS: .TEXT /Checksum error/ 6719 13674 ERRNBT: .TEXT /No bootstrap/ 6720 13705 ERRNDK: .TEXT /No disk/ 6721 6722 ; Program trap messages... 6723 13713 BPTMSG: .TEXT /%Breakpoint at / 6724 13726 PR0MSG: .TEXT /?Illegal PR0 function at / 6725 13750 BRKMSG: .TEXT /%Break at / 6726 13760 PRNMSG: .TEXT /?Panel trap at / 6727 13773 HLTMSG: .TEXT /?Halted at / 6728 14004 TRPMSG: .TEXT /?Unknown trap at / 6729 6730 ; Breakpoint messages... 6731 14021 ERRNBP: .TEXT /None set/ 6732 14030 ERRNST: .TEXT /Not set/ 6733 14036 ERRAST: .TEXT /Already set/ 6734 14047 ERRBTF: .TEXT /Table full/ 6735 6736 ; Register names... 6737 14057 ACNAME: .TEXT /AC>/ 6738 14062 PCNAME: .TEXT /PC>/ 6739 14065 MQNAME: .TEXT /MQ>/ 6740 14070 IRNAME: .TEXT /IR>/ 6741 14073 SRNAME: .TEXT /SR>/ 6742 14076 PSNAME: .TEXT /PS>/ 6743 14101 SP1NAM: .TEXT /SP1>/ 6744 14105 SP2NAM: .TEXT /SP2>/ 6745 6746 ; Disk formatting status messages... 6747 14111 FCFMSG: .TEXT \Format unit/partition \ 6748 14131 FM1MSG: .TEXT /Writing / 6749 14140 FM2MSG: .TEXT / Verifying / 6750 14151 FM3MSG: .TEXT / Done/ 6751 14156 ERRDSK: .TEXT \?Verification error, block/page \ 6752 6753 ; Partition copy messages.... 6754 14205 CCFMSG: .TEXT \Overwrite partition \ 6755 14224 CP1MSG: .TEXT /Copying / 6756 4151 CP2MSG=FM3MSG 6757 6758 ; Partition map messages... 6759 14233 PM1MSG: .TEXT /Unit / 6760 14240 PM2MSG: .TEXT / -> Partition / 6761 6762 ; Device names that get printed by the boot sniffer... 6763 14253 VMAMSG: .TEXT /-VMA0/ 6764 14260 IDAMSG: .TEXT /-IDA0/ 6765 6766 ; System name message... 6767 14265 SYSNM1: .TEXT /SBC6120 ROM Monitor V/ 6768 14304 SYSNM2: .TEXT / Checksum / 6769 14314 SYSNM3: .TEXT / \d \h/ 6770 14332 SYSCRN: .TEXT /Copyright (C) 1983-2003 Spare Time Gizmos. All rights reserved./ 6771 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 169 Messages BTS6120.PLX 6772 ; RAM disk status message... 6773 14406 RAMMS1: .TEXT /NVR: / 6774 14413 RAMMS3: .TEXT /KB - Battery / 6775 14425 BOKMSG: .TEXT /OK/ 6776 14430 BFAMSG: .TEXT /FAIL/ 6777 6778 ; IDE disk status message... 6779 14434 IDEMS1: .TEXT /IDE: / 6780 14441 IDEMS2: .TEXT /MB - / 6781 14446 IDEMS3: .TEXT /Not detected/ 6782 14457 IDEMS4: .TEXT /Not supported/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 170 Help Text BTS6120.PLX 6783 .TITLE Help Text 6784 6785 6786 ; This table is used by the HELP command to generate a page of text 6787 ; describing the monitor commands. Each word is a pointer to a text string, 6788 ; also in field 1, which contains a single line of text, usually a description 6789 ; of one command. The table ends with a zero word. 6790 14471 HLPLST: 6791 ; Examine/Deposit commands... 6792 .DATA HLPEDC 14471 4564 6793 .DATA HLPE, HLPEP, HLPER, HLPD, HLPDP, HLPDR 14472 4610 14473 4652 14474 4715 14475 4742 14476 5006 14477 5053 6794 ; Memory commands... 6795 .DATA HLPNUL, HLPMEM 14500 4563 14501 5104 6796 .DATA HLPBM, HLPCK, HLPWS, HLPFM, HLPCM 14502 5117 14503 5154 14504 5211 14505 5250 14506 5302 6797 ; Breakpoint commands... 6798 .DATA HLPNUL, HLPBPC 14507 4563 14510 5331 6799 .DATA HLPBP, HLPBR, HLPBL, HLPP 14511 5347 14512 5373 14513 5422 14514 5444 6800 ; Program control commands... 6801 .DATA HLPNUL, HLPPCC 14515 4563 14516 5472 6802 .DATA HLPST, HLPC, HLPSI, HLPTR, HLPEX, HLPMR 14517 5513 14520 5550 14521 5573 14522 5616 14523 5643 14524 5677 6803 ; Disk commands... 6804 .DATA HLPNUL, HLPDSK 14525 4563 14526 5716 6805 .DATA HLPLP, HLPRD, HLPRL, HLPRF, HLPDD, HLPDL, HLPDF 14527 5730 14530 5755 14531 6012 14532 6036 14533 6061 14534 6120 14535 6146 6806 .DATA HLPPC, HLPPM, HLPB 14536 6236 14537 6173 14540 6275 6807 ; Other (miscellaneous) commands... PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 171 Help Text BTS6120.PLX 6808 .DATA HLPNUL, HLPMSC 14541 4563 14542 6325 6809 .DATA HLPTW, HLPTP, HLPVE, HLPSEM, HLPRP, HLPDOL 14543 6345 14544 6374 14545 6427 14546 6454 14547 6515 14550 6557 6810 ; Special control characters... 6811 .DATA HLPNUL, HLPCTL 14551 4563 14552 6604 6812 .DATA HLPCTS, HLPCTQ, HLPCTO, HLPCTC, HLPCTH, HLPRUB, HLPCTR, HLPCTU 14553 6621 14554 6660 14555 6716 14556 6751 14557 7004 14560 7055 14561 7122 14562 7155 6813 HLPNUL: .DATA 0 14563 0000 6814 6815 ; Examine/Deposit commands... 6816 14564 HLPEDC: .TEXT /EXAMINE AND DEPOSIT COMMANDS/ 6817 14610 HLPE: .TEXT /E aaaaa[-bbbbb] [, ccccc]\t-> Examine main memory/ 6818 14652 HLPEP: .TEXT /EP aaaaa[-bbbbb] [, ccccc]\t-> Examine panel memory/ 6819 14715 HLPER: .TEXT /ER [rr]\t\t\t\t-> Examine register/ 6820 14742 HLPD: .TEXT /D aaaaa bbbb, [cccc, ...]\t-> Deposit in main memory/ 6821 15006 HLPDP: .TEXT /DP aaaaa bbbb, [cccc, ...]\t-> Deposit in panel memory/ 6822 15053 HLPDR: .TEXT /DR xx yyyy\t\t\t-> Deposit in register/ 6823 6824 ; Memory commands... 6825 15104 HLPMEM: .TEXT /MEMORY COMMANDS/ 6826 15117 HLPBM: .TEXT /BM aaaaa-bbbbb ddddd\t\t-> Move memory block/ 6827 15154 HLPCK: .TEXT /CK aaaaa-bbbbb\t\t\t-> Checksum memory block/ 6828 15211 HLPWS: .TEXT /WS vvvv [aaaaa-bbbbb [mmmm]]\t-> Search memory/ 6829 15250 HLPFM: .TEXT /FM vvvv [aaaaa-bbbbb]\t\t-> Fill memory/ 6830 15302 HLPCM: .TEXT /CM [aaaaa-bbbbb]\t\t-> Clear memory/ 6831 6832 ; Breakpoint commands... 6833 15331 HLPBPC: .TEXT /BREAKPOINT COMMANDS/ 6834 15347 HLPBP: .TEXT /BP aaaaa\t\t\t-> Set breakpoint/ 6835 15373 HLPBR: .TEXT /BR [aaaaa]\t\t\t-> Remove breakpoint/ 6836 15422 HLPBL: .TEXT /BL\t\t\t\t-> List breakpoints/ 6837 15444 HLPP: .TEXT /P\t\t\t\t-> Proceed past breakpoint/ 6838 6839 ; Program control commands... 6840 15472 HLPPCC: .TEXT /PROGRAM CONTROL COMMANDS/ 6841 15513 HLPST: .TEXT /ST [aaaaa]\t\t\t-> Start main memory program/ 6842 15550 HLPC: .TEXT /C\t\t\t\t-> Continue execution/ 6843 15573 HLPSI: .TEXT /SI\t\t\t\t-> Single instruction/ 6844 15616 HLPTR: .TEXT /TR\t\t\t\t-> Trace one instruction/ 6845 15643 HLPEX: .TEXT /EX 6xxx\t\t\t\t-> Execute an IOT instruction/ 6846 15677 HLPMR: .TEXT /MR\t\t\t\t-> Master reset/ 6847 6848 ; Disk commands... 6849 15716 HLPDSK: .TEXT /DISK COMMANDS/ 6850 15730 HLPLP: .TEXT /LB\t\t\t\t-> Load a BIN paper tape/ 6851 15755 HLPRD: .TEXT /RD u [pppp [cccc]]\t\t-> Dump RAM disk page/ 6852 16012 HLPRL: .TEXT /RL u\t\t\t\t-> Download RAM disk/ 6853 16036 HLPRF: .TEXT /RF u\t\t\t\t-> Format RAM disk/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 172 Help Text BTS6120.PLX 6854 16061 HLPDD: .TEXT /DD pppp [bbbb [cccc]]\t\t-> Dump IDE disk block/ 6855 16120 HLPDL: .TEXT /DL pppp\t\t\t\t-> Download IDE disk/ 6856 16146 HLPDF: .TEXT /DF pppp\t\t\t\t-> Format IDE disk/ 6857 16173 HLPPM: .TEXT /PM [u] [pppp]\t\t\t-> Edit or review IDE partition map/ 6858 16236 HLPPC: .TEXT /PC ssss dddd\t\t\t-> Copy partition ssss to dddd/ 6859 16275 HLPB: .TEXT /B [dd]\t\t\t\t-> Boot RAM or IDE disk / 6860 6861 ; Other (miscellaneous) commands... 6862 16325 HLPMSC: .TEXT /MISCELLANEOUS COMMANDS/ 6863 16345 HLPTW: .TEXT /TW nn\t\t\t\t-> Set the console width/ 6864 16374 HLPTP: .TEXT /TP nn\t\t\t\t-> Set the console page length/ 6865 16427 HLPVE: .TEXT /VE\t\t\t\t-> Show firmware version/ 6866 16454 HLPSEM: .TEXT /aa; bb; cc; dd ...\t\t-> Combine multiple commands/ 6867 16515 HLPRP: .TEXT /RP [nn]; A; B; C; ...\t\t-> Repeat commands A, B, C/ 6868 16557 HLPDOL: .TEXT /!any text...\t\t\t-> Comment text/ 6869 6870 ; Special control characters... 6871 16604 HLPCTL: .TEXT /SPECIAL CHARACTERS/ 6872 16621 HLPCTS: .TEXT /Control-S (XOFF)\t\t-> Suspend terminal output/ 6873 16660 HLPCTQ: .TEXT /Control-Q (XON)\t\t\t-> Resume terminal output/ 6874 16716 HLPCTO: .TEXT /Control-O\t\t\t-> Suppress terminal output/ 6875 16751 HLPCTC: .TEXT /Control-C\t\t\t-> Abort current operation/ 6876 17004 HLPCTH: .TEXT /Control-H (Backspace)\t\t-> Delete the last character entered/ 6877 17055 HLPRUB: .TEXT /RUBOUT (Delete)\t\t\t-> Delete the last character entered/ 6878 17122 HLPCTR: .TEXT /Control-R\t\t\t-> Retype the current line/ 6879 17155 HLPCTU: .TEXT /Control-U\t\t\t-> Erase current line/ PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 173 Temporary Disk Buffer BTS6120.PLX 6880 .TITLE Temporary Disk Buffer 6881 6882 6883 ; The last two pages of field 1, addresses 17400 thru 17777, are used as a 6884 ; temporary disk buffer by the disk load, disk dump, disk format and boot 6885 ; commands. 6886 17400 .PAGE 36 6887 17400 DSKBUF: .BLOCK 128. 6888 17600 .PAGE 37 6889 17600 .BLOCK 128. 6890 6891 .END PALX - Program break is 20000 PALX - No errors detected PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 174 Memory Map BTS6120.PLX 00000/ 11111110 11110000 11111111 11111111 11111111 11111111 11111111 11111111 00100/ 11111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000 00200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 00300/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 00400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 00500/ 11111111 11111111 11111111 11111111 11111100 00011111 11111111 11111111 00600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 00700/ 11111111 11111111 11111111 11111111 11111111 11111000 00001111 11111111 01000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 01100/ 11111111 11111111 11111111 11111111 11110000 00000000 00001111 11111111 01200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 01300/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11011111 01400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 01500/ 11111111 11111111 11111111 11111111 11111100 00000000 00000000 00000111 01600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 01700/ 11111111 11111111 11111111 11111111 11111111 11111111 11110000 00111111 02000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 02100/ 11111111 11111111 11111111 11111111 11111111 11111111 11110000 01111111 02200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 02300/ 11111111 11111111 11111111 11111111 11111111 11111000 00000000 00000111 02400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 02500/ 11111111 11111111 11111111 11111111 11111100 00000000 00000001 11111111 02600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 02700/ 11111111 11111111 11111111 11111111 11100000 00000000 00000000 00111111 03000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 03100/ 11111111 11111111 11111111 11111111 11111111 11110000 01111111 11111111 03200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 03300/ 11111111 11111111 11111111 11111111 11111100 00000000 00000000 01111111 03400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 03500/ 11111111 11111111 11111111 11111111 11111111 11111111 10000001 11111111 03600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 03700/ 11111111 11111111 11111111 11111111 11111111 11111111 11111000 11111111 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 175 Memory Map BTS6120.PLX 04000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 04100/ 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00111111 04200/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 04300/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 04400/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 04500/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 04600/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 04700/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05000/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05100/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05200/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05300/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05400/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05500/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05600/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 05700/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 06000/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 06100/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 06200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 06300/ 11111111 11111111 11111111 11111111 11111111 11111000 00000000 11111111 06400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 06500/ 11111111 11111111 11111111 11111110 00000000 00000000 00000000 01111111 06600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 06700/ 11111111 11111111 11111111 11111111 11111111 11111000 00000000 11111111 07000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 07100/ 11111111 11111111 11111111 11111111 11100000 00000001 11111111 11111111 07200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 07300/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 07400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 07500/ 11111111 11111111 11111111 11111111 11111111 11111000 00111111 11111111 07600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 07700/ 11111111 11111111 11111100 00000000 00000000 00000000 00000001 11111111 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 176 Memory Map BTS6120.PLX 10000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10100/ 11111111 11111111 11111111 11111110 00000000 00000000 01111111 11111111 10200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10300/ 11111111 11111111 11111111 11111111 11110000 00001111 11111111 11111111 10400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10500/ 11111111 11111111 11111111 11111111 11111111 11111000 00000011 11111111 10600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10700/ 11111111 11111111 11111111 11111111 11111100 00000000 11111111 11111111 11000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11100/ 11111111 11111111 11111111 11111110 00000000 11111111 11111111 11111111 11200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11300/ 11111111 11111111 11111111 11111111 11111111 11111110 01111111 11111111 11400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11500/ 11111111 11111111 11111110 00000000 00000000 00000000 00011111 11111111 11600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11700/ 11111111 11111111 11111111 11111111 11100000 00000000 01111111 11111111 12000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 12100/ 11111111 11111111 11000000 00000000 00000000 00000000 00000011 11111111 12200/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 12300/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 12400/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 12500/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 12600/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 12700/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 13000/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 13100/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 13200/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 13300/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 13400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 13500/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 13600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 13700/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 177 Memory Map BTS6120.PLX 14000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14100/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14300/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14500/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 14700/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15100/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15300/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15500/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 15700/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16100/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16200/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16300/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16500/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 16700/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 17000/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 17100/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 17200/ 11110000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 17300/ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 17400/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 17500/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 17600/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 17700/ 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 178 Symbol Table BTS6120.PLX .ASCIZ -POP- 2721 .BLOCK -POP- 990 1146 1147 1148 1149 1150 1151 1152 1156 1157 1158 1159 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1177 1178 1179 1180 1181 1182 1183 1186 1187 1190 1191 1192 1193 1196 1197 1198 1240 1253 1257 1258 1259 1264 1460 1461 1911 2139 2140 2954 2999 3252 3253 3368 3439 3508 3624 4097 4494 4495 4619 4876 4877 4878 4879 4883 4884 4885 4886 4887 4888 4889 4890 4891 4895 4896 4897 4898 4899 4902 4903 4904 4905 4906 4907 4917 5332 5992 6037 6205 6370 6444 6887 6889 .DATA -POP- 6792 6793 6795 6796 6798 6799 6801 6802 6804 6805 6806 6808 6809 6811 6812 6813 .END -POP- 6891 .FIELD -POP- 782 984 4862 .HM6120 -POP- 56 .NOWARN -POP- 58 .ORG -POP- 1145 1155 1160 1248 4691 4872 4875 4880 4912 .PAGE -POP- 783 967 985 1130 1267 1432 1588 1735 1912 2062 2226 2398 2621 2835 2977 3129 3291 3444 3626 3707 3710 3875 4009 4186 4354 4497 4688 4909 5160 5352 5528 5869 6070 6227 6446 6578 6581 6886 6888 .POP -POP- 3831 4534 4559 4580 4584 .POPJ -POP- 1375 1392 1407 1423 1430 1498 1517 1539 1583 1651 1696 1742 1747 1752 1762 1767 1849 1861 1874 1885 1898 1954 2058 2134 2171 2192 2217 2224 2253 2266 2317 2346 2372 2555 2568 2709 2717 2775 2780 2788 2793 2819 2831 2879 2894 2962 3027 3277 3379 3617 3751 3771 3782 3858 3904 3912 3920 3947 3957 3966 3974 3985 3990 4007 4024 4040 4050 4057 4141 4184 4225 4232 4261 4265 4278 4352 4472 4511 4586 4611 4633 4656 4664 4672 4676 4684 4686 4841 5012 5033 5043 5143 5192 5197 5250 5294 5329 5350 5367 5404 5417 5441 5526 5554 5559 5768 5774 5837 5852 5881 5888 5899 5906 5989 6026 6034 6060 6068 6138 6202 6223 6255 6261 6281 6286 6314 6358 6363 6476 6491 6576 .PUSH -POP- 1452 1455 3823 4530 4548 4569 .PUSHJ -POP- 1052 1053 1058 1059 1074 1083 1084 1109 1113 1125 1276 1281 1285 1290 1318 1320 1321 1335 1337 1383 1400 1404 1414 1478 1481 1482 1483 1504 1505 1526 1527 1545 1549 1553 1557 1560 1576 1584 1585 1614 1628 1629 1630 1631 1634 1639 1643 1647 1648 1649 1659 1660 1686 1687 1690 1692 1693 1694 1712 1715 1716 1717 1719 1728 1729 1730 1731 1776 1777 1778 1779 1780 1784 1792 1867 1868 1879 1880 1893 1894 1903 1905 1906 1907 1931 1934 1935 1939 1940 1941 1945 1946 1948 1949 1973 1976 1986 1989 1992 2001 2022 2034 2046 2049 2050 2051 2055 2056 2059 2081 2098 2102 2105 2115 2116 2121 2122 2125 2128 2150 2151 2162 2163 2201 2236 2239 2240 2247 2260 2283 2288 2291 2298 2326 2335 2338 2354 2364 2379 2388 2392 2395 2407 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 179 Symbol Table BTS6120.PLX 2429 2430 2447 2450 2500 2505 2506 2507 2508 2519 2531 2534 2585 2592 2593 2738 2741 2742 2743 2747 2752 2758 2761 2773 2778 2786 2791 2807 2808 2814 2815 2851 2854 2855 2864 2867 2868 2869 2888 2900 2974 3039 3044 3050 3065 3066 3077 3083 3097 3115 3124 3155 3161 3169 3192 3204 3221 3239 3248 3288 3319 3326 3338 3341 3342 3353 3356 3357 3361 3372 3387 3411 3418 3419 3429 3474 3475 3477 3478 3479 3490 3498 3543 3556 3570 3583 3596 3605 3636 3639 3640 3643 3649 3650 3698 3752 3760 3772 3783 3794 3828 3853 3868 3872 3885 3887 3888 3901 3907 3915 3932 3933 3939 3944 4022 4025 4033 4034 4109 4133 4155 4176 4220 4243 4244 4249 4250 4273 4319 4333 4350 4388 4391 4412 4424 4425 4427 4429 4430 4438 4439 4449 4450 4451 4467 4468 4478 4480 4483 4490 4533 4558 4570 4630 4642 4651 4652 4850 4852 4855 4857 4858 4859 4951 4953 4972 5117 5118 5125 5130 5136 5138 5169 5172 5181 5184 5468 5766 5772 5879 5882 5886 5897 5900 5904 5908 6249 6275 6304 6305 6356 6459 6472 6528 6538 6543 6553 6558 .SIXBIT -POP- 6593 6595 6597 6599 6601 6603 6605 6607 6609 6611 6613 6615 6617 6619 6621 6623 6625 6627 6629 6631 6633 6635 6637 6639 6641 6643 6645 6647 6649 6651 6653 6655 6657 6659 6661 6663 6672 6674 6676 6678 6680 6687 6689 6691 6693 6695 6701 6703 .STACK -POP- 57 .TEXT -POP- 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6723 6724 6725 6726 6727 6728 6731 6732 6733 6734 6737 6738 6739 6740 6741 6742 6743 6744 6747 6748 6749 6750 6751 6754 6755 6759 6760 6763 6764 6767 6768 6769 6770 6773 6774 6775 6776 6779 6780 6781 6782 6816 6817 6818 6819 6820 6821 6822 6825 6826 6827 6828 6829 6830 6833 6834 6835 6836 6837 6840 6841 6842 6843 6844 6845 6846 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6862 6863 6864 6865 6866 6867 6868 6871 6872 6873 6874 6875 6876 6877 6878 6879 .TITLE -POP- 1 59 123 605 674 723 760 968 1131 1265 1309 1339 1376 1433 1469 1499 1540 1564 1589 1662 1701 1736 1769 1835 1913 1959 2008 2063 2142 2193 2227 2267 2318 2347 2373 2399 2432 2486 2521 2569 2622 2693 2722 2794 2836 2910 2978 3052 3089 3130 3254 3292 3389 3445 3509 3627 3708 3711 3785 3803 3833 3876 3897 3921 3958 4010 4058 4098 4142 4187 4233 4266 4308 4355 4498 4620 4689 4863 4910 4987 5013 5035 5044 5099 5144 5161 5198 5251 5295 5333 5353 5405 5448 5529 5560 5641 5705 5736 5838 5853 5870 5917 5941 5993 6038 6071 6139 6206 6228 6287 6371 6411 6447 6505 6579 6582 6667 6707 6783 6880 .VECTOR -POP- 4704 ACNAME 14057 1799 2617 6737* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 180 Symbol Table BTS6120.PLX ADDR 00020 1163* 1621 1635 1869 1882 2037 2084 2156 2159 2208 2244 2251 2252 2287 2311 2332 2360 2386 3179 3222 3228 3886 3903 3908 3916 3941 3965 3988 3997 4000 ADRFLD 00021 1164* 1844 2038 2085 2158 2213 2315 2334 2362 2384 2511 2514 3180 3238 3884 3910 3918 3943 3967 3973 3981 4003 4006 4219 4231 ALPHA 06627 4025 4034 4045* ALPHA1 06635 4048 4053* AND 0000 964 1620 1623 1636 1756 1759 1845 2110 2117 2383 2713 2857 2971 3036 3185 3195 3199 3215 3233 3237 3493 3593 3694 3735 3740 3748 3800 3852 3895 3972 4171 4211 4218 4230 4275 4631 4791 4854 4978 5004 5123 5221 5224 5236 5242 5279 5284 5325 5485 5501 5793 5796 5825 5831 5960 5965 6022 6055 6107 6169 6172 6320 6436 6462 6466 6531 6546 ARGPTR 10053 4903* 5000 5009 BACKS1 07141 4347 4351* BACKUP 00542 1212 1427* BANKSZ 0025 5095* 5377 5386 BATTMP 10551 5319 5320 5323 5332* BATTOK 10026 1078 4887* 5315 5327 5349 BATTST 10531 1071 5314* BFAMSG 14430 1081 6776* BINCH1 03323 3191 3194 3211 3214 3252* BINCH2 03324 3193 3198 3212 3253* BINLO1 03203 3159* 3164 3249 BINLO2 03205 3161* 3166 BINLO3 03214 3169* 3172 BINLO5 03227 3183* 3224 3229 3241 BINLO6 03276 3217 3227* BINLO7 03301 3187 3232* BINLO8 03314 3209 3235 3244* BLIST 01674 2150* 6620 BLIST1 01701 2155* 2166 BLIST2 01715 2161 2165* BMOVE 01400 1931* 6610 BNAMES 13542 2746 6701* BOKMSG 14425 1081 1082 6775* BOOKEY 02421 2702 2721* BOOT 02426 2738* 6660 BOOT1 02452 2740 2758* BOOTGO 02445 2752* 2760 2763 BOOTS 00406 1279* 1304 BOOTS1 00413 1285* 1298 1308 BOOTS2 00423 1288 1293* BPT 6236 636* 2337 4803 4806 BPTADR 00201 1257* 1260 2183 BPTCL2 02030 2261* 2265 BPTCLR 02026 1053 2238 2260* BPTCO1 02054 2293 2298* BPTCO2 02056 2299* 2304 BPTCO3 02066 2302 2309* BPTCOM 02036 2283* 6622 BPTDAT 00221 1259* 2187 BPTEND 0210 1260* BPTFLD 00211 1258* 2185 BPTFN1 01741 2204* 2222 BPTFN2 01757 2206 2210 2220* BPTFN3 01760 2215 2221* BPTFND 01737 2201* 2247 2291 BPTIN1 02101 2329* 2345 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 181 Symbol Table BTS6120.PLX BPTIN2 02116 2331 2342* BPTIN3 02120 2339 2344* BPTINS 02077 2326* 2450 BPTMSG 13713 4816 6723* BPTRM1 02125 2357* 2371 BPTRM2 02137 2359 2368* BPTRM3 02141 2365 2370* BPTRMV 02123 2354* 4859 BPTTRP 07672 4805 4815* BREMO1 02024 2249 2256* BREMOV 02000 2236* 6624 BRKMSG 13750 4778 6725* BSETUP 01724 2151 2182* 2201 2260 2298 2326 2354 BSW 7002 672 3196 3736 3741 3793 4029 4229 5234 5280 5387 5958 6105 6173 6469 BTIDA0 02500 2761 2784* 6704 BTSTRP 07640 4753 4777* BTVMA0 02464 2758 2771* 6702 BUFCDF 12035 5154 5232 5262 5862 6097 6163 6464 6486 6498* 6504 BUFPNL 10055 4905* 5155 5863 6475 6490 6501 BUFPTR 10011 4877* 5152 5238 5244 5263 5265 5778 5794 5797 5860 6100 6176 6474 6484 BUFSIZ 10056 4906* 5878 5889 5896 5907 6090 6116 6156 6182 BUFTMP 11512 6101 6102 6104 6170 6175 6205* CAF 6007 2548 CAM 7621 3183 CCFMSG 14205 3647 6754* CDF 6201 861 889 898 946 1077 1079 1103 1106 1554 1556 1579 1581 1846 1873 1884 2827 2829 2875 2878 2906 2908 2929 2939 2947 2963 2966 2989 2992 3009 3022 3028 3031 3043 3047 3049 3067 3069 3098 3100 3109 3112 3118 3121 3327 3334 3343 3348 3373 3376 3382 3420 3425 3430 3434 3471 3473 3482 3484 3585 3590 3657 3659 3665 3667 3678 3680 3688 3695 3702 3724 3749 3778 3780 4077 4093 4799 4969 4971 4973 4998 5005 5011 5153 5229 5246 5290 5421 5508 5861 6133 6199 6463 6485 6532 6547 6574 CFIELD 01302 1843* 1867 1879 CHBEL 0007 641* 4292 CHBSP 0010 642* 4349 4443 4455 CHCRT 0015 645* 4318 4455 4458 CHCTC 0003 640* 4636 4641 4646 CHCTO 0017 646* 4646 4650 4659 CHCTR 0022 648* 4419 4423 4434 CHCTU 0025 650* 4434 4437 4443 CHDEL 0177 652* CHESC 0033 651* 4461 4466 4523 4535 CHKSUM 00031 1172* 1978 1981 1985 1987 1988 1998 2006 3177 3210 3213 3246 3247 3468 3487 3488 3503 3539 3588 3589 3608 CHLFD 0012 644* 4338 4458 4461 CHNUL 0000 639* CHTAB 0011 643* 1354 1356 1357 4517 4523 CHXOF 0023 649* 4659 4667 CHXON 0021 647* 4667 4675 CIA 7041 956 1895 2111 2207 2212 2710 3011 3245 3359 3558 3572 3607 3987 4083 4328 4554 5321 5435 6470 6559 CKBOO1 02404 2706* 2718 CKBOOT 02400 2702* 2773 2786 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 182 Symbol Table BTS6120.PLX CKMEM 01442 1973* 6612 CKMEM1 01452 1981* 1993 CKSMSG 13550 2005 6710* CLA 7200 655 656 657 658 659 660 661 662 664 666 668 669 670 671 672 673 792 803 852 862 890 899 1003 1037 1080 1101 1273 1279 1287 1297 1316 1334 1347 1386 1389 1405 1418 1421 1453 1456 1479 1496 1610 1637 1653 1682 1698 1713 1775 1843 1856 1859 1897 1942 1999 2035 2047 2096 2100 2119 2133 2160 2170 2182 2209 2214 2237 2292 2301 2501 2560 2590 2598 2612 2716 2739 2816 2830 2852 2858 2865 2892 2959 2972 3013 3018 3037 3103 3163 3186 3208 3216 3234 3268 3275 3339 3354 3494 3501 3546 3560 3568 3574 3578 3594 3597 3609 3612 3651 3696 3758 3824 3883 3935 3946 3964 3980 3984 3989 3994 4020 4085 4106 4116 4137 4139 4152 4162 4180 4182 4209 4215 4221 4224 4260 4264 4276 4281 4286 4291 4296 4301 4317 4330 4351 4403 4409 4447 4462 4476 4531 4550 4556 4571 4573 4576 4585 4610 4682 4838 4840 4958 4997 5031 5126 5131 5134 5142 5191 5209 5257 5326 5348 5363 5366 5399 5403 5413 5416 5439 5475 5486 5495 5499 5502 5513 5523 5553 5719 5836 5850 5926 5936 5953 6025 6033 6058 6137 6201 6214 6222 6254 6280 6311 6313 6329 6426 6500 6502 6575 CLL 7100 657 658 659 660 661 662 664 669 1982 2223 2512 2513 2706 2779 2792 2935 3005 3737 3742 3814 3845 3956 3964 3980 4121 4124 4125 4260 4956 5031 5191 5235 5240 5241 5249 5281 5285 5286 5293 5348 5363 5376 5390 5403 5413 5419 5420 5438 5551 5836 5850 6018 6033 6051 6137 6174 6201 6214 6252 6277 6313 6529 6544 6575 CLRCOM 02270 2531* 6644 CLRCPU 02304 1052 2508 2519 2534 2560* 2752 CLRDRD 0006 5667* 5798 5811 6177 6191 6438 CLRDRE 0012 5671* 5730 CLRDWR 0010 5669* 6111 6125 6402 CMA 7040 659 661 662 664 666 810 2943 2970 3035 3693 3982 3987 4554 4654 6033 6313 CMDBUF 00231 1264* 1319 4382 4428 4470 CMDEDD 0220 5699* CMDIDD 0354 5700* 5769 CMDLEN 07356 4384 4407 4415 4446 4475 4485 4486 4494* CMDRDS 0040 5701* 5883 CMDSDN 0340 5704* 5937 CMDSUP 0341 5703* 5927 CMDTBL 13400 1289 6592* CMDWRS 0060 5702* 5901 CMEM 01507 2034* 6616 CMEM0 01512 2024 2036* CMEM1 01534 2048 2054* 2060 CML 7020 657 658 660 2935 3005 3945 3970 3982 4055 5191 5440 6024 6033 6057 6313 COMERR 00441 1223 1316* 6666 6683 6698 6706 CONCHR 07476 4602 4608 4619* CONF1 07027 4244* 4246 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 183 Symbol Table BTS6120.PLX CONF2 07052 4256 4259 4264* CONFRM 07025 2815 3650 4243* CONGE1 03330 3273* 3284 3286 CONGE2 03335 3274 3282* CONGET 03325 3161 3169 3192 3204 3239 3268* CONIN 07550 4630 4682* CONLOD 03200 3155* 6646 CONOU1 07465 4606* 4615 CONOU2 07467 4608* 4616 CONOU3 07473 4607 4614* CONOUT 07463 4581 4602* CONT 02216 2431 2450* 2516 2520 2755 CONT1 02222 2422 2465* 4982 CONTCM 02214 2447* 6626 COUNT 00047 1192* 1944 1952 2108 2124 2132 2165 2190 2221 2264 2303 2344 2370 2604 2607 2611 2861 2872 2887 2889 2890 2899 2903 2936 2945 3006 3020 3160 3165 3465 3476 3491 3492 3499 3536 3544 3573 3591 3592 CP1MSG 14224 3656 6755* CP2MSG 4151 3704 6756* CPANEL 01311 1856* 1868 1880 CPBOOT 07600 4704 4705* CPD 6266 916 924 1860 2711 4795 5008 6503 6534 6536 6549 6551 CPSAVE 07602 1045 4722* CPYDST 0024 1200* 3642 3648 3677 CPYSRC 0023 1199* 3638 3664 CRLF 07104 1208 4317* CRLF1 07127 4327 4331 4338* CS1FX 0100 5677* 5679 5680 5681 5682 5683 5684 5685 5686 5687 CS3FX 0200 5678* CTRLO 00034 1177* 4386 4396 4572 4639 4653 4655 CXF 6203 938 1035 1458 4705 4740 4807 4810 4981 4985 5042 DAC 01200 1740* 6688 DANDV 01343 1221 1891* DCA 3000 805 807 819 821 823 825 827 829 853 857 891 915 917 947 949 951 954 1046 1050 1051 1104 1282 1294 1305 1307 1317 1373 1429 1447 1449 1490 1494 1497 1516 1538 1578 1611 1621 1625 1683 1741 1746 1751 1761 1790 1847 1870 1878 1882 1891 1936 1944 1977 1978 1985 1988 2036 2037 2038 2040 2042 2043 2083 2084 2085 2087 2089 2091 2092 2104 2108 2112 2124 2152 2156 2158 2184 2186 2188 2190 2191 2244 2251 2252 2261 2262 2263 2287 2310 2312 2314 2316 2332 2334 2336 2360 2362 2384 2386 2387 2389 2421 2451 2467 2510 2515 2561 2562 2563 2564 2565 2567 2587 2588 2604 2608 2703 2705 2754 2812 2861 2874 2877 2887 2905 2930 2931 2936 2938 2941 2944 2990 2991 3006 3008 3068 3071 3074 3076 3080 3082 3099 3106 3111 3114 3120 3123 3156 3160 3174 3177 3179 3180 3191 3193 3201 3205 3213 3228 3238 3240 3247 3270 3313 3315 3321 3323 3329 3331 3332 3333 3335 3345 3347 3350 3360 3383 3405 3407 3413 3415 3422 3424 3431 3433 3464 3465 3467 3468 3485 3488 3533 3535 3536 3538 3539 3565 3586 3589 3638 3642 3658 3666 3679 3719 3721 3730 3733 3768 3777 3791 3809 3810 3839 3841 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 184 Symbol Table BTS6120.PLX 3847 3850 3863 3903 3909 3911 3917 3919 3941 3943 3953 3955 3973 3998 4000 4004 4006 4021 4030 4039 4076 4092 4107 4108 4122 4129 4153 4154 4167 4174 4219 4231 4247 4320 4332 4335 4348 4381 4383 4384 4385 4386 4394 4395 4396 4397 4414 4422 4469 4471 4486 4602 4603 4639 4640 4649 4655 4663 4670 4671 4722 4724 4726 4728 4730 4742 4789 4793 4797 4954 4962 4964 4974 4976 4980 5000 5006 5119 5124 5152 5154 5155 5156 5157 5211 5222 5225 5227 5238 5244 5259 5264 5266 5275 5277 5282 5288 5315 5319 5322 5327 5374 5388 5393 5422 5433 5436 5466 5467 5479 5481 5496 5509 5517 5549 5557 5720 5778 5780 5794 5797 5806 5826 5833 5860 5862 5863 5864 5865 5878 5896 5961 6014 6015 6090 6092 6101 6156 6158 6170 6176 6216 6217 6219 6248 6250 6258 6260 6276 6284 6306 6322 6324 6332 6388 6437 6460 6464 6471 6474 6475 6484 6486 6488 6490 6533 6537 6540 6548 6552 6555 6560 6568 DDBUF 03600 3372 3464* DDBUF2 03605 3471* 3502 DDBUF3 03623 3482* 3495 DDCNT 03652 3464 3500 3508* 3533 3545 DDDUMP 03405 3319* 6648 DDUMP1 03463 3340 3355 3364* 3378 DECNW 06662 1482 1504 1526 4106* DECNW1 06667 4112* 4134 DECNW2 06713 4114 4117 4137* DERCKS 03762 3610 3620* DFRMAT 03072 3065* 6656 DIGITS 00050 1193* 3721 3725 3730 3810 3818 3825 3841 3856 4108 4132 4138 4154 4175 4181 4222 DIOERR 03504 2956 3001 3370 3382* 3441 3672 3685 DISKID 11034 1100 5766* DISKIO 11700 6332 6356 6367 6370* DISKRD 11200 3081 3320 3670 5867 5878* 6330 DISKRW 11634 5022 6304* DISKWR 11220 3075 3412 3683 5896* 6330 6331 DKPART 10036 3068 3329 3424 3666 3679 4895* 5864 5962 5969 6217 6218 6220 6224 6248 6259 6324 DKRBN 10037 1237 3689 3694 4896* 5865 5954 5957 6306 6359 DKRW0 11646 6312 6319* DKRW1 11661 6352* 6362 DKRW2 11676 6354 6366* DKSIZE 10040 1105 2828 4897* 5720 5826 5832 5833 5851 6310 DKUNIT 10041 4898* 6250 6251 6256 6276 6279 6282 DLLOAD 03521 3411* 6652 DLOAD 03527 3408 3418* DLOAD1 03541 3428* 3442 DMEM 01067 1682* 6602 DMEM1 01075 1690* 1700 DMQ 01206 1750* 6692 DNAMES 13526 1732 6687* DPC 01203 1745* 6690 DPMEM 01065 1679* 6604 DPS 01211 1755* 6694 DREG 01132 1728* 6608 DRVERR 11353 6020 6053 6065* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 185 Symbol Table BTS6120.PLX DSKBUF 17400 1104 1112 2937 3007 3466 3534 5777 5822 5827 6483 6887* DSR 01221 1765* 6696 DSTCDF 12111 6548 6566* DSTSPD 12112 6552 6567* EMEM 01002 1610* 6598 EMEM0 01004 1614* 1655 EMEM1 01017 1628* 1640 EMEM2 01021 1629* 1638 EMEM3 01044 1633 1647* ENAMES 13512 1718 6672* EOLNXT 00523 1214 1400* EOLTST 00525 1213 1404* EONE 01042 1616 1643* EPMEM 01000 1607* 6600 EREG 01114 1712* 6606 ERRAST 14036 2295 6733* ERRBTF 14047 2306 6734* ERRCKS 13661 3621 6718* ERRDIO 13650 3385 6717* ERRDSK 14156 3046 6751* ERRILV 13576 1521 2601 2823 2883 6712* ERRNBP 14021 2173 6731* ERRNBT 13674 2767 6719* ERRNDK 13705 2833 6720* ERRNST 14030 2257 6732* ERROR 00453 1224 1333* 1336 ERRRAN 13621 3949 6714* ERRSRF 13610 2136 6713* ERRWRP 13632 1958 6715* F1ADDR 00616 1449 1460* FCFMSG 14111 2810 6747* FLDTS1 10117 950* 953 FLDTS2 10124 955* 961 FLDTST 10112 925 932 945* 965 FLMEM 01503 2022* 6618 FM1MSG 14131 2928 6748* FM2MSG 14140 2988 6749* FM3MSG 14151 3087 6750* 6756 FMTARG 02514 2807* 3066 3097 FMTCNT 00053 1198* 2940 2942 2960 2971 3010 3016 3025 3036 3074 3080 3111 3120 FMTP1 02671 2927* 3077 3115 FMTP11 02676 2934* 2973 2975 FMTP12 02704 2940* 2946 FMTP2 03000 2987* 3083 3124 FMTP21 03006 2995* 3038 3040 FMTP22 03023 3010* 3021 FMTP23 03040 3025* 3051 FMTP29 03057 3014 3019 3043* FMTRDP 03012 2999* 3082 3123 FMTWRP 02720 2954* 3076 3114 FRDONE 03115 3086* 3127 FTCONT 0310 3266* 3269 FUNTBL 10261 4961 5018* 5027 GCF 6256 4723 GET 00463 1215 1347* GET1 00503 1351 1367* GET2 00507 1364 1373* GETARG 10241 4951 4953 4997* 5118 6249 6275 6305 6459 6472 6528 6538 6543 6553 6558 GETBAT 10552 5021 5348* GETDKS 11123 5023 5850* GETPMP 11617 5025 6275* GETRDS 11000 5020 5549* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 186 Symbol Table BTS6120.PLX GETVER 10272 5018 5031* GOOD 01371 1891 1892 1896 1904 1911* HALTED 07676 4762 4838* HELLO 00711 1059 1546* HELP 00737 1576* 6594 HELP1 00743 1579* 1586 HGHFLD 00025 1168* 2042 2089 3911 3955 3983 HIGH 00023 1166* 1199 1622 1625 2040 2087 3909 3953 3986 HLPB 16275 6806 6859* HLPBL 15422 6799 6836* HLPBM 15117 6796 6826* HLPBP 15347 6799 6834* HLPBPC 15331 6798 6833* HLPBR 15373 6799 6835* HLPC 15550 6802 6842* HLPCK 15154 6796 6827* HLPCM 15302 6796 6830* HLPCTC 16751 6812 6875* HLPCTH 17004 6812 6876* HLPCTL 16604 6811 6871* HLPCTO 16716 6812 6874* HLPCTQ 16660 6812 6873* HLPCTR 17122 6812 6878* HLPCTS 16621 6812 6872* HLPCTU 17155 6812 6879* HLPD 14742 6793 6820* HLPDD 16061 6805 6854* HLPDF 16146 6805 6856* HLPDL 16120 6805 6855* HLPDOL 16557 6809 6868* HLPDP 15006 6793 6821* HLPDR 15053 6793 6822* HLPDSK 15716 6804 6849* HLPE 14610 6793 6817* HLPEDC 14564 6792 6816* HLPEP 14652 6793 6818* HLPER 14715 6793 6819* HLPEX 15643 6802 6845* HLPFM 15250 6796 6829* HLPLP 15730 6805 6850* HLPLST 14471 1577 6790* HLPMEM 15104 6795 6825* HLPMR 15677 6802 6846* HLPMSC 16325 6808 6862* HLPNUL 14563 6795 6798 6801 6804 6808 6811 6813* HLPP 15444 6799 6837* HLPPC 16236 6806 6858* HLPPCC 15472 6801 6840* HLPPM 16173 6806 6857* HLPRD 15755 6805 6851* HLPRF 16036 6805 6853* HLPRL 16012 6805 6852* HLPRP 16515 6809 6867* HLPRUB 17055 6812 6877* HLPSEM 16454 6809 6866* HLPSI 15573 6802 6843* HLPST 15513 6802 6841* HLPTP 16374 6809 6864* HLPTR 15616 6802 6844* HLPTW 16345 6809 6863* HLPVE 16427 6809 6865* HLPWS 15211 6796 6828* HLT 7402 2419 HLTMSG 13773 4843 6727* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 187 Symbol Table BTS6120.PLX HPOS 00036 1179* 4274 4320 4345 4348 4549 4555 IAC 7001 656 668 669 670 671 672 673 792 852 890 1451 1984 3017 3282 3982 5191 5484 5727 IDAMSG 14260 2790 6764* IDBOOT 11126 2785 5859* IDDEV1 11057 5790* 5801 IDDEV2 11075 5807* 5814 IDEINI 11013 1096 2552 5719* IDEINP 0222 5664* 5721 5781 6135 6159 6408 6427 IDEMS1 14434 1094 6779* IDEMS2 14441 1111 6780* IDEMS3 14446 1124 6781* IDEMS4 14457 1119 6782* IDEOUT 0200 5665* 6093 6389 IDERDR 11721 6016 6049 6065 6425* 6429 6430 6441 IDETMP 11742 6388 6398 6437 6440 6444* IDEWRR 11701 5733 5770 5884 5902 5928 5938 5955 5967 5972 5982 5987 6387* 6391 6392 6410 ILLPR0 07674 4819* 4986 INCH10 07353 4410 4490* INCHR1 07515 4638 4646* INCHR2 07532 4648 4659* INCHR3 07540 4661 4667* INCHR4 07546 4669 4675* INCHRS 07477 2115 4244 4391 4570 4630* INCHW1 07211 4391* 4393 4416 4431 4448 4477 4487 4491 INCHW2 07230 4407* 4463 INCHW3 07243 4401 4419* INCHW4 07265 4421 4434* INCHW5 07276 4436 4443* INCHW6 07313 4445 4455* INCHW7 07327 4457 4460 4468* INCHW8 07335 4404 4475* INCHW9 07345 4452 4483* INCHWL 07200 1281 3543 4381* 4440 INIPM1 11517 6218* 6225 INIPMP 11513 1055 2554 6214* INLMES 06237 1209 3757* 3759 3761 3762 IRMA 00042 1183* 3270 3285 4603 4614 IRNAME 14070 1814 6740* ISZ 2000 858 893 919 952 960 1952 2164 2165 2220 2221 2264 2299 2303 2342 2343 2344 2368 2369 2370 2607 2889 2945 2960 2964 2965 3020 3025 3029 3030 3165 3222 3285 3374 3375 3377 3491 3562 3591 3689 3725 3761 3818 3856 3965 4087 4132 4175 4323 4415 4549 4614 5001 5139 5140 5247 5291 5380 5520 5800 5813 6027 6029 6113 6116 6127 6179 6182 6193 6224 6352 6359 6361 6392 6430 6569 JMP 5000 795 812 859 863 894 896 900 920 927 934 939 953 959 961 965 1006 1010 1013 1022 1025 1098 1102 1108 1114 1120 1128 1288 1298 1304 1308 1322 1338 1351 1364 1390 1406 1422 1459 1480 1508 1511 1514 1530 1533 1536 1563 1586 1616 1633 1638 1640 1654 1655 1661 1699 1700 1714 1720 1733 1781 1785 1794 1908 1933 1951 1953 1975 1991 1993 2000 2007 2024 2048 2060 2097 2101 2120 2127 2129 2161 2166 2206 2210 2215 2222 2238 2243 2249 2265 2286 2293 2302 2304 2331 2339 2345 2359 2365 2371 2396 2422 2431 2479 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 188 Symbol Table BTS6120.PLX 2502 2516 2520 2547 2591 2599 2613 2619 2718 2740 2749 2755 2760 2763 2817 2853 2859 2866 2893 2909 2946 2956 2973 2975 3001 3014 3019 3021 3038 3040 3051 3088 3104 3127 3164 3166 3172 3187 3209 3217 3224 3229 3235 3241 3249 3274 3284 3286 3289 3316 3340 3355 3370 3378 3388 3408 3441 3442 3495 3502 3504 3547 3561 3563 3569 3575 3579 3595 3598 3599 3610 3613 3652 3672 3685 3691 3697 3699 3705 3726 3744 3753 3762 3773 3784 3802 3817 3819 3827 3832 3857 3865 3869 3873 3889 3896 3936 4027 4036 4048 4082 4086 4088 4094 4114 4117 4134 4140 4160 4163 4177 4183 4212 4246 4256 4259 4277 4283 4288 4293 4298 4303 4307 4327 4331 4339 4347 4393 4401 4404 4410 4416 4421 4431 4436 4440 4445 4448 4452 4457 4460 4463 4477 4487 4491 4514 4519 4520 4525 4527 4536 4553 4557 4574 4577 4581 4607 4615 4616 4638 4643 4648 4661 4669 4706 4753 4756 4759 4762 4805 4809 4860 4959 4982 4986 5127 5132 5135 5137 5141 5158 5171 5174 5175 5183 5186 5187 5248 5292 5379 5381 5447 5487 5512 5524 5729 5735 5801 5814 5867 5890 5916 5930 5940 6020 6028 6030 6053 6059 6115 6117 6128 6181 6183 6194 6225 6312 6354 6362 6367 6410 6441 6504 6570 JMS 4000 925 932 1054 1068 1070 1072 1075 1093 1095 1099 1110 1118 1123 1520 1546 1550 1558 1561 1798 1803 1808 1813 1818 1823 1828 1833 1901 1957 2004 2135 2172 2256 2294 2305 2551 2553 2600 2614 2616 2766 2771 2776 2784 2789 2809 2822 2832 2882 2897 2901 2927 2950 2953 2987 2995 2998 3045 3086 3101 3364 3367 3384 3435 3438 3620 3646 3655 3662 3669 3675 3682 3703 3948 4769 4777 4811 4815 4819 4842 5218 5232 5262 5272 5476 5733 5770 5884 5902 5928 5938 5955 5967 5972 5982 5987 6016 6049 6065 6097 6163 KCC 6032 616* 1020 KEY 01672 2083 2109 2112 2118 2139* KRB 6036 618* 3276 4685 KRS 6034 617* KSF 6031 615* 1023 3273 4683 L 00013 1159* 1293 1307 1317 1348 1428 1429 1493 4383 4414 4422 4469 4471 4479 LAS 7604 1832 LBATMP 11310 5961 5966 5992* LDAR 6410 5098* 5316 5402 5474 5494 5498 LDBUF 03653 3429 3533* LDBUF2 03662 3542* 3599 LDBUF3 03704 3561 3566* LDBUF4 03723 3583* 3595 LDBUF5 03746 3547 3605* LDPAGE 03764 3538 3559 3562 3565 3616 3624* LENGTH 00041 1051 1182* 1538 4325 LOW 00024 1167* 1200 1619 2310 2312 2314 2316 3917 3940 3952 3995 3998 LOWFLD 00026 1169* 3919 3942 3954 4001 4004 LSP1 6217 1039 1275 2470 4739 LSP2 6237 2472 MASK 01673 2091 2104 2110 2117 2140* MATCH 06642 1290 1719 1733 2747 4076* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 189 Symbol Table BTS6120.PLX MATCH1 06644 4080* 4088 MATCH2 06655 4082 4086 4091* MATCH3 06661 4092 4094 4097* MAXBPT 0010 1256* 1257 1258 1259 1260 2189 MAXCMD 0147 1263* 1264 4408 MAXFUN 0010 4957 5027* MCALL 10201 4809 4951* MCALL1 10225 4973* MCALL2 10237 4959 4985* MEMMOV 12044 5026 6528* MEMMSG 13561 1902 6711* MEMTS1 10100 925* 927 MEMTS2 10105 932* 934 MM0 6400 719* MM1 6401 720* 854 MM2 6402 721* 856 5228 5289 5328 5507 MM3 6403 722* 5219 5273 5317 5477 MOVE1 01411 1939* 1953 MOVE2 01440 1951 1957* MQA 7501 1760 3200 3743 3999 4005 4725 MQL 7421 1757 2474 3197 3738 3996 4002 MQNAME 14065 1809 6739* MUUO 10052 4902* 4954 4955 4960 4962 4963 4964 4972 4976 4979 5122 5133 6319 6328 6460 6461 6465 NAME 00030 1171* 1286 4021 4030 4038 4039 4084 NAMENW 06600 1285 1716 1728 2742 4020* NL0000 7200 655* NL0001 7201 656* 5986 NL0002 7326 657* 5195 NL0003 7325 668* 3287 NL0004 7307 669* NL0006 7327 670* NL0010 7215 673* NL0100 7203 672* NL2000 7332 658* NL3777 7350 659* 1489 4977 NL4000 7330 660* 6468 NL5777 7352 661* NL6000 7333 671* NL7775 7346 662* 663 NL7776 7344 664* 665 NL7777 7240 666* 667 2704 6489 NLM1 7240 667* 3349 NLM2 7344 665* 3731 6487 NLM3 7346 663* 3720 3729 3864 NOBOOT 02462 2749 2766* NODISK 02537 2827* 3065 3319 3411 NOP 7000 948 2606 3223 4324 4794 5002 5007 5446 5809 5810 6360 6434 6499 6563 6564 6566 6567 NOUNIT 02535 2822* 3104 NXTADR 06473 1219 3964* OCTN1 06725 4158* 4177 OCTN2 06750 4160 4163 4180* OCTNF 07004 3901 4215* OCTNF1 07010 4212 4219* OCTNI 07000 2240 2283 2506 4209* OCTNW 06720 1216 4152* OUTCH1 07411 4519 4523* OUTCH2 07416 4525 4530* OUTCH3 07426 4514 4539* OUTCHR 07400 1203 4510* OUTST1 06204 3724* 3753 OUTST2 06227 3726 3747* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 190 Symbol Table BTS6120.PLX OUTST3 06230 3744 3748* OUTSTR 06200 1083 1337 1584 1792 3718* 3760 4852 PAC1 6215 57 PACK 10471 5136 5187 5257* PACK1 10474 5262* 5292 PARMAP 10042 2873 2904 4899* 6215 6257 6283 6321 PARSDX 03413 3316 3326* PCNAME 14062 1804 6738* PCOPY 04000 3636* 6664 PCOPY1 04032 3662* 3697 3699 PCOPY2 04045 3675* PCOPY3 04060 3688* PCOPY4 04075 3691 3702* PEX 6004 2478 PGO 6003 2418 2452 PM1MSG 14233 2898 6759* PM2MSG 14240 2902 6760* PMALL 02642 2853 2887* 2893 PMEDI1 02640 2859 2882* PMEDIT 02600 2851* 6662 PMSHOW 02653 2866 2888 2897* PNLBUF 12024 2951 2996 3365 3436 3663 3676 6483* PNLCDF 07656 4792 4799* PNLMEM 00022 1165* 1611 1683 1858 1936 1977 2043 2092 2191 2387 3156 PNLTRP 07642 4756 4787* POP1 6235 57 POPJ1 10275 1454 5042* POST 6440 635* 791 801 888 913 995 1002 1028 2468 4743 PPC1 6205 57 PR0 6206 4806 PR0MSG 13726 4820 6724* PR3 6236 636 PRCR 6473 628* PRNMSG 13760 4812 6726* PROCEE 02207 2429* 6632 PROMPT 07357 4381 4387 4426 4495* PRPA 6470 625* 5792 6171 PRPB 6471 626* 5795 6168 6435 PRPC 6472 627* PRS 6000 2465 4750 PSNAME 14076 1819 6742* PUSHAC 00617 1447 1457 1461* PUSHJ1 00600 1225 1446* 1448 1450 PWCR 6477 632* 5722 5725 5731 5782 5791 5799 5808 5812 6094 6110 6112 6124 6126 6136 6160 6167 6178 6190 6192 6390 6401 6403 6409 6428 6433 6439 PWPA 6474 629* 6108 PWPB 6475 630* 6103 6399 PWPC 6476 631* 5723 5784 6096 6162 6393 6431 PWRON 07636 4759 4769* R3L 7014 673 792 3862 4217 5419 RAL 7004 664 668 1982 4121 4124 4125 4170 4751 4754 4760 5390 5420 5830 6021 6054 RAM128 1240 5094* 5398 5503 5504 RAM512 5200 5093* 5503 RAMBUF 10022 4885* 5222 5225 5227 5233 5237 5239 5243 5264 5266 5274 5276 5278 5282 5283 5287 RAMCDF 10662 5218 5272 5422 5445* 5447 5476 RAMDAR 10025 4886* 5374 5380 5401 RAMDRD 10400 3122 3312 5158 5169* RAMDRW 10277 5019 5117* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 191 Symbol Table BTS6120.PLX RAMDWR 10411 3113 3404 5181* RAMER1 10422 5127 5171 5183 5191* RAMER2 10424 5132 5174 5186 5195* RAMMS1 14406 1069 6773* RAMMS3 14413 1076 6774* RAMPTR 10010 4876* 5220 5223 5226 5275 5277 5288 5388 5389 5391 5393 RAMSEL 10635 3102 5125 5169 5181 5413* 5468 RAMSIZ 10033 4889* 5467 5516 5517 5525 RAMUSZ 10035 3110 3119 4891* 5365 5397 5436 5437 RANGE 06441 1217 3932* RANGE1 06465 3936 3952* RAR 7010 659 660 2935 3005 3849 3893 4975 5823 6018 6051 RDADDR 06416 1686 1934 3901* 3907 3915 RDBOOT 10334 2772 5151* RDDUMP 03400 3312* 6650 RDF 6214 860 897 962 RDHIGH 06423 3907* 3939 RDIBU1 11456 6166* 6183 RDIBU2 11500 6189* 6194 RDIBU3 11506 6181 6199* RDIBUF 11446 5890 6156* RDLOW 06432 3915* 3932 RDMEM 01317 1220 1867* 1894 RDPAGE 10021 1236 4884* 5119 5139 5157 5364 5375 RDPTR 03467 3313 3321 3368* RDRW1 10313 5130* 5141 RDRW2 10325 5135 5138* RDRW3 10327 5137 5139* RDSIZE 10027 4888* 5432 5556 RDTES0 10667 5468* 5524 RDTES1 10724 5487 5507* RDTES2 10737 5512 5520* RDTEST 10665 1073 5466* RDUNIT 10020 3099 3331 3422 4883* 5124 5156 5414 5418 5431 5466 5520 5521 5549 5550 5555 RDYTMO 11335 6014 6015 6027 6029 6037* RECCNT 00052 1197* 3335 3350 3360 3377 RECSIZ 00051 1196* 2934 2952 2969 2997 3004 3034 3071 3106 3315 3323 3366 3371 3407 3415 3428 3437 REGCMD 0107 5687* 5771 5885 5903 5929 5939 REGCNT 0102 5681* 5988 REGDAT 0100 5679* 5783 6095 6161 REGERR 0101 5680* 6066 REGLB0 0103 5682* 5956 REGLB1 0104 5683* 5968 REGLB2 0105 5684* 5973 REGLB3 0106 5685* 5734 5983 REGLSC 01240 1714 1784* 2396 4858 REGLST 01224 1775* 1784 REGSTS 0107 5686* 6017 6050 REPCNT 00043 1186* 1282 1302 1305 1490 1497 REPEA1 00635 1480 1489* REPEAT 00620 1478* 6596 REPLOC 00044 1187* 1306 1494 1495 RESTA 00400 1222 1272* 1322 RFRMAT 03120 3097* 6658 RLLOAD 03514 3404* 6654 ROMCH0 10056 892* 894 ROMCHK 10054 890* 900 ROMCK0 00200 990* 1552 ROMCK1 10200 1555 4917* ROMCP0 10036 852* 863 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 192 Symbol Table BTS6120.PLX ROMCPY 10040 805 807 808 809 818 819 820 821 822 823 824 825 826 827 828 829 854* 859 RSP1 6207 2466 4727 RSP2 6227 4729 RTF 6005 2476 RTL 7006 657 662 669 670 2513 3737 3845 3846 4169 4757 5235 5240 5241 5828 5829 5963 5964 6174 RTN1 6225 57 RTR 7012 658 661 671 2512 3742 3894 5281 5285 5286 5824 5959 5970 5971 6106 RWCNT 10057 4907* 5140 6352 6361 6471 6488 SAVCHR 00033 1174* 1373 1374 1387 1391 1419 2095 2099 2589 3566 3576 3611 3847 3848 3851 4127 4172 4247 4248 4253 4394 4398 4411 4413 SEAR1 01633 2097 2101 2108* SEAR2 01640 2115* 2129 SEAR3 01656 2120 2125* SEAR4 01665 2127 2132* SEARCH 01600 2081* 6614 SETBUF 12000 5117 6304 6459* SETDA1 10607 5376* 5381 SETDA2 10615 5379 5386* SETDAR 10600 5130 5172 5184 5363* SETDRD 0007 5666* 5790 5807 6166 6189 6432 SETDRE 0013 5670* 5724 SETDWR 0011 5668* 6109 6123 6400 SETLBA 11254 5882 5900 5953* SETPMP 11600 5024 6248* SICOM 02144 2379* 6634 SIMFLG 00032 1173* 2421 2451 4839 SINGLE 02202 2392 2418* 2430 SIZPTR 10034 4890* 5433 5434 5509 5510 5557 5558 SKP 7410 1009 1024 1488 1608 1680 2961 3026 3690 6114 6180 6353 SKPMSG 13643 2615 6716* SMA 7500 1350 1513 1535 2598 4047 4054 4116 4162 4409 4513 5134 6329 SNA 7450 1080 1107 1287 1297 1355 1358 1361 1368 1389 1479 1496 1507 1529 1582 1650 1695 1713 1859 1897 1999 2047 2096 2100 2160 2205 2237 2242 2285 2301 2330 2358 2501 2590 2708 2739 2852 2865 3171 3208 3234 3339 3354 3546 3560 3750 3770 3781 3826 4023 4081 4085 4139 4182 4245 4255 4258 4326 4392 4403 4447 4456 4459 4476 4510 4552 4632 4804 4808 5399 5439 5511 6025 6467 6502 SNCOM 02200 2407* 6628 SNL 7420 1615 1932 1974 2248 2292 2759 2762 2816 3651 3816 4026 4035 5378 SP1NAM 14101 1824 6743* SP2NAM 14105 1829 6744* SPA 7510 1303 1368 1510 1532 3969 4113 4159 4224 4330 4346 4400 4556 5513 SPACM0 00514 1211 1386* SPACMP 00512 1210 1383* 1390 SPANXT 00532 1414* 1729 SPATST 00534 1418* 1687 3639 SPD 6276 802 918 930 1036 1272 1857 1872 1883 2714 4741 4798 5010 5245 5267 6134 6200 6536 6551 6573 SPINDN 11247 5936* PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 193 Symbol Table BTS6120.PLX SPINUP 11242 5926* SRCCDF 12106 6533 6563* 6570 SRCSPD 12107 6537 6564* SRNAME 14073 1834 6741* STA 7240 914 1019 1301 1427 1486 1607 1679 1943 2039 2086 2090 2123 2420 2566 3537 4334 4344 4484 4662 4787 5151 5314 5859 STACK 0177 1038 1241* 1242 1274 START 02241 2500* 6630 START1 02265 2502 2519* STKLEN 0063 1242* STKSAV 00113 1240* 2467 4738 STL 7120 668 670 671 2216 2715 4045 4264 5196 6067 STSBSY 0200 5690* 6022 6055 STSCOR 0004 5695* STSDF 0040 5692* STSDRQ 0010 5694* 6055 6056 STSDSC 0020 5693* STSERR 0001 5696* STSRDY 0100 5691* 6022 6023 SWPADR 06521 1939 1946 3994* SYSCRN 14332 1562 6770* SYSIN2 00201 939 995* SYSIN3 00225 1028* SYSIN4 00331 1098 1102 1123* SYSIN5 00333 1114 1120 1125* SYSIN7 00326 1108 1118* SYSINI 10001 791* 4706 SYSNM1 14265 1547 6767* SYSNM2 14304 1551 6768* SYSNM3 14314 1559 6769* SZA 7440 794 811 862 895 899 926 933 958 1021 1405 1421 1513 1535 1637 1653 1698 2119 2133 2170 2209 2214 2612 2716 2830 2858 2892 2972 3013 3018 3037 3163 3186 3216 3283 3494 3501 3568 3574 3578 3594 3597 3609 3612 3696 3935 3984 4116 4162 4276 4420 4435 4444 4462 4518 4524 4573 4576 4637 4647 4660 4668 4840 5326 5486 5502 5523 5728 6058 6311 SZL 7430 1097 1101 1632 1942 1950 1983 1990 2057 2126 2748 2774 2787 2955 3000 3103 3369 3440 3671 3684 3946 4752 4755 4758 4761 4958 5126 5131 5170 5173 5182 5185 5366 5416 5553 5767 5773 5880 5887 5898 5905 6019 6052 6222 6254 6280 6357 6535 6550 TAD 1000 793 804 806 808 809 818 820 822 824 826 828 855 892 931 946 950 955 957 963 1038 1045 1049 1078 1081 1082 1105 1112 1274 1280 1286 1289 1293 1295 1296 1302 1306 1319 1336 1348 1349 1354 1356 1357 1359 1360 1362 1363 1367 1369 1370 1374 1387 1388 1391 1419 1420 1428 1448 1450 1454 1457 1487 1493 1495 1506 1509 1512 1515 1528 1531 1534 1537 1548 1552 1555 1577 1580 1619 1622 1624 1635 1652 1691 1697 1718 1732 1740 1745 1750 1755 1758 1765 1791 1793 1797 1802 1807 1812 1817 1822 1827 1844 1846 1858 1869 1871 1881 1892 1896 1904 1947 1981 1987 1998 2006 2023 2041 2054 2082 2088 2095 2099 2103 2109 2118 2132 2155 2157 2159 2169 2183 2185 2187 2189 2204 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 194 Symbol Table BTS6120.PLX 2208 2211 2213 2241 2250 2284 2300 2309 2311 2313 2315 2329 2333 2337 2357 2361 2363 2382 2385 2469 2471 2473 2475 2477 2509 2511 2514 2586 2589 2596 2597 2605 2611 2618 2702 2707 2712 2746 2753 2811 2813 2818 2828 2856 2860 2872 2873 2876 2890 2891 2899 2903 2904 2907 2934 2937 2940 2942 2952 2969 2997 3004 3007 3010 3012 3015 3016 3034 3048 3070 3075 3081 3105 3110 3113 3119 3122 3159 3162 3170 3173 3178 3184 3190 3194 3198 3206 3207 3210 3211 3212 3214 3220 3227 3232 3236 3244 3246 3269 3312 3314 3320 3322 3328 3330 3344 3346 3358 3366 3371 3386 3404 3406 3412 3414 3421 3423 3428 3432 3437 3466 3472 3476 3483 3486 3487 3489 3492 3499 3500 3503 3534 3542 3544 3545 3557 3559 3564 3566 3567 3571 3573 3576 3577 3584 3587 3588 3592 3606 3608 3611 3616 3637 3641 3648 3664 3668 3677 3681 3692 3718 3732 3734 3739 3747 3759 3769 3779 3792 3795 3801 3811 3815 3822 3825 3840 3844 3848 3851 3884 3886 3902 3908 3910 3916 3918 3934 3940 3942 3952 3954 3967 3968 3971 3981 3983 3986 3988 3995 3997 4001 4003 4028 4037 4038 4046 4049 4053 4056 4080 4084 4091 4112 4115 4120 4123 4126 4127 4128 4138 4158 4161 4166 4168 4172 4173 4181 4210 4216 4222 4223 4228 4248 4253 4254 4257 4274 4282 4287 4292 4297 4302 4306 4318 4325 4329 4338 4345 4349 4382 4387 4398 4399 4402 4407 4408 4411 4413 4419 4423 4426 4428 4434 4437 4443 4446 4455 4458 4461 4466 4470 4475 4479 4485 4512 4517 4523 4526 4532 4535 4539 4551 4555 4572 4575 4608 4636 4641 4646 4650 4653 4659 4667 4675 4738 4788 4790 4792 4796 4802 4803 4806 4839 4851 4853 4856 4955 4957 4960 4961 4963 4970 4979 4999 5003 5005 5009 5032 5122 5133 5153 5210 5220 5223 5226 5233 5237 5239 5243 5258 5263 5265 5274 5276 5278 5283 5287 5318 5320 5323 5324 5349 5364 5365 5375 5377 5386 5389 5391 5392 5397 5398 5400 5401 5414 5415 5418 5421 5431 5432 5434 5437 5473 5478 5480 5482 5483 5493 5497 5500 5503 5504 5510 5514 5515 5516 5521 5522 5525 5550 5552 5555 5556 5558 5721 5724 5726 5730 5732 5769 5777 5779 5781 5783 5790 5798 5805 5807 5811 5822 5827 5832 5851 5861 5866 5883 5889 5901 5907 5927 5937 5954 5957 5962 5966 5969 5981 6013 6023 6056 6091 6093 6095 6100 6102 6104 6109 6111 6123 6125 6135 6157 6159 6161 6166 6175 6177 6189 6191 6215 6218 6220 6221 6251 6253 6256 6257 6259 6278 6279 6282 6283 6285 6310 6319 6321 6323 6328 6330 6331 6355 6366 6389 6391 6398 6400 6402 6408 6427 6429 6432 6438 6440 6461 6463 6465 6473 6483 6485 6501 6530 6532 6534 6536 6539 6545 6547 6549 6551 6554 6565 TADDR 06400 1628 1659 1903 3883* TASCI1 06247 3769* 3773 TASCIZ 06246 1320 3768* 4429 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 195 Symbol Table BTS6120.PLX TASZF1 06255 1113 3777* 3784 TBACKS 07131 4344* 4449 4451 TBELL 07071 4291* 4333 4490 TCF 6042 620* 1007 TCKSUM 01472 1998* 3248 TCKSUN 01477 1991 2000 2004* TDECN1 06302 3814* 3819 TDECN2 06310 3817 3822* TDECN3 06320 3827 3831* TDECNW 06277 1074 1109 3809* 3828 TDIGIT 07102 2900 3832 3853 3896 4306* TDOT 07077 2974 3039 3475 3698 4301* TFCHA1 07445 4570* 4577 TFCHA2 07460 4574 4584* TFCHAR 07444 4293 4319 4339 4350 4533 4569* TFIELD 06412 3885 3893* 4855 TFILV 00665 1511 1514 1520* 1533 1536 THCHA1 07443 4553 4557 4559* THCHAR 07427 3802 4283 4288 4298 4303 4307 4527 4536 4548* TLS 6046 622* 1004 1011 4609 TMEM 01060 1643 1659* 2121 2162 TOCT3 06343 1549 3477 3862* TOCT4 06322 1205 3839* 3868 3872 TOCT4C 06352 1206 3872* TOCT4S 06347 1207 3868* TOCTL 06325 3844* 3857 TOCTN 06324 3841* 3865 TPC 6044 621* TPCOM 00667 1526* 6640 TPCOM1 00705 1530 1538* TQUEST 07066 1318 1321 1335 2001 4243 4286* TRAP 07704 4769 4777 4811 4815 4819 4842 4849* 4851 TRPMSG 14004 4770 6728* TSF 6041 619* 1005 1008 1012 2546 4606 TSIXC 06274 3794 3800* TSIXW 06266 3791* TSLASH 07074 3478 3888 4296* TSPACE 07063 1204 4273 4281* TSTADR 06506 1218 3944 3980* TTABC 07054 4273* 4277 4520 TWCOM 00645 1504* 6638 TWCOM1 00663 1508 1516* TYPEAC 01252 1778 1797* 6673 TYPEIR 01263 1812* 2395 TYPEMQ 01260 1779 1807* 6677 TYPEPC 01255 1776 1802* 6675 TYPEPS 01266 1777 1817* 6679 TYPESR 01277 1832* 6681 TYPRG4 01243 1789* 1791 1798 1803 1808 1813 1818 1823 1828 1833 TYPSP1 01271 1780 1822* TYPSP2 01274 1781 1827* UAC 00001 1147* 1741 1797 2477 2561 4722 4970 4974 UFLAGS 00002 1148* 1758 1761 1817 2382 2475 2515 2563 4210 4216 4724 4790 4853 4978 4980 5003 UIR 00006 1152* 1812 2389 4797 4802 UMQ 00003 1149* 1751 1807 2473 2562 4726 UNPAC1 10432 5218* 5248 UNPACK 10427 5138 5175 5209* UPC 00000 1146* 1746 1802 2385 2479 2510 2567 2754 4788 4789 4796 4856 4999 5001 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 196 Symbol Table BTS6120.PLX USP1 00004 1150* 1822 2469 2564 4728 USP2 00005 1151* 1827 2471 2565 4730 VALUE 00027 1170* 1790 1793 1870 1871 1878 1881 1947 2036 2054 2152 2164 2169 2608 2618 2812 2813 2818 3201 3220 3227 3244 3383 3386 3485 3486 3489 VECOM 00707 1545* 6636 VERSION 0215 604* 1548 5032 VMAMSG 14253 2777 6763* VPOS 00037 1180* 4323 4329 4332 4397 4671 4742 WDRQ 11337 5772 5886 5904 6049* 6059 WIDTH 00040 1050 1181* 1516 4551 WORD 00045 1190* 1294 1295 1487 1506 1528 1691 1740 1745 1750 1755 1765 2023 2082 2103 2241 2284 2509 2586 2588 2605 2811 2856 2860 2876 3174 3184 3190 3205 3206 3232 3236 3240 3328 3330 3344 3346 3358 3421 3423 3557 3564 3571 3584 3587 3606 3637 3641 3791 3792 3795 3809 3811 3839 3844 3850 3863 3902 4107 4120 4122 4123 4126 4129 4153 4166 4168 4174 WORDH 00046 1191* 4167 4228 WREAD1 11314 6016* 6028 6030 WREADY 11311 5735 5766 5879 5897 5916 5930 5940 6013* WRIBU1 11410 6100* 6117 WRIBU2 11432 6123* 6128 WRIBU3 11440 6115 6133* WRIBUF 11400 5908 6090* WRMEM 01331 1878* 1893 WRPTR 03555 3405 3413 3439* WSR 6246 1766 X1 00010 1156* 2155 2184 2204 2250 2261 2300 2309 2329 2357 2703 2707 2874 2877 2905 2907 2938 2941 2944 3008 3012 3015 3467 3483 3535 3586 3719 3732 3733 3734 3739 3747 3768 3769 3777 3779 4076 4080 4087 4091 X2 00011 1157* 2157 2186 2211 2220 2262 2299 2313 2333 2342 2361 2368 2705 2712 X3 00012 1158* 1578 1580 2188 2263 2336 2343 2363 2369 XCT1 02331 2591 2596* XCT2 02337 2599 2604* XCT3 02351 2613 2616* XCTBLK 02341 2587 2596 2606* XCTCOM 02315 2585* 6642 XFRCNT 10054 4904* 5211 5247 5259 5291 5780 5800 5806 5813 6092 6113 6127 6158 6179 6193 6560 6569 XOFF 00035 1178* 4335 4385 4395 4575 4640 4649 4663 4670 XX1 10012 4878* 6216 6219 6258 6260 6284 6285 6322 6323 6540 6565 XX2 10013 4879* 6555 6568 ZBACKUP 00065 1212* 1481 1648 1715 2049 2239 2505 2741 2854 2867 3341 3356 4036 4430 4478 4483 ZCOMERR 00100 1223* 1406 1422 1654 1699 1933 1975 2243 2286 3563 3569 3575 3579 3598 3613 4027 4140 4183 ZCRLF 00061 1058 1084 1125 1208* 1276 1560 1563 1585 1639 1647 1720 1785 2122 2163 2778 2791 3044 3088 3498 3705 3873 4250 4425 4439 4468 4558 4652 4850 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 197 Symbol Table BTS6120.PLX ZDANDV 00076 1221* 1692 1948 2055 2338 2364 3221 ZDKRBN 00112 1237* 2930 2964 2990 3029 3048 3332 3345 3374 3431 3432 3472 3658 ZEOLNXT 00067 1214* 1545 1717 2150 2379 2407 2429 2447 2531 2743 3155 ZEOLTST 00066 1213* 1483 1505 1527 1576 1731 1935 1976 2051 2105 2288 2507 2593 2808 2869 3361 3419 3643 ZERROR 00101 1224* 1520 1957 2135 2172 2256 2294 2305 2600 2766 2822 2832 2882 3620 3948 ZGET 00070 1215* 1383 1400 1414 2034 2236 2500 3596 4033 4133 4176 ZINLMES 00062 1068 1075 1093 1110 1118 1123 1209* 1546 1550 1558 1561 1901 2004 2614 2616 2776 2789 2809 2897 2901 2927 2987 3045 3086 3384 3646 3655 3703 ZK177 00103 1228* 2713 3748 4631 ZK7 00105 1230* 1624 1636 3493 3593 3852 3895 4275 ZK70 00104 1229* 1845 2041 2088 2383 3237 3972 4211 4218 4230 4791 4854 ZK7400 0110 1235* 3735 3740 ZK7600 0107 1233* ZM128 00107 1232* 1233 3105 3314 3406 ZM256 00110 1234* 1235 3070 3322 3414 3668 3681 3692 ZMSPACE 00106 1231* 1388 1420 4028 4037 4399 4512 ZNXTADR 00074 1219* 1634 1693 1945 1949 1992 2059 2128 ZOCTNW 00071 1216* 1690 1730 2022 2081 2102 2585 2592 2807 2855 2868 3326 3342 3357 3418 3556 3570 3583 3605 3636 3640 4220 ZOUTCHR 00054 1203* 3288 3752 3772 3783 4249 4388 4412 4424 4427 4438 4467 4480 4642 4651 ZPUSHJ1 00102 1054 1070 1072 1095 1099 1225* 2551 2553 2771 2784 2950 2953 2995 2998 3101 3364 3367 3435 3438 3662 3669 3675 3682 ZRANGE 00072 1217* 1614 1931 1973 2050 2098 ZRDMEM 00075 1220* 1629 1660 1906 1940 1986 2116 2335 2388 ZRDPAGE 00111 1236* 2931 2965 2991 3030 3333 3347 3375 3433 ZRESTA 00077 1128 1222* 1338 1908 2817 3289 3388 3652 4643 4860 ZSPACM0 00064 1211* 1404 1694 2046 2864 3338 3353 3933 ZSPACMP 00063 1210* 1478 1649 1712 2738 2851 4022 4109 4155 ZTOCT4 00056 1205* 3474 3887 ZTOCT4C 00057 1206* 1907 2007 2619 2909 3050 3387 3504 4857 ZTOCT4S 00060 1207* 1553 1557 1630 1661 1794 1905 2814 3490 3649 ZTSPACE 00055 1204* 3479 3869 3889 4450 ZTSTADR 00073 1218* 1631 1941 1989 2056 2125 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 198 BTS6120.PLX PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 199 Table of Contents BTS6120.PLX SBC6120 ROM Monitor . . . . . . . . . . . . . . . . . . . . . . 1 BTS6120 Memory Layout . . . . . . . . . . . . . . . . . . . . . 2 Edit History . . . . . . . . . . . . . . . . . . . . . . . . . 3 SBC6120 IOTs and Definitions . . . . . . . . . . . . . . . . . 11 SBC6120 Memory Mapping Hardware . . . . . . . . . . . . . . . . 13 System Startup and POST Codes . . . . . . . . . . . . . . . . . 14 System Startup, Part 1 . . . . . . . . . . . . . . . . . . . . 15 System Startup, Part 2 . . . . . . . . . . . . . . . . . . . . 19 Field 0 Variables . . . . . . . . . . . . . . . . . . . . . . . 22 Monitor Main Loop . . . . . . . . . . . . . . . . . . . . . . . 25 Command Error Processing . . . . . . . . . . . . . . . . . . . 26 Get Next Command Character . . . . . . . . . . . . . . . . . . 27 Simple Lexical Functions . . . . . . . . . . . . . . . . . . . 28 Call Routines in Field 1 . . . . . . . . . . . . . . . . . . . 30 RP Command -- Repeat . . . . . . . . . . . . . . . . . . . . . 31 TW and TP Commands - Set Terminal Width and Page . . . . . . . 32 VE Command - Show System Name and Version . . . . . . . . . . . 33 H Command - Show Monitor Help . . . . . . . . . . . . . . . . . 34 E and EP Commands -- Examine Main Memory or Panel Memory . . . 35 D and DP Commands -- Deposit in Main Memory or Panel Memory . . 37 ER and DR Commands - Examine and Deposit in Registers . . . . . 38 Deposit in Registers . . . . . . . . . . . . . . . . . . . . . 39 Examine Registers . . . . . . . . . . . . . . . . . . . . . . . 40 Read and Write Memory . . . . . . . . . . . . . . . . . . . . . 42 BM Command -- Memory Block Move . . . . . . . . . . . . . . . . 44 CK Command -- Checksum Memory . . . . . . . . . . . . . . . . . 45 CM and FM Commands -- Clear Memory and Fill Memory . . . . . . 46 WS Command -- Word Search Memory . . . . . . . . . . . . . . . 48 BL Command -- List Breakpoints . . . . . . . . . . . . . . . . 50 Search for Breakpoints . . . . . . . . . . . . . . . . . . . . 51 BR Command -- Remove Breakpoints . . . . . . . . . . . . . . . 52 BP Command -- Set Breakpoints . . . . . . . . . . . . . . . . . 53 Insert Breakpoints in Memory . . . . . . . . . . . . . . . . . 54 Remove Breakpoints from Memory . . . . . . . . . . . . . . . . 55 TR Command -- Single Instruction with Trace . . . . . . . . . . 56 SI and P Commands - Single Instruction and Proceed . . . . . . 57 C Command - Restore Main Memory Context and Continue . . . . . 58 ST Command -- Start a Main Memory Program . . . . . . . . . . . 59 MR Command - Master Reset . . . . . . . . . . . . . . . . . . . 60 EX Command - Execute IOT Instructions . . . . . . . . . . . . . 61 OS/8 Bootstrap . . . . . . . . . . . . . . . . . . . . . . . . 61 Boot Sniffer . . . . . . . . . . . . . . . . . . . . . . . . . 63 B Command - Boot Disk . . . . . . . . . . . . . . . . . . . . . 64 Parse FORMAT Unit/Partition Argument . . . . . . . . . . . . . 66 PM Command - Show and Edit Disk Partition Map . . . . . . . . . 67 Disk Formatter, Pass 1 . . . . . . . . . . . . . . . . . . . . 69 Disk Formatter, Pass 2 . . . . . . . . . . . . . . . . . . . . 71 DF Command - Format IDE Disk Partition . . . . . . . . . . . . 73 RF Command - Format a RAM Disk . . . . . . . . . . . . . . . . 74 LP Command - Load Binary Paper Tapes from the Console . . . . . 75 Paper Tape Console Input Routine . . . . . . . . . . . . . . . 78 RD and DD Commands - Dump Disk (RAM and IDE) Records . . . . . 79 RL and DL Commands - Load Disk (RAM and IDE) Records . . . . . 81 Dump Disk Buffer on Console . . . . . . . . . . . . . . . . . . 83 Load Disk Buffer from Console . . . . . . . . . . . . . . . . . 85 PC Command - Copy an IDE Disk Partition . . . . . . . . . . . . 88 Free Space for Future Expansion! . . . . . . . . . . . . . . . 90 Type ASCII Strings . . . . . . . . . . . . . . . . . . . . . . 91 Type SIXBIT Words, and Characters . . . . . . . . . . . . . . . 93 Type Decimal Numbers . . . . . . . . . . . . . . . . . . . . . 94 Type Octal Numbers . . . . . . . . . . . . . . . . . . . . . . 95 Type 15 Bit Addresses . . . . . . . . . . . . . . . . . . . . . 96 Scan Addresses . . . . . . . . . . . . . . . . . . . . . . . . 97 Scan an Address Range . . . . . . . . . . . . . . . . . . . . . 98 PALX - IM6100/HM6120 Assembly Language V3.32 RLA 11-JAN-24 11:09:03 Page 200 Table of Contents BTS6120.PLX Address Arithmetic . . . . . . . . . . . . . . . . . . . . . . 99 Scan a Command Name . . . . . . . . . . . . . . . . . . . . . . 100 Command Lookup and Dispatch . . . . . . . . . . . . . . . . . . 101 Scan Decimal Numbers . . . . . . . . . . . . . . . . . . . . . 102 Scan Octal Numbers . . . . . . . . . . . . . . . . . . . . . . 103 Scan 15 Bit Addresses . . . . . . . . . . . . . . . . . . . . . 104 Ask For Confirmation . . . . . . . . . . . . . . . . . . . . . 105 Type Special Characters . . . . . . . . . . . . . . . . . . . . 106 Type Carriage Return, Line Feed and Backspace . . . . . . . . . 107 Read Command Lines . . . . . . . . . . . . . . . . . . . . . . 109 Terminal Output Primitives . . . . . . . . . . . . . . . . . . 112 Terminal Input Primitives . . . . . . . . . . . . . . . . . . . 114 Control Panel Entry Points . . . . . . . . . . . . . . . . . . 116 Field 1 Variables . . . . . . . . . . . . . . . . . . . . . . . 119 ROM Calls (PR0 Instructions) . . . . . . . . . . . . . . . . . 120 Fetch PR0 Arguments . . . . . . . . . . . . . . . . . . . . . . 122 ROM Call Table . . . . . . . . . . . . . . . . . . . . . . . . 123 Return from Routines in Field 1 . . . . . . . . . . . . . . . . 124 RAM Disk support . . . . . . . . . . . . . . . . . . . . . . . 125 RAM Disk Read/Write ROM Call . . . . . . . . . . . . . . . . . 126 RAM Disk Primary Bootstrap . . . . . . . . . . . . . . . . . . 127 Read and Write RAM Disk Pages . . . . . . . . . . . . . . . . . 128 Unpack RAM Disk Pages . . . . . . . . . . . . . . . . . . . . . 129 Pack RAM Disk Pages . . . . . . . . . . . . . . . . . . . . . . 130 Test RAM Disk Batteries . . . . . . . . . . . . . . . . . . . . 131 Get Battery Status ROM Call . . . . . . . . . . . . . . . . . . 132 Calculate RAM Disk Addresses . . . . . . . . . . . . . . . . . 133 Select RAM Disk Unit . . . . . . . . . . . . . . . . . . . . . 134 RAM Disk Diagnostics . . . . . . . . . . . . . . . . . . . . . 135 Get RAM Disk Size ROM Call . . . . . . . . . . . . . . . . . . 137 ATA Disk Support . . . . . . . . . . . . . . . . . . . . . . . 138 IDE Disk Interface . . . . . . . . . . . . . . . . . . . . . . 140 Initialize IDE Drive and Interface . . . . . . . . . . . . . . 141 Identify IDE/ATA Device . . . . . . . . . . . . . . . . . . . . 142 Get IDE Disk Size ROM Call . . . . . . . . . . . . . . . . . . 144 IDE Disk Primary Bootstrap . . . . . . . . . . . . . . . . . . 145 Read and Write IDE Sectors . . . . . . . . . . . . . . . . . . 146 Spin Up and Spin Down IDE Drive . . . . . . . . . . . . . . . . 147 Setup IDE Unit, LBA and Sector Count Registers . . . . . . . . 148 Wait for IDE Drive Ready . . . . . . . . . . . . . . . . . . . 149 Wait for IDE Data Request . . . . . . . . . . . . . . . . . . . 150 Write IDE Sector Buffer . . . . . . . . . . . . . . . . . . . . 151 Read IDE Sector Buffer . . . . . . . . . . . . . . . . . . . . 153 Initialize Disk Partition Map . . . . . . . . . . . . . . . . . 155 Get/Set Disk Partition Map ROM Call . . . . . . . . . . . . . . 156 IDE Disk Read/Write ROM Call . . . . . . . . . . . . . . . . . 157 Write IDE Register . . . . . . . . . . . . . . . . . . . . . . 159 Read IDE Register . . . . . . . . . . . . . . . . . . . . . . . 160 I/O Buffer Management . . . . . . . . . . . . . . . . . . . . . 161 Copy Memory ROM Calls . . . . . . . . . . . . . . . . . . . . . 162 Free Space for Future Expansion! . . . . . . . . . . . . . . . 164 Command Names Table . . . . . . . . . . . . . . . . . . . . . . 165 Argument Tables for Various Commands . . . . . . . . . . . . . 167 Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 Help Text . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 Temporary Disk Buffer . . . . . . . . . . . . . . . . . . . . . 173 Memory Map . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 Symbol Table . . . . . . . . . . . . . . . . . . . . . . . . . . 178