11 2 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 3+ 19:09 05/27/2017 4+ PAGE 1 5 6 7 8 ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 9 ; 10 ; CUTER - MODIFIED TO USE MITS CARDS IN ALTAIR 8800 11 ; 12 ; PSEUDO DEVICE 0, CONSOLE: VDM-1 AT C8/CC00, KBD AT 4/5 13 ; PSEUDO DEVICE 1, SERIAL: MITS SIO REV. 1 AT 0/1 14 ; PSEUDO DEVICE 2, SERIAL: MITS 2SIO CHANNEL B AT 18/19 15 ; 16 ; TAPE I/O MODIFIED TO USE MITS ACR SIO AT 6/7 17 ; 18 ; 03/02/2017 UDO MUNK FIRST VERSION FOR RELEASE 19 ; 03/23/2017 UDO MUNK USE MITS 2SIO CHANNEL B FOR PSEUDO 2 20 ; 03/27/2017 UDO MUNK USE MITS ACR SIO FOR TAPE I/O 21 ; 06/27/2017 UDO MUNK DON'T CLEAR TO EOL FOR CR, JUST ADVANCE LINE 22 ; 23 ;<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 24 ; 25 ; 26 ; 27 ; CUTER(TM) 28 ; 29 ; COPYRIGHT (C) 1977 30 ; SOFTWARE TECHNOLOGY CORP. 31 ; P.O. BOX 5260 32 ; SAN MATEO, CA 94402 33 ; (415) 349-8080 34 ; 35 ; A L L R I G H T S R E S E R V E D ! ! ! 36 ; 37 ; 38 ; VERSION 1.3 39 ; 77-03-27 40 ; 41 ; 42 ; THIS PROGRAM IS DESIGNED TO BE A STANDALONE CUTS 43 ; OPERATING SYSTEM. CUTER IS DESIGNED TO BE READ IN FROM 44 ; CASSETTE TAPE OR TO BE RESIDENT IN READ-ONLY-MEMORY. 45 ; CUTER SUPPORTS VARIOUS DEVICES INCLUDING SERIAL, 46 ; PARALLEL, THE PROCESSOR TECHNOLOGY VDM(TM) AND UP TO 47 ; TWO CUTS TAPE DRIVES. 48 ; 49 ; CUTER(TM) HAS BEEN WRITTEN SO AS TO BE COMPATIBLE WITH 50 ; SOLOS(TM). THE FOLLOWING KEYS ARE USED BY CUTER(TM) 51 ; IN PLACE OF THE SPECIAL KEYS ON THE SOL KEYBOARD: 52 ; 53 ; CURSOR UP CTL-W 54 ; CURSOR LEFT CTL-A 55 ; CURSOR RIGHT CTL-S 56 ; CURSOR DOWN CTL-Z 57 ; CURSOR HOME CTL-N 58 ; CLEAR SCREEN CTL-K 591 60 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 61+ 19:09 05/27/2017 62+ PAGE 2 63 64 65 66 ; MODE CTL-@ 67 ; 68 ; 69 ; 70 C000 ORG 0C000H 71 ; 72 ; 73 ; AUTO-STARTUP CODE 74 ; 75 C000 7F START: MOV A,A ;SHOW THIS IS CUTER (SOLOS=00) 76 ; THIS BYTE ALLOWS AUTOMATIC POWER ON ENTRY 77 ; WHEN IN ROM SUPPORTING THIS HARDWARE FEATURE. 78 C001 C3D7C1 INIT: JMP STRTA ;SYSTEM RESTART ENTRY POINT 79 ; 80 ; THESE JUMP POINTS ARE PROVIDED TO ALLOW COMMON ENTRY 81 ; LOCATIONS FOR ALL VERSIONS OF CUTER. THEY ARE USED 82 ; EXTENSIVELY BY CUTS SYSTEM PROGRAMS AND IT IS RECOMMENDED 83 ; THAT USER ROUTINES ACCESS CUTER ROUTINES THROUGH THESE 84 ; POINTS ONLY! 85 ; 86 C004 C318C2 RETRN: JMP COMND ;RETURN TO CUTER COMMAND PROCESSOR 87 C007 C3DCC5 FOPEN: JMP BOPEN ;CASSETTE OPEN FILE ENTRY 88 C00A C3FFC5 FCLOS: JMP PCLOS ;CASSETTE CLOSE FILE ENTRY 89 C00D C342C6 RDBYT: JMP RTBYT ;CASSETTE READ BYTE ENTRY 90 C010 C37FC6 WRBYT: JMP WTBYT ;CASSETTE WRITE BYTE ENTRY 91 C013 C3C7C6 RDBLK: JMP RTAPE ;CASSETTE READ BLOCK ENTRY 92 C016 C37CC7 WRBLK: JMP WTAPE ;CASSETTE WRITE BLOCK ENTRY 93 ; 94 ; SYSTEM I/O ENTRY POINTS 95 ; 96 ; THESE FOUR ENTRY POINTS ARE USED TO EITHER INPUT 97 ; OR OUTPUT TO CUTER PSUEDO PORTS. 98 ; THESE PSUEDO PORTS ARE AS FOLLOWS: 99 ; 100 ; PORT INPUT OUTPUT 101 ; ---- ----------------- --------------------- 102 ; 0 KEYBOARD INPUT BUILT-IN VDM DRIVER 103 ; ACTUAL PORT 3 PORT C8, MEMORY FROM CC00 104 ; 1 SERIAL PORT SERIAL PORT 105 ; ACTUAL PORT 1 ACTUAL PORT 1 106 ; 2 PARALLEL PORT PARALLEL PORT 107 ; ACTUAL PORT 2 ACTUAL PORT 2 108 ; 3 USER'S INPUT RTN USER'S OUTPUT ROUTINE 109 ; 110 ; STATUS FOR ACTUAL PORTS 1, 2 AND 3 IS VIA ACTUAL 111 ; PORT 0. THE BITS OF PORT ZERO ARE DEFINED AS FOLLOWS: 112 ; 113 ; : : : : : :---- : --- : --- : 114 ; : TBE : RDA : : : :PXDR : PDR : KDR : 115 ; BIT 7 6 5 4 3 2 1 0 116 ; 1171 118 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 119+ 19:09 05/27/2017 120+ PAGE 3 121 122 123 124 ; WHERE: 125 ; TBE 1=TRANSMITTER BUFFER EMPTY (SERIAL) 126 ; RDA 1=READER DATA AVAILABLE (SERIAL) 127 ; ---- 128 ; PXDR 0=PARALLEL EXTERNAL DEVICE READY 129 ; --- 130 ; PDR 0=PARALLEL DATA READY 131 ; --- 132 ; KDR 0=KEYBOARD DATA READY 133 ; 134 ; 135 ; 136 ; 137 ; NOTE: SOUT AND SINP ARE "LDA" INSTRUCTIONS. 138 ; THIS FACT IS USED TO ALLOW ACCESS TO THE 139 ; BYTES "OPORT" AND "IPORT" DYNAMICALLY. 140 ; THESE MUST REMAIN "LDA" INSTRUCTIONS!!!!! 141 ; 142 C019 3A07C8 SOUT: LDA OPORT ;OUTPUT VIA STANDARD OUTPUT PSUEDO PORT 143 C01C C32EC0 AOUT: JMP OUTPR ;OUTPUT VIA PSUEDO PORT SPECIFIED IN REG A 144 C01F 3A06C8 SINP: LDA IPORT ;INPUT VIA STANDARD INPUT PSUEDO PORT 145 C022 AINP EQU $ ;INPUT VIA PSUEDO PORT SPECIFIED IN REG A 146 ; -----------END OF SYSTEM ENTRY POINTS---------- 147 ; 148 ; 149 ; AINP CONTINUES HERE (IT COULD HAVE BEEN A "JMP" THOUGH) 150 C022 E5 PUSH H ;SAVE HL FM ENTRY 151 C023 2109C3 LXI H,ITAB 152 ; 153 ; THIS ROUTINE PROCESSES THE I/O REQUESTS 154 ; 155 C026 E603 IOPRC: ANI 3 ;KEEP REGISTER "A" TO FOUR VALUES 156 C028 07 RLC ;COMPUTE ENTRY ADDRESS 157 C029 85 ADD L 158 C02A 6F MOV L,A ;WE HAVE ADDRESS 159 C02B C387C2 JMP DISPT ;DISPATCH TO IT 160 ; 161 ; 162 C02E OUTPR EQU $ ;PROCESS OUTPUT REQUESTS 163 C02E E5 PUSH H ;SAVE REGS 164 C02F 2101C3 LXI H,OTAB ;POINT TO OUTPUT DISPATCH TABLE 165 C032 C326C0 JMP IOPRC ;DISPATCH FOR PROPER PSUEDO PORT 166 ; 167 ; 168 ; 169 ; CUTER SYSTEM I/O ROUTINES 170 ; 171 ; 172 ; THIS ROUTINE IS A MODEL OF ALL INPUT ROUTINES WITHIN 173 ; CUTER. THE FIRST ROUTINE "KREA1" PERFORMS THE INPUT 174 ; FROM THE STANDARD KEYBOARD ON PARALLEL PORT 3. 1751 176 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 177+ 19:09 05/27/2017 178+ PAGE 4 179 180 181 182 ; ALL STANDARD INPUT DRIVERS RETURN EITHER THE CHARACTER 183 ; WITH A NON-ZERO FLAG, OR JUST A ZERO FLAG INDICATING 184 ; THAT NO CHARACTER IS AVAILABLE YET. IT WILL BE THE 185 ; RESPONSIBILITY OF THE USER TO LOOP WAITING FOR A 186 ; CHARACTER, OR TO USE THE INPUT AS A STATUS REQUEST. 187 ; WHEN A CHARACTER IS AVAILABLE, IT IS RETURNED IN REG A. 188 ; 189 ; THE FOLLOWING KEYBOARD ROUTINE MAY BE USED AS A SAMPLE 190 ; OF HOW TO WRITE A USER INPUT ROUTINE. 191 ; 192 ; KEYBOARD INPUT ROUTINE 193 ; 194 ; MODIFIED SO THAT KBD STATUS PORT CAN BE DIFFERENT FROM SIO STATUS PORT 195 ; UDO MUNK 196 ; 197 C035 KREA1 EQU $ ;KEYBOARD READ ROUTINE 198 ; IN STAPT ;GET STATUS WORD 199 C035 DB04 IN STKBD ;*UM* 200 C037 2F CMA ;INVERT IT FOR PROPER RETURN 201 C038 E601 ANI KDR ;TEST NOT KEYBOARD DATA READY 202 C03A C8 RZ ;ZERO IF NO CHARACTER RECEIVED 203 ; 204 C03B DB05 IN KDATA ;GET CHARACTER 205 C03D C9 RET ;GO BACK WITH IT 206 ; 207 ; 208 ; 209 ; SERIAL INPUT ROUTINE 210 ; 211 C03E SREA1 EQU $ ;SERIAL INPUT ROUTINE 212 C03E DB00 IN STAPT ;GET STATUS 213 C040 2F CMA ;*UM* MITS SIO FLAGS ARE ACTIVE LOW 214 C041 E601 ANI SDR ;TEST FOR SERIAL DATA READY 215 C043 C8 RZ ;FLAGS ARE SET 216 ; 217 C044 DB01 IN SDATA ;GET DATA BYTE 218 ; IT IS UP TO THE CALLER TO STRIP PARITY IF DESIRED 219 C046 C9 RET ;WE HAVE IT 220 ; 221 ; 222 ; SERIAL DATA OUTPUT 223 ; 224 ; MODIFIED SO THAT STATUS BIT CAN BE DEFINED AS ANY BIT 225 ; UDO MUNK 226 ; 227 C047 SEROT EQU $ ;SERIAL OUTPUT ROUTINE 228 C047 DB00 IN STAPT ;GET STATUS 229 ; RAL ;PUT HIGH BIT IN CARRY 230 ; JNC SEROT ;LOOP UNTIL TRANSMITTER BUFFER IS EMPTY 231 C049 E680 ANI STBE ;*UM* 232 C04B C247C0 JNZ SEROT ;*UM* 2331 234 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 235+ 19:09 05/27/2017 236+ PAGE 5 237 238 239 240 C04E 78 MOV A,B ;GET THE CHARACTER BACK 241 C04F D301 OUT SDATA ;SEND IT OUT 242 C051 C9 RET ;AND WE'RE DONE 243 ; 244 ; 245 ; PARALLEL DATA INPUT 246 ; 247 ; MODIFIED TO USE 2SIO CHANNEL B 248 ; UDO MUNK 249 ; 250 C052 PARIT EQU $ ;GET CHAR FM PARALLEL PORT 251 ; IN STAPT ;STATUS 252 ; CMA ;INVERT FOR PROPER RETURN 253 ; ANI PDR ;IS DATA READY? 254 ; RZ ;NO--JUST EXIT 255 ; IN PDATA ;YES--GET CHAR THEN 256 ; RET ;THEN EXIT 257 C052 DB12 IN SIO2S ;GET STATUS 258 C054 E601 ANI SDR2 ;TEST FOR SERIAL DATA READY 259 C056 C8 RZ ;FLAGS ARE SET 260 C057 DB13 IN SIO2D ;GET DATA BYTE 261 C059 C9 RET ;WE HAVE IT 262 ; 263 ; 264 ; PARALLEL DATA OUTPUT ROUTINE 265 ; 266 ; MODIFIED TO USE 2SIO CHANNEL B 267 ; UDO MUNK 268 ; 269 C05A PAROT EQU $ ;OUTPUT CHAR TO PARALLEL PORT 270 ; IN STAPT ;STATUS 271 ; ANI PXDR ;IS EXTERNAL DEVICE READY? 272 ; JNZ PAROT ;NO--WAIT TIL IT IS 273 ; MOV A,B ;GET CHAR 274 ; OUT PDATA ;SEND DATA NOW 275 ; RET ;DONE 276 C05A DB12 IN SIO2S ;GET STATUS 277 C05C E602 ANI STBE2 ;DEVICE READY ? 278 C05E CA5AC0 JZ PAROT ;NO, WAIT 279 C061 78 MOV A,B ;GET THE CHARACTER BACK 280 C062 D313 OUT SIO2D ;SEND IT OUT 281 C064 C9 RET ;AND WE'RE DONE 282 ; 283 ; 284 ; USER DEFINED INPUT/OUTPUT ROUTINES 285 C065 ERRIT EQU $ ;USER INPUT ROUTINE 286 C065 E5 PUSH H ;SAVE ORIG HL 287 C066 2A00C8 LHLD UIPRT ;GET USER'S RTN ADDR 288 C069 C370C0 JMP ERRO1 ;MERGE TO VERIFY THE ADDR 289 ; 290 C06C ERROT EQU $ ;USER OUTPUT ROUTINE 2911 292 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 293+ 19:09 05/27/2017 294+ PAGE 6 295 296 297 298 C06C E5 PUSH H ;SAVE ORIG HL 299 C06D 2A02C8 LHLD UOPRT ;GET USER'S RTN ADDR 300 C070 ERRO1 EQU $ ;WE MERGE HERE TO VFY ADDR 301 C070 7D MOV A,L ;ZERO=UNDEFINED 302 C071 B4 ORA H ;IS IT? 303 C072 C28BC2 JNZ DISP1 ;NO--VALID--OFF TO IT 304 C075 C30FC2 JMP STRTD ;RESET I/O PORTS AND BACK TO COMMAND MODE 305 ; 306 ; 307 ; 308 ; VIDEO DISPLAY ROUTINES 309 ; 310 ; 311 ; THESE ROUTINES ALLOW FOR STANDARD VIDEO TERMINAL 312 ; OPERATIONS. ON ENTRY, THE CHARACTER FOR OUTPUT IS IN 313 ; REGISTER B AND ALL REGISTERS ARE UNALTERED ON RETURN. 314 ; 315 ; 316 ; 317 C078 VDM01 EQU $ ;VDM OUTPUT DRIVER 318 C078 E5 PUSH H ;SAVE HL 319 C079 D5 PUSH D ;SAVE DE 320 C07A C5 PUSH B 321 ; 322 ; PROCESS ESC SEQUENCE IF ANY 323 ; 324 C07B 3A0CC8 LDA ESCFL ;GET ESCAPE FLAG 325 C07E B7 ORA A 326 C07F C287C1 JNZ ESCS ;IF NON ZERO GO PROCESS THE REST OF THE SEQUENCE 327 ; 328 C082 78 MOV A,B ;GET CHAR 329 C083 E67F ANI 7FH ;CLR HI BIT IN CASE 330 C085 47 MOV B,A ;USE CHAR STRIPPED OF HI BIT FOR COMPATABILITY 331 C086 CAA0C0 JZ GOBK ;MAKE A QUICK EXIT FOR A NULL 332 ; 333 C089 21E2C2 LXI H,TBL 334 C08C CDA6C0 CALL TSRCH ;GO PROCESS 335 ; 336 C08F GOBACK EQU $ ;RESET CURSOR AND DELAY 337 C08F CD45C1 CALL VDADD ;GET SCRN ADDR 338 C092 7E MOV A,M ;GET CHAR 339 C093 F680 ORI 80H ;INVERSE VIDEO 340 C095 77 MOV M,A ;CURSOR IS NOW THERE 341 C096 2A0AC8 LHLD SPEED-1 ;GET DELAY SPEED 342 C099 2C INR L ;MAKE IT DEFINITELY NON-ZERO 343 C09A AF XRA A ;DELAY ENDS WHEN H=ZERO 344 C09B 2B TIMER: DCX H ;LOOP FOR DELAY AMNT 345 C09C BC CMP H ;IS IT DONE YET 346 C09D C29BC0 JNZ TIMER ;NO--KEEP DELAYING 347 C0A0 C1 GOBK: POP B 348 C0A1 D1 POP D ;RESTORE ALL REGISTERS 3491 350 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 351+ 19:09 05/27/2017 352+ PAGE 7 353 354 355 356 C0A2 E1 POP H 357 C0A3 C9 RET ;EXIT FROM VDMOT 358 ; 359 ; 360 C0A4 NEXT EQU $ ;GO TO NEXT CHR 361 C0A4 23 INX H 362 C0A5 23 INX H 363 ; 364 ; THIS ROUTINE SEARCHES FOR A MATCH OF THE CHAR IN "B" 365 ; TO THE CHAR IN THE TBL POINTED TO BY HL. 366 ; 367 C0A6 7E TSRCH: MOV A,M ;GET CHR FROM TABLE 368 C0A7 B7 ORA A ;SEE IF END OF TBL 369 C0A8 CAB8C0 JZ CHAR ;ZERO IS THE LAST 370 C0AB B8 CMP B ;TEST THE CHR 371 C0AC 23 INX H ;POINT FORWARD 372 C0AD C2A4C0 JNZ NEXT 373 C0B0 E5 PUSH H ;FOUND ONE...SAVE ADDRESS 374 C0B1 CD5FC1 CALL CREM ;REMOVE CURSOR 375 C0B4 E3 XTHL ;RESTORE ADDR OF CHAR ENTRY IN TBL 376 C0B5 C387C2 JMP DISPT ;DISPATCH FOR CURSOR CONTROL 377 ; 378 ; 379 C0B8 CHAR EQU $ ;WE HAVE A CHAR 380 C0B8 78 MOV A,B ;GET CHARACTER 381 C0B9 FE7F CPI 7FH ;IS IT A DEL? 382 C0BB C8 RZ ;GO BACK IF SO 383 ; 384 ; 385 ; 386 C0BC CD45C1 OCHAR: CALL VDADD ;GET SCREEN ADDRESS 387 C0BF 70 MOV M,B ;PUT CHR ON SCREEN 388 C0C0 3A08C8 LDA NCHAR ;GET CHARACTER POSITION 389 C0C3 FE3F CPI 63 ;END OF LINE? 390 C0C5 DAE5C0 JC OK 391 C0C8 3A09C8 LDA LINE 392 C0CB FE0F CPI 15 ;END OF SCREEN? 393 C0CD C2E5C0 JNZ OK 394 ; 395 ; END OF SCREEN...ROLL UP ONE LINE 396 ; 397 C0D0 AF SCROLL: XRA A 398 C0D1 3208C8 STA NCHAR ;BACK TO FIRST CHAR POSITION 399 C0D4 4F SROL: MOV C,A 400 C0D5 CD4CC1 CALL VDAD ;CALCULATE LINE TO BE BLANKED 401 C0D8 AF XRA A 402 C0D9 CD23C1 CALL CLIN1 ;CLEAR IT 403 C0DC 3A0AC8 LDA BOT 404 C0DF 3C INR A 405 C0E0 E60F ANI 0FH 406 C0E2 C312C1 JMP ERAS3 4071 408 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 409+ 19:09 05/27/2017 410+ PAGE 8 411 412 413 414 ; 415 ; INCREMENT LINE COUNTER IF NECESSARY 416 ; 417 C0E5 3A08C8 OK: LDA NCHAR ;GET CHR POSITION 418 C0E8 3C INR A 419 C0E9 E63F ANI 3FH ;MOD 64 420 C0EB 3208C8 STA NCHAR ;STORE THE NEW 421 C0EE C0 RNZ ;MORE CHARS THIS LINE 422 C0EF PDOWN EQU $ ;MOVE CURSOR DOWN ONE LINE 423 C0EF 3A09C8 LDA LINE ;GET THE LINE COUNT 424 C0F2 3C INR A 425 C0F3 E60F CURSC: ANI 0FH ;MOD 15 INCREMENT 426 C0F5 3209C8 CUR: STA LINE ;STORE THE NEW 427 C0F8 C9 RET 428 ; 429 ; ERASE SCREEN 430 ; 431 C0F9 2100CC PERSE: LXI H,VDMEM ;POINT TO SCREEN 432 C0FC 36A0 MVI M,80H+' ' ;THIS IS THE CURSOR 433 ; 434 C0FE 23 INX H ;NEXT CHAR 435 C0FF ERAS1 EQU $ ;LOOP TO CLR SCRN 436 C0FF 3620 MVI M,' ' ;BLANK IT OUT 437 C101 23 INX H ;NEXT SCRN LOC 438 C102 7C MOV A,H ;SEE IF DONE 439 C103 FED0 CPI 0D0H ;DID IT GO ABOVE VDM 440 C105 DAFFC0 JC ERAS1 ;NO--MORE 441 C108 37 STC ;SAY WE WANT TO DROP THRU TO ERAS3 442 ; 443 C109 PHOME EQU $ ;RESET CURSOR TO HOME 444 C109 3E00 MVI A,0 ;CLEAR, LEAVE CARRY AS IS 445 C10B 3209C8 STA LINE ;ZERO LINE 446 C10E 3208C8 STA NCHAR ;LEFT SIDE OF SCREEN 447 C111 D0 RNC ;THIS IS JUST A HOME OPERATION 448 ; 449 C112 D3C8 ERAS3: OUT DSTAT ;RESET SCROLL PARAMETERS 450 C114 320AC8 STA BOT ;BEGINNING OF TEXT OFFSET 451 C117 C9 RET 452 ; 453 ; 454 C118 CLIN2 EQU $ ;HERE TO SEE IF VDM OUTPUT 455 C118 3A07C8 LDA OPORT ;GET CRNT OUTPUT PORT 456 C11B B7 ORA A 457 C11C C0 RNZ ;NOT VDM--DONE THEN 458 C11D CD45C1 CLINE: CALL VDADD ;GET CURRENT SCREEN ADDRESS 459 C120 3A08C8 LDA NCHAR ;CURRENT CURSOR POSITION 460 C123 FE40 CLIN1: CPI 64 ;NO MORE THAN 63 461 C125 D0 RNC ;ALL DONE 462 C126 3620 MVI M,' ' ;ALL SPACED OUT 463 C128 23 INX H 464 C129 3C INR A 4651 466 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 467+ 19:09 05/27/2017 468+ PAGE 9 469 470 471 472 C12A C323C1 JMP CLIN1 ;LOOP TO END OF LINE 473 ; 474 ; 475 ; ROUTINE TO MOVE THE CURSOR UP ONE LINE 476 ; 477 C12D 3A09C8 PUP: LDA LINE ;GET LINE COUNT 478 C130 3D DCR A 479 C131 C3F3C0 JMP CURSC ;MERGE 480 ; 481 ; MOVE CURSOR LEFT ONE POSITION 482 ; 483 C134 3A08C8 PLEFT: LDA NCHAR 484 C137 3D DCR A 485 C138 PCUR EQU $ ;TAKE CARE OF CURSOR SAME LINE 486 C138 E63F ANI 03FH ;LET CURSOR WRAP AROUND 487 C13A 3208C8 STA NCHAR ;UPDATED CURSOR 488 C13D C9 RET 489 ; 490 ; CURSOR RIGHT ONE POSITION 491 ; 492 C13E 3A08C8 PRIT: LDA NCHAR 493 C141 3C INR A 494 C142 C338C1 JMP PCUR 495 ; 496 ; ROUTINE TO CALCULATE SCREEN ADDRESS 497 ; 498 ; ENTRY AT: RETURNS: 499 ; 500 ; VDADD CURRENT SCREEN ADDRESS 501 ; VDAD2 ADDRESS OF CURRENT LINE, CHAR 'C' 502 ; VDAD LINE 'A', CHARACTER POSITION 'C' 503 504 C145 3A08C8 VDADD: LDA NCHAR ;GET CHARACTER POSITION 505 C148 4F MOV C,A ;'C' KEEPS IT 506 C149 3A09C8 VDAD2: LDA LINE ;LINE POSITION 507 C14C 6F VDAD: MOV L,A ;INTO 'L' 508 C14D 3A0AC8 LDA BOT ;GET TEXT OFFSET 509 C150 85 ADD L ;ADD IT TO THE LINE POSITION 510 C151 0F RRC ;TIMES TWO 511 C152 0F RRC ;MAKES FOUR 512 C153 6F MOV L,A ;L HAS IT 513 C154 E603 ANI 3 ;MOD THREE FOR LATER 514 C156 C6CC ADI VDMEM SHR 8 ;LOW SCREEN OFFSET 515 C158 67 MOV H,A ;NOW H IS DONE 516 C159 7D MOV A,L ;TWIST L'S ARM 517 C15A E6C0 ANI 0C0H 518 C15C 81 ADD C 519 C15D 6F MOV L,A 520 C15E C9 RET ;H & L ARE NOW PERVERTED 521 ; 522 ; ROUTINE TO REMOVE CURSOR 5231 524 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 525+ 19:09 05/27/2017 526+ PAGE 10 527 528 529 530 ; 531 C15F CD45C1 CREM: CALL VDADD ;GET CURRENT SCREEN ADDRESS 532 C162 7E MOV A,M 533 C163 E67F ANI 7FH ;STRIP OFF THE CURSOR 534 C165 77 MOV M,A 535 C166 C9 RET 536 ; 537 ; ROUTINE TO BACKSPACE 538 ; 539 C167 CD34C1 PBACK: CALL PLEFT 540 C16A CD45C1 CALL VDADD ;GET SCREEN ADDRESS 541 C16D 3620 MVI M,' ' ;PUT A BLANK THERE 542 C16F C9 RET 543 ; 544 ; ROUTINE TO PROCESS A CARRIAGE RETURN 545 ; 546 C170 PCR: ;CALL CLINE ;CLEAR FROM CURRENT CURSOR TO END OF LINE 547 ; NOTE THAT A COMES BACK=64 WHICH WILL BE CLEARED AT PCUR 548 C170 3E40 MVI A,64 ;*UM* JUST ADVANCE LINE 549 C172 C338C1 JMP PCUR ;AND STORE THE NEW VALUE 550 ; 551 ; ROUTINE TO PROCESS LINEFEED 552 ; 553 C175 3A09C8 PLF: LDA LINE ;GET LINE COUNT 554 C178 3C INR A ;NEXT LINE 555 C179 E60F ANI 15 ;SEE IF IT WRAPPED AROUND 556 C17B C2F5C0 JNZ CUR ;IT DID NOT--NO SCROLL 557 ; 558 C17E C3D4C0 JMP SROL ;SCROLL ONE LINE--CURSOR SOME POSITION 559 ; 560 ; SET ESCAPE PROCESS FLAG 561 ; 562 C181 3EFF PESC: MVI A,(-1) AND 0FFH 563 C183 320CC8 STA ESCFL ;SET FLAG 564 C186 C9 RET 565 ; 566 ; PROCESS ESCAPE SEQUENCE 567 ; 568 C187 CD5FC1 ESCS: CALL CREM ;REMOVE CURSOR 569 C18A CD90C1 CALL ESCSP ;PROCESS THE CHARACTER 570 C18D C38FC0 JMP GOBACK 571 ; 572 C190 3A0CC8 ESCSP: LDA ESCFL ;GET ESCAPE FLAG 573 C193 FEFF CPI (-1) AND 0FFH ;TEST FLAG 574 C195 CAB8C1 JZ SECOND 575 ; 576 ; PROCESS THIRD CHR OF ESC SEQUENCE 577 ; 578 C198 210CC8 LXI H,ESCFL 579 C19B 3600 MVI M,0 580 C19D FE02 CPI 2 5811 582 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 583+ 19:09 05/27/2017 584+ PAGE 11 585 586 587 588 C19F DAB0C1 JC SETX ;SET X 589 C1A2 CAB4C1 JZ SETY ;SET Y 590 C1A5 FE08 CPI 8 ;SPECIAL SET SPEED 591 C1A7 CA94C5 JZ STSPD ;YES--SET THE SPEED WITH IT THEN 592 C1AA FE09 CPI 9 593 C1AC DABCC0 JC OCHAR ;PUT IT ON THE SCREEN 594 C1AF C0 RNZ 595 ; 596 ; TAB ABSOLUTE TO VALUE IN REG B 597 ; 598 C1B0 78 SETX: MOV A,B 599 C1B1 C338C1 JMP PCUR 600 ; 601 ; SET CURSOR TO LINE "B" 602 ; 603 C1B4 78 SETY: MOV A,B 604 C1B5 C3F3C0 JMP CURSC 605 ; 606 ; 607 ; PROCESS SECOND CHR OF ESC SEQUENCE 608 ; 609 C1B8 78 SECOND: MOV A,B 610 C1B9 FE03 CPI 3 611 C1BB CACEC1 JZ CURET 612 C1BE FE04 CPI 4 613 C1C0 C2CAC1 JNZ ARET2 614 ; 615 C1C3 44 ARET: MOV B,H 616 C1C4 4D MOV C,L ;PRESENT SCREEN ADDRESS TO BC FOR RETURN 617 C1C5 E1 ARET1: POP H ;RETURN ADDRESS 618 C1C6 D1 POP D ;OLD B 619 C1C7 C5 PUSH B 620 C1C8 E5 PUSH H 621 C1C9 AF XRA A 622 C1CA 320CC8 ARET2: STA ESCFL 623 C1CD C9 RET 624 ; 625 ; 626 ; RETURN PRESENT SCREEN PARAMETERS IN BC 627 ; 628 C1CE 2108C8 CURET: LXI H,NCHAR 629 C1D1 46 MOV B,M ;CHARACTER POSITION 630 C1D2 23 INX H 631 C1D3 4E MOV C,M ;LINE POSITION 632 C1D4 C3C5C1 JMP ARET1 633 ; 634 ; 635 ; 636 ; START UP SYSTEM 637 ; 638 ; CLEAR SCREEN AND THE FIRST 256 BYTES OF GLOBAL RAM 6391 640 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 641+ 19:09 05/27/2017 642+ PAGE 12 643 644 645 646 ; THEN ENTER THE COMMAND MODE. 647 ; 648 C1D7 AF STRTA: XRA A 649 C1D8 4F MOV C,A 650 C1D9 2104C8 LXI H,DFLTS ;CLEAR AFTER USER PORT ADDRESSES 651 ; 652 C1DC 77 CLERA: MOV M,A 653 C1DD 23 INX H 654 C1DE 0C INR C 655 C1DF C2DCC1 JNZ CLERA 656 ; 657 ; DETERMINE THE DEFAULT PORTS 658 ; THIS COULD BECOME "MVI A,XX" FOR YOUR SPECIFIC PORTS 659 C1E2 DBFF IN SENSE ;GET SWITCHES 660 ; 661 C1E4 47 MOV B,A ;SAVE IT 662 C1E5 E603 ANI 3 ;MAKE IT A VALID PORT 663 C1E7 3205C8 STA DFLTS+1 ;SET DEFAULT OUTPUT PORT 664 C1EA B7 ORA A ;SEE IF THIS THE VDM 665 C1EB C2F4C1 JNZ STRTB ;NO--DO NOT RESET VDM 666 C1EE 31FFCB LXI SP,SYSTP ;SET UP THE STACK FOR CALL 667 C1F1 CDF9C0 CALL PERSE ;(REG A ASSUMED TO COME BACK ZERO) 668 C1F4 STRTB EQU $ ;FINISH OFF THIS PORT THEN DO NEXT 669 C1F4 210000 LXI H,0 ;USE FOR CLEARING USER ADDRESSES 670 C1F7 FE03 CPI 3 ;IS IT A USER PORT 671 C1F9 CAFFC1 JZ STRTC ;YES-- DO NOT CLEAR IT 672 C1FC 2202C8 SHLD UOPRT ;NO--CLEAR ADDR 673 C1FF STRTC EQU $ ;OUTPUT PORT ALL SET 674 C1FF 78 MOV A,B ;FM SENSE SWITCHES 675 C200 1F RAR 676 C201 1F RAR ;NEXT 2 BITS ARE INPUT PORT 677 C202 E603 ANI 3 ;VALID PORT 678 C204 3204C8 STA DFLTS ;THIS IS DEFAULT INPUT PORT 679 C207 FE03 CPI 3 ;IS THIS ONE A USER PORT 680 C209 CA0FC2 JZ STRTD ;YES--DO NOT CLEAR IT THEN 681 C20C 2200C8 SHLD UIPRT ;NO--FORCE USER ADDRESS ZERO 682 C20F STRTD EQU $ ;1ST TIME INITIALIZATION ALL DONE NOW 683 C20F 2A04C8 LHLD DFLTS ;PICK UP DEFAULT PORTS 684 C212 2206C8 SHLD IPORT ;FORCE PORTS TO DEFAULT 685 C215 COMN1 EQU $ ;HERE TO TURN OFF TAPES, THEN COMMAND MODE 686 C215 AF XRA A 687 C216 D306 OUT TAPPT ;BE SURE TAPES ARE OFF 688 ; 689 ; 690 ; 691 ; =-- COMMAND MODE --= 692 ; 693 ; 694 ; THIS ROUTINE GETS AND PROCESSES COMMANDS 695 ; 696 C218 31FFCB COMND: LXI SP,SYSTP ;SET STACK POINTER 6971 698 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 699+ 19:09 05/27/2017 700+ PAGE 13 701 702 703 704 C21B CD3AC3 CALL PROMPT ;PUT PROMPT ON SCREEN 705 C21E CD27C2 CALL GCLI0 ;INIT TO GET COMMAND LINE 706 C221 CD6AC2 CALL COPRC ;PROCESS THE LINE 707 C224 C318C2 JMP COMND ;OVER AND OVER 708 ; 709 ; 710 ; 711 ; THIS ROUTINE READS A COMMAND LINE FROM THE SYSTEM 712 ; KEYBOARD 713 ; 714 ; C/R TERMINATES THE SEQUENCE ERASING ALL CHARS TO THE 715 ; RIGHT OF THE CURSOR 716 ; L/F TERMINATES THE SEQUENCE 717 ; ESC RESETS TO COMMAND MODE. 718 ; 719 C227 GCLI0 EQU $ ;HERE TO INIT FOR GCLIN 720 C227 2163CA LXI H,INLIN-1 ;PT TO CHAR IN FRONT OF INPUT BFR 721 C22A 3607 MVI M,7 ;MAKE SURE IT IS "BELL" TO KEEP FM DEL'ING TOO FAR 722 C22C 23 INX H ;NOW PT TO INPUT BFR 723 C22D 220EC8 SHLD INPTR ;SAVE AS STARTING PTR 724 C230 3E50 MVI A,80 ;NUMBER OF CHARS IN LINE (MAX) 725 C232 GCLI1 EQU $ ;LOOP TO BLANK OUT LINE BFR 726 C232 3620 MVI M,' ' ;BLANKS 727 C234 23 INX H ;NEXT CHAR 728 C235 3D DCR A ;FOR THIS COUNT 729 C236 C232C2 JNZ GCLI1 ;ENTIRE LINE 730 C239 CD1FC0 GCLIN: CALL SINP ;READ INPUT DEVICE 731 C23C CA39C2 JZ GCLIN 732 C23F E67F ANI 7FH ;MAKE SURE NO X'80' BIT DURING CMND MODE 733 C241 CA0FC2 JZ STRTD ;IF EITHER MODE (OR CTL-@) 734 C244 47 MOV B,A 735 C245 FE0D CPI CR ;IS IT CR? 736 C247 CA18C1 JZ CLIN2 ;YES--TERMINATE LINE HERE (CLR IF VDM) 737 C24A FE0A CPI LF ;IS IT A LINEFEED 738 C24C C8 RZ ;YES--TERMINATE LINE AS IS 739 C24D 2A0EC8 LHLD INPTR ;CRNT LINE PTR 740 C250 FE7F CPI 7FH ;DELETE CHR? 741 C252 C25FC2 JNZ GCLI2 ;NO--OK 742 C255 0608 MVI B,BACKS ;REPLACE IT 743 C257 2B DCX H ;BACK LINE PTR UP TOO 744 C258 3E07 MVI A,'G'-40H ;SEE IF A BELL 745 C25A BE CMP M ;IS IT? 746 C25B C261C2 JNZ GCLI3 ;NO--OK 747 C25E 47 MOV B,A ;YES--RING THE BELL THEN 748 C25F GCLI2 EQU $ ;STORE CHAR IN INPUT AREA 749 C25F 70 MOV M,B ;PLACE CHAR INTO LINE 750 C260 23 INX H ;NEXT CHAR 751 C261 GCLI3 EQU $ ;SAVE NEW LINE PTR 752 C261 220EC8 SHLD INPTR ;SAVE PTR 753 ; 754 C264 CD19C0 CONT: CALL SOUT 7551 756 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 757+ 19:09 05/27/2017 758+ PAGE 14 759 760 761 762 C267 C339C2 JMP GCLIN 763 ; 764 ; 765 ; 766 ; 767 ; FIND AND PROCESS COMMAND 768 ; 769 C26A COPRC EQU $ ;PROCESS THIS COMMAND LINE 770 C26A CDAAC2 CALL STUP ;SETUP TO PROCESS INPUT LINE 771 C26D EB XCHG ;DE=ADDR 772 C26E 2100C0 LXI H,START ;PREP SO THAT HL WILL PT TO CUTER LATER 773 C271 E5 PUSH H ;PLACE PTR TO CUTER ON STACK FOR LATER DISPT 774 C272 CD6CC3 CALL SCHR ;SCAN PAST BLANKS 775 C275 CA6BC4 JZ ERR1 ;NO COMMAND? 776 C278 EB XCHG ;HL HAS FIRST CHR 777 C279 11BDC2 LXI D,COMTAB ;POINT TO COMMAND TABLE 778 C27C CD91C2 CALL FDCOM ;SEE IF IN PRIMARY TABLE 779 C27F CC8EC2 CZ FDCOU ;TRY CUSTOM ONLY IF NOT PRIMARY COMMAND 780 C282 DISP0 EQU $ ;HERE TO EITHER DISPATCH OR DO ERROR 781 C282 CA6CC4 JZ ERR2 ;NOT IN EITHER TABLE 782 C285 13 INX D ;PT DE TO ADDR OF RTN 783 C286 EB XCHG ;HL=ADDR OF ADDR OF RTN 784 ; **** DROP THRU TO DISPT *** 785 ; 786 ; THIS ROUTINE DISPTACHES TO THE ADDR AT CONTENTS OF HL. 787 ; HL ARE RESTORED PRIOR TO GOING TO ROUTINE. 788 ; 789 C287 DISPT EQU $ ;DISPATCH 790 C287 7E MOV A,M ;LOW BYTE 791 C288 23 INX H 792 C289 66 MOV H,M ;HI BYTE 793 C28A 6F MOV L,A ;AND LO, HL NOW COMPLETE 794 C28B DISP1 EQU $ ;HERE TO GO OFF TO HL DIRECTLY 795 C28B E3 XTHL ;HL RESTORED AND ADDR ON STACK 796 C28C 7D MOV A,L ;ALWAYS PASS L IN "A" (PRIMARILY FOR SET'S) 797 C28D C9 RET ;OFF TO ROUTINE 798 ; 799 ; 800 ; 801 ; THIS ROUTINE SEARCHES THROUGH A TABLE, POINTED TO 802 ; BY 'DE', FOR A DOUBLE CHARACTER MATCH OF THE 'HL' 803 ; MEMORY CONTENT. IF NO MATCH IS FOUND THE SCAN ENDS 804 ; WITH THE ZERO FLAG SET, ELSE NON-ZERO SET. 805 ; 806 C28E FDCOU EQU $ ;HERE TO SCAN CUSTOM TABLE 807 C28E 113CC8 LXI D,CUTAB ;PT TO CUSTOM RTN TBL 808 C291 1A FDCOM: LDAX D 809 C292 B7 ORA A ;TEST FOR TABLE END 810 C293 C8 RZ ;NOT FOUND POST THAT AND RETURN 811 C294 E5 PUSH H ;SAVE START OF SCAN ADDRESS 812 C295 BE CMP M ;TEST FIRST CHR 8131 814 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 815+ 19:09 05/27/2017 816+ PAGE 15 817 818 819 820 C296 13 INX D 821 C297 C2A3C2 JNZ NCOM 822 ; 823 C29A 23 INX H 824 C29B 1A LDAX D 825 C29C BE CMP M ;NOW SECOND CHARACTER 826 C29D C2A3C2 JNZ NCOM ;GOODNESS 827 ; 828 C2A0 E1 POP H ;RETURN HL TO PT TO CHAR START 829 C2A1 B7 ORA A ;FORCE TO NON-ZERO FLAG 830 C2A2 C9 RET ;LET CALLER KNOW 831 ; 832 ; 833 C2A3 13 NCOM: INX D ;GO TO NEXT ENTRY 834 C2A4 13 INX D 835 C2A5 13 INX D 836 C2A6 E1 POP H ;GET BACK ORIGINAL ADDRESS 837 C2A7 C391C2 JMP FDCOM ;CONTINUE SEARCH 838 ; 839 ; 840 ; SET UP TO PROCESS AN INPUT LINE 841 C2AA STUP EQU $ ;PREPARE WHETHER VDM OR NOT 842 C2AA 2164CA LXI H,INLIN ;ASSUME NON-VDM INPUT 843 C2AD 220EC8 SHLD INPTR ;ALSO RESET PTR FOR NOW 844 C2B0 3A07C8 LDA OPORT ;SEE IF IT IS VDM 845 C2B3 B7 ORA A ;IS IT THE VDM PORT 846 C2B4 C0 RNZ ;NO--HL ARE SET PROPERLY 847 C2B5 CD5FC1 CALL CREM ;REMOVE CURSOR 848 C2B8 0E01 MVI C,1 ;GET VDM ADDR FM POSITION ONE 849 C2BA C349C1 JMP VDAD2 ;GET SCRN ADDR 850 ; 851 ; COMMAND TABLE 852 ; 853 ; THIS TABLE DESCRIBES THE VALID COMMANDS FOR CUTER 854 ; 855 C2BD COMTAB EQU $ ;START OF KNOWN COMMANDS 856 C2BD 4455 DB 'DU' ;DUMP 857 C2BF ADC3 DW DUMP 858 C2C1 454E DB 'EN' ;ENTR 859 C2C3 14C4 DW ENTER 860 C2C5 4558 DB 'EX' ;EXEC 861 C2C7 49C4 DW EXEC 862 C2C9 4745 DB 'GE' ;GET 863 C2CB A1C4 DW TLOAD 864 C2CD 5341 DB 'SA' ;SAVE 865 C2CF E0C4 DW TSAVE 866 C2D1 5845 DB 'XE' ;XEQ 867 C2D3 A0C4 DW TXEQ 868 C2D5 4341 DB 'CA' ;CAT 869 C2D7 27C5 DW TLIST 870 C2D9 5345 DB 'SE' ;SET COMMAND 8711 872 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 873+ 19:09 05/27/2017 874+ PAGE 16 875 876 877 878 C2DB 76C5 DW CSET 879 C2DD 4355 DB 'CU' ;CUSTOM COMMAND ENTER/CLEAR 880 C2DF B9C5 DW CUSET 881 C2E1 00 DB 0 ;END OF TABLE MARK 882 ; 883 ; 884 ; DISPLAY DRIVER COMMAND TABLE 885 ; 886 ; THIS TABLE DEFINES THE CHARACTERS FOR SPECIAL 887 ; PROCESSING. IF THE CHARACTER IS NOT IN THE TABLE IT 888 ; GOES TO THE SCREEN. 889 ; 890 C2E2 0B TBL: DB CLEAR ;SCREEN 891 C2E3 F9C0 DW PERSE 892 C2E5 17 DB UP ;CURSOR 893 C2E6 2DC1 DW PUP 894 C2E8 1A DB DOWN ;" 895 C2E9 EFC0 DW PDOWN 896 C2EB 01 DB LEFT ;" 897 C2EC 34C1 DW PLEFT 898 C2EE 13 DB RIGHT ;" 899 C2EF 3EC1 DW PRIT 900 C2F1 0E DB HOME ;" 901 C2F2 09C1 DW PHOME 902 C2F4 0D DB CR ;CARRIAGE RETURN 903 C2F5 70C1 DW PCR 904 C2F7 0A DB LF ;LINE FEED 905 C2F8 75C1 DW PLF 906 C2FA 08 DB BACKS ;BACK SPACE 907 C2FB 67C1 DW PBACK 908 C2FD 1B DB ESC ;ESCAPE KEY 909 C2FE 81C1 DW PESC 910 C300 00 DB 0 ;END OF TABLE 911 ; 912 ; OUTPUT DEVICE TABLE 913 ; 914 C301 78C0 OTAB: DW VDM01 ;VDM DRIVER 915 C303 47C0 DW SEROT ;SERIAL OUTPUT 916 C305 5AC0 DW PAROT ;PARALLEL OUTPUT 917 C307 6CC0 DW ERROT ;ERROR OR USER DRIVER HANDLER 918 ; 919 ; INPUT DEVICE TABLE 920 ; 921 C309 35C0 ITAB: DW KREA1 ;KEYBOARD INPUT 922 C30B 3EC0 DW SREA1 ;SERIAL INPUT 923 C30D 52C0 DW PARIT ;PARALLEL INPUT 924 C30F 65C0 DW ERRIT ;ERROR OR USER DRIVER HANDLER 925 ; 926 ; 927 ; SECONDARY COMMAND TABLE FOR SET COMMAND 928 ; 9291 930 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 931+ 19:09 05/27/2017 932+ PAGE 17 933 934 935 936 C311 5441 SETAB: DB 'TA' ;SET TAPE SPEED 937 C313 8AC5 DW TASPD 938 C315 533D DB 'S=' ;SET DISPLAY SPEED 939 C317 95C5 DW DISPD 940 C319 493D DB 'I=' ;SET INPUT PORT 941 C31B 99C5 DW SETIN 942 C31D 4F3D DB 'O=' ;SET OUTPUT PORT 943 C31F 9DC5 DW SETOT 944 C321 4349 DB 'CI' ;SET CUSTOM DRIVER ADDRESS 945 C323 A1C5 DW SETCI 946 C325 434F DB 'CO' ;SET CUSTOM OUTPUT DRIVER ADDRESS 947 C327 A5C5 DW SETCO 948 C329 5845 DB 'XE' ;SET HEADER XEQ ADDRESS 949 C32B ADC5 DW SETXQ 950 C32D 5459 DB 'TY' ;SET HEADER TYPE 951 C32F A9C5 DW SETTY 952 C331 4E3D DB 'N=' ;SET NUMBER OF NULLS 953 C333 B1C5 DW SETNU 954 C335 4352 DB 'CR' ;SET CRC (NORMAL OR IGNORE CRC ERRORS) 955 C337 B5C5 DW SETCR 956 C339 00 DB 0 ;END OF TABLE MARK 957 ; -*- 958 ; 959 ; 960 ; OUTPUT A CRLF FOLLOWED BY A PROMPT 961 ; 962 C33A CD42C3 PROMPT: CALL CRLF 963 C33D 063E MVI B,'>' ;THE PROMPT 964 C33F C319C0 JMP SOUT ;PUT IT ON THE SCREEN 965 ; 966 C342 060A CRLF: MVI B,LF ;LINE FEED 967 C344 CD19C0 CALL SOUT 968 C347 060D MVI B,CR ;CARRIAGE RETURN 969 C349 CD19C0 CALL SOUT 970 C34C 3A10C8 LDA NUCNT ;GET COUNT OF NULLS TO OUTPUT 971 C34F 4F MOV C,A ;SAVE COUNT IN C 972 C350 0D NULOT: DCR C 973 C351 F8 RM ;COUNTED DOWN PAST ZERO (MAX COUNT IS X'7F') 974 C352 AF XRA A ;HERE IS THE NULL 975 C353 CD10C4 CALL OUTH ;OUTPUT IT 976 C356 C350C3 JMP NULOT ;LOOP FOR NUMBER OF NULLS 977 ; 978 ; 979 ; SCAN OVER UP TO 12 CHARACTERS LOOKING FOR A BLANK 980 ; 981 C359 0E0C SBLK: MVI C,12 ;MAXIMUM COMMAND STRING 982 C35B 1A SBLK1: LDAX D 983 C35C FE20 CPI BLANK 984 C35E CA6CC3 JZ SCHR ;GOT A BLANK NOW SCAN PAST IT 985 C361 13 INX D 986 C362 FE3D CPI '=' ;A EQUAL WILL ALSO STOP US (AT NEXT CHAR) 9871 988 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 989+ 19:09 05/27/2017 990+ PAGE 18 991 992 993 994 C364 CA6CC3 JZ SCHR ;FOUND, DE PT TO NEXT CHAR 995 C367 0D DCR C ;NO MORE THAN TWELVE 996 C368 C25BC3 JNZ SBLK1 997 C36B C9 RET ;GO BACK WITH ZERO FLAG SET 998 ; 999 ; 1000 ; SCAN PAST UP TO 10 BLANK POSITIONS LOOKING FOR 1001 ; A NON BLANK CHARACTER. 1002 ; 1003 C36C 0E0A SCHR: MVI C,10 ;SCAN TO FIRST NON BLANK CHR WITHIN 10 1004 C36E 1A SCHR1: LDAX D ;GET NEXT CHARACTER 1005 C36F FE20 CPI SPACE 1006 C371 C0 RNZ ;WE'RE PAST THEM 1007 C372 13 INX D ;NEXT SCAN ADDRESS 1008 C373 0D DCR C 1009 C374 C8 RZ ;COMMAND ERROR 1010 C375 C36EC3 JMP SCHR1 ;KEEP LOOPING 1011 ; 1012 ; THIS ROUTINE SCANS OVER CHARACTERS, PAST BLANKS AND 1013 ; CONVERTS THE FOLLOWING ADDRESS TO HEX. ERRORS RETURN TO 1014 ; THE ERROR HANDLER. 1015 ; 1016 C378 CD59C3 SCONV: CALL SBLK 1017 C37B CA6BC4 JZ ERR1 1018 ; 1019 ; THIS ROUTINE CONVERTS ASCII DIGITS INTO BINARY FOLLOWING 1020 ; A STANDARD HEX CONVERSION. THE SCAN STOPS WHEN AN ASCII 1021 ; SPACE IS ENCOUNTERED. PARAMETER ERRORS REPLACE THE ERROR 1022 ; CHARACTER ON THE SCREEN WITH A QUESTION MARK. 1023 ; 1024 C37E 210000 SHEX: LXI H,0 ;CLEAR H & L 1025 C381 1A SHE1: LDAX D ;GET CHARACTER 1026 C382 FE20 CPI 20H ;IS IT A SPACE? 1027 C384 C8 RZ ;IF SO 1028 C385 FE2F CPI '/' 1029 C387 C8 RZ 1030 C388 FE3A CPI ':' 1031 C38A C8 RZ 1032 ; 1033 C38B 29 HCONV: DAD H ;MAKE ROOM FOR THE NEW ONE 1034 C38C 29 DAD H 1035 C38D 29 DAD H 1036 C38E 29 DAD H 1037 C38F CD9BC3 CALL HCOV1 ;DO THE CONVERSION 1038 C392 D26BC4 JNC ERR1 ;NOT VALID HEXIDECIMAL VALUE 1039 C395 85 ADD L 1040 C396 6F MOV L,A ;MOVE IT IN 1041 C397 13 INX D ;BUMP THE POINTER 1042 C398 C381C3 JMP SHE1 1043 ; 1044 C39B D630 HCOV1: SUI 48 ;REMOVE ASCII BIAS 10451 1046 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1047+ 19:09 05/27/2017 1048+ PAGE 19 1049 1050 1051 1052 C39D FE0A CPI 10 1053 C39F D8 RC ;IF LESS THAN 9 1054 C3A0 D607 SUI 7 ;IT'S A LETTER?? 1055 C3A2 FE10 CPI 10H 1056 C3A4 C9 RET ;WITH TEST IN HAND 1057 ; 1058 ; 1059 ; THIS ROUTINE WILL SEE IF A FIELD (OPERAND) IS PRESENT. 1060 ; IF NOT, THEN HL WILL REMAIN AS THEY WERE ON ENTRY. 1061 ; IF IT WAS PRESENT, THEN HL=THAT VALUE IN HEX. 1062 ; 1063 C3A5 PSCAN EQU $ ;OPTIONAL FIELD SCANNER 1064 C3A5 CD59C3 CALL SBLK ;SEE IF FIELD IS PRESENT 1065 C3A8 C8 RZ ;RETURN LEAVING HL AS THEY WERE ON ENTRY 1066 C3A9 CD7EC3 CALL SHEX ;FIELD IS THERE, GO GET IT 1067 C3AC C9 RET ;HL= EITHER OPTIONAL FIELD (HEX), OR AS IT WAS 1068 ; 1069 ; 1070 ; 1071 ; 1072 ; DUMP COMMAND 1073 ; 1074 ; THIS ROUTINE DUMPS CHARACTERS FROM MEMORY TO THE 1075 ; CURRENT OUTPUT DEVICE. 1076 ; ALL VALUES ARE DESPLAYED AS ASCII HEX. 1077 ; 1078 ; THE COMMAND FORM IS AS FOLLOWS: 1079 ; 1080 ; DUMP ADDR1 ADDR2 1081 ; 1082 ; THE VALUES FROM ADDR1 TO ADDR2 ARE THEN OUTPUT TO THE 1083 ; OUTPUT DEVICE. IF ONLY ADDR1 IS SPECIFIED THEN THE 1084 ; VALUE AT THAT ADDRESS IS OUTPUT. 1085 ; 1086 ; IF WHILE DUMPING, THE MODE KEY IS PRESSED, THE DUMP WILL 1087 ; BE TERMINATED. IF THE SPACE BAR IS PRESSED, THE DUMP 1088 ; WILL BE TEMPORARILY SUSPENDED UNTIL ANY KEY IS PRESSED. 1089 ; 1090 C3AD DUMP EQU $ ;SET UP REGS TO DUMP SPECIFIED AREA 1091 C3AD CD78C3 CALL SCONV ;GET START ADDR (REQUIRED) 1092 C3B0 E5 PUSH H ;SAVE THE START ADDR 1093 C3B1 CDA5C3 CALL PSCAN ;GET OPTIONAL END ADDR, HL=THIS OR START ADDR 1094 C3B4 D1 POP D ;DE=START ADDR 1095 C3B5 EB XCHG ;DE=END ADDR, HL=START ADDR NOW 1096 ; 1097 C3B6 CD42C3 DLOOP: CALL CRLF 1098 C3B9 CDD9C3 CALL ADOUT ;OUTPUT ADDRESS 1099 C3BC CDF7C3 CALL BOUT ;ANOTHER SPACE TO KEEP IT PRETTY 1100 C3BF 0E10 MVI C,16 ;VALUES PER LINE 1101 ; 1102 C3C1 7E DLP1: MOV A,M ;GET THE CHR 11031 1104 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1105+ 19:09 05/27/2017 1106+ PAGE 20 1107 1108 1109 1110 C3C2 C5 PUSH B ;SAVE VALUE COUNT 1111 C3C3 CDDEC3 CALL HBOUT ;SEND IT OUT WITH A BLANK 1112 C3C6 7C MOV A,H ;CRNT ADDR 1113 C3C7 BA CMP D ;VERSUS ENDING ADDR 1114 C3C8 DAD0C3 JC DLP1A ;NOT DONE YET 1115 C3CB 7D MOV A,L ;TRY LOW ORDER BYTE 1116 C3CC BB CMP E 1117 C3CD D218C2 JNC COMND ;ALL DONE WHEN CRNT REACHES ENDING 1118 C3D0 DLP1A EQU $ ;HERE TO KEEP DUMPING 1119 C3D0 C1 POP B ;VALUES PER LINE 1120 C3D1 23 INX H 1121 C3D2 0D DCR C ;BUMP THE LINE COUNT 1122 C3D3 C2C1C3 JNZ DLP1 ;NOT ZERO IF MORE FOR THIS LINE 1123 C3D6 C3B6C3 JMP DLOOP ;DO A LFCR BEFORE THE NEXT 1124 ; 1125 ; OUTPUT HL AS HEX 16 BIT VALUE 1126 ; 1127 C3D9 7C ADOUT: MOV A,H ;H FIRST 1128 C3DA CDFCC3 CALL HEOUT 1129 C3DD 7D MOV A,L ;THEN L FOLLOWED BY A SPACE 1130 ; 1131 C3DE CDFCC3 HBOUT: CALL HEOUT 1132 C3E1 CD1FC0 CALL SINP ;SEE IF WE SHD ESCAPE FM DUMP 1133 C3E4 CAF7C3 JZ BOUT ;NO--ADD THE SPACE THEN 1134 C3E7 E67F ANI 7FH ;MAKE SURE ITS CLEAR OF PARITY 1135 C3E9 CA18C2 JZ COMND ;EITHER MODE (OR CTL-@) 1136 C3EC FE20 CPI ' ' ;IS IT SPACE 1137 C3EE C2F7C3 JNZ BOUT ;NO--IGNORE THE CHAR 1138 C3F1 CD1FC0 WTLP1: CALL SINP ;ON SPACE, WAIT FOR ANY OTHER CHAR 1139 C3F4 CAF1C3 JZ WTLP1 ;JUST LOOP AFTER A SPACE UNTIL ANY KEY PRESSED 1140 C3F7 0620 BOUT: MVI B,' ' 1141 C3F9 C319C0 JMP SOUT ;PUT IT OUT 1142 ; 1143 C3FC 4F HEOUT: MOV C,A ;GET THE CHARACTER 1144 C3FD 0F RRC 1145 C3FE 0F RRC ;MOVE THE HIGH FOUR DOWN 1146 C3FF 0F RRC 1147 C400 0F RRC 1148 C401 CD05C4 CALL HEOU1 ;PUT THEM OUT 1149 C404 79 MOV A,C ;THIS TIME THE LOW FOUR 1150 ; 1151 C405 E60F HEOU1: ANI 0FH ;FOUR ON THE FLOOR 1152 C407 C630 ADI 48 ;WE WORK WITH ASCII HERE 1153 C409 FE3A CPI 58 ;0-9? 1154 C40B DA10C4 JC OUTH ;YUP! 1155 C40E C607 ADI 7 ;MAKE IT A LETTER 1156 C410 47 OUTH: MOV B,A ;OUTPUT IT FROM REGISTER 'B' 1157 C411 C319C0 JMP SOUT 1158 ; 1159 ; 1160 ; ENTR COMMAND 11611 1162 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1163+ 19:09 05/27/2017 1164+ PAGE 21 1165 1166 1167 1168 ; 1169 ; THIS ROUTINE GETS VALUES FROM THE KEYBOARD AND ENTERS 1170 ; THEM INTO MEMORY. THE INPUT VALUES ARE SCANNED FOLLOWING 1171 ; A STANDARD 'GCLIN' INPUT SO ON-SCREEN EDITING MAY TAKE 1172 ; PLACE PRIOR TO THE LINE TERMINATOR. A SLASH '/' 1173 ; ENDS THE ROUTINE AND RETURNS CONTROL TO THE COMMAND MODE. 1174 ; 1175 C414 CD78C3 ENTER: CALL SCONV ;SCAN OVER CHARS AND GET ADDRESS 1176 C417 E5 PUSH H ;SAVE ADDRESS 1177 ; 1178 C418 CD42C3 ENLOP: CALL CRLF 1179 C41B 063A MVI B,':' 1180 C41D CD19C0 CALL SOUT ;DSPLY THE COLON 1181 C420 CD27C2 CALL GCLI0 ;INIT AND PROCESS A LINE 1182 C423 CDAAC2 CALL STUP ;SET UP TO PROCESS INPUT LINE 1183 C426 EB XCHG ;....TO DE 1184 ; 1185 ; 1186 C427 0E03 ENLO1: MVI C,3 ;NO MORE THAN THREE SPACES BETWEEN VALUES 1187 C429 CD6EC3 CALL SCHR1 ;SCAN TO NEXT VALUE 1188 C42C CA18C4 JZ ENLOP ;LAST ENTRY FOUND START NEW LINE 1189 ; 1190 C42F FE2F CPI '/' ;COMMAND TERMINATOR? 1191 C431 CA18C2 JZ COMND ;IF SO... 1192 C434 CD7EC3 CALL SHEX ;CONVERT VALUE 1193 C437 FE3A CPI ':' ;ADDRESS TERMINATOR? 1194 C439 CA44C4 JZ ENLO3 ;GO PROCESS IF SO 1195 C43C 7D MOV A,L ;GET LOW PART AS CONVERTED 1196 C43D E1 POP H ;GET MEMORY ADDRESS 1197 C43E 77 MOV M,A ;PUT IN THE VALUE 1198 C43F 23 INX H 1199 C440 E5 PUSH H ;BACK GOES THE ADDRESS 1200 C441 C327C4 JMP ENLO1 ;CONTINUE THE SCAN 1201 ; 1202 C444 E3 ENLO3: XTHL ;PUT NEW ADDRESS ON STACK 1203 C445 13 INX D ;MOVE SCAN PAST TERMINATOR 1204 C446 C327C4 JMP ENLO1 1205 ; 1206 ; 1207 ; EXECUTE COMMAND 1208 ; 1209 ; THIS ROUTINE GETS THE FOLLOWING PARAMETER AND DOES A 1210 ; PROGRAM JUMP TO THE LOCATION GIVEN BY IT. IF PROPER 1211 ; STACK OPERATIONS ARE USED WITHIN THE EXTERNAL PROGRAM 1212 ; IT CAN DO A STANDARD 'RET'URN TO THE CUTER COMMAND MODE. 1213 ; 1214 ; 1215 C449 CD78C3 EXEC: CALL SCONV ;SCAN PAST BLANKS AND GET PARAMETER 1216 C44C EXEC1 EQU $ ;HERE TO GO TO HL 1217 C44C E5 PUSH H ;SAVE ON STACK 1218 C44D 2100C0 LXI H,START ;LET USER KNOW WHERE WE ARE 12191 1220 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1221+ 19:09 05/27/2017 1222+ PAGE 22 1223 1224 1225 1226 C450 C9 RET ;AND OFF TO USER 1227 ; 1228 ; 1229 ; 1230 ; 1231 ; THIS ROUTINE GETS A NAME OF UP TO 5 CHARACTERS 1232 ; FROM THE INPUT STRING. IF THE TERMINATOR IS A 1233 ; SLASH (/) THEN THE CHARACTER FOLLOWING IS TAKEN 1234 ; AS THE CASSETTE UNIT SPECIFICATION. 1235 ; 1236 ; 1237 C451 NAME0 EQU $ ;ENTER HERE TO SET HL TO THEAD 1238 C451 211CC8 LXI H,THEAD ;PT WHERE TO PUT NAME 1239 C454 CD59C3 NAME: CALL SBLK ;SCAN OVER TO FIRST CHRS 1240 C457 0606 MVI B,6 1241 ; 1242 C459 1A NAME1: LDAX D ;GET CHARACTER 1243 C45A FE20 CPI ' ' ;NO UNIT DELIMITER 1244 C45C CA80C4 JZ NFIL 1245 C45F FE2F CPI '/' ;UNIT DELIMITER 1246 C461 CA80C4 JZ NFIL 1247 C464 77 MOV M,A 1248 C465 13 INX D ;BUMP THE SCAN POINTER 1249 C466 23 INX H 1250 C467 05 DCR B 1251 C468 C259C4 JNZ NAME1 ;NAME IS OK, FALL THRU TO 'ERR1' IF NOT 1252 ; 1253 ; CUTER ERROR HANDLER 1254 ; 1255 C46B EB ERR1: XCHG ;GET SCAN ADDRESS 1256 C46C 363F ERR2: MVI M,'?' ;FLAG THE ERROR 1257 C46E 3A07C8 LDA OPORT ;SEE IF VIA VDM DRIVER 1258 C471 B7 ORA A 1259 C472 CA18C2 JZ COMND ;YES--VDM SCREEN NOW HAS THE ? 1260 C475 CD42C3 CALL CRLF 1261 C478 063F MVI B,'?' ;SET UP THE ???? 1262 C47A CD19C0 CALL SOUT ;INDICATE INPUT NOT VALID 1263 C47D C318C2 JMP COMND ;NOW READY FOR NEXT INPUT 1264 ; 1265 ; 1266 ; 1267 ; HERE WE HAVE SCANNED OFF THE NAME. ZERO FILL IN FOR 1268 ; NAMES LESS THAN FIVE CHARACTERS. 1269 ; 1270 C480 3600 NFIL: MVI M,0 ;PUT IN AT LEAST ONE ZERO 1271 C482 23 INX H 1272 C483 05 DCR B 1273 C484 C280C4 JNZ NFIL ;LOOP UNTIL B IS ZERO 1274 ; 1275 C487 FE2F CPI '/' ;IS THERE A UNIT SPECIFICATION? 1276 C489 3E01 MVI A,1 ;PRETEND NOT 12771 1278 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1279+ 19:09 05/27/2017 1280+ PAGE 23 1281 1282 1283 1284 C48B C294C4 JNZ DEFLT 1285 C48E 13 INX D ;MOVE PAST THE TERMINATOR 1286 C48F CD6CC3 CALL SCHR ;GO GET IT 1287 C492 D630 SUI '0' ;REMOVE ASCII BIAS 1288 ; 1289 C494 DEFLT EQU $ ;CNVRT TO INTERNAL BIT FOR TAPE CONTROL 1290 C494 E601 ANI 1 ;JUST BIT ZERO 1291 C496 3E80 MVI A,TAPE1 ;ASSUME TAPE ONE 1292 C498 C29CC4 JNZ STUNT ;IF NON ZERO, IT IS ONE 1293 C49B 1F RAR ;ELSE MAKE IT TAPE TWO 1294 C49C 3254C8 STUNT: STA FNUMF ;SET IT IN 1295 C49F C9 RET 1296 ; 1297 ; 1298 ; 1299 ; THIS ROUTINE PROCESSES THE XEQ AND GET COMMANDS 1300 ; 1301 ; 1302 C4A0 3E TXEQ: DB 3EH ;THIS BEGINS "MVI" OF THE "XRA" FOLLOWING 1303 C4A1 AF TLOAD: XRA A ;A=0 TLOAD, A=AF (#0) THEN XEQ 1304 C4A2 F5 PUSH PSW ;SAVE FLAG TO SAY WHETHER LOAD OR XEQ 1305 C4A3 212CC8 LXI H,DHEAD ;PLACE DUMMY HDR HERE FOR COMPARES 1306 C4A6 CD54C4 CALL NAME ;SET IN NAME AND UNIT 1307 C4A9 210000 LXI H,0 ;ASSUME LOAD ADDR NOT GIVEN 1308 C4AC CDA5C3 CALL PSCAN ;HL EITHER =0, OR OVERRIDE LOAD ADDR 1309 ; 1310 C4AF EB TLOA2: XCHG ;PUT ADDRESS IN DE 1311 C4B0 212CC8 LXI H,DHEAD ;PT TO NORMAL HDR 1312 C4B3 7E MOV A,M ;GET 1ST CHAR OF NAME 1313 C4B4 B7 ORA A ;IS THERE A NAME? 1314 C4B5 C2BBC4 JNZ TLOA3 ;YES--LOOK FOR IT 1315 C4B8 211CC8 LXI H,THEAD ;PT TO SAME HDR TO LOAD NEXT FILE 1316 C4BB E5 TLOA3: PUSH H ;SAVE PTR TO WHICH HDR TO USE 1317 C4BC CD44C5 CALL ALOAD ;GET UNIT AND SPEED 1318 C4BF E1 POP H ;RESTORE PTR TO PROPER HDR TO USE 1319 C4C0 CDC7C6 CALL RTAPE ;READ IN THE TAPE 1320 C4C3 DA10C5 JC TAERR ;TAPE ERROR? 1321 ; 1322 C4C6 CD4CC5 CALL NAOUT ;PUT OUT THE HEADER PARAMETERS 1323 C4C9 F1 POP PSW ;RESTORE FLAG SAYING WHETHER IT WAS LOAD OR XEQ 1324 C4CA B7 ORA A 1325 C4CB C8 RZ ;AUTO XEQ NOT WANTED 1326 C4CC 3A22C8 LDA HTYPE ;CHECK TYPE 1327 C4CF B7 ORA A ;SET FLAGS 1328 C4D0 FA10C5 JM TAERR ;TYPE IS NON XEQ 1329 C4D3 3A21C8 LDA THEAD+5 1330 C4D6 B7 ORA A 1331 C4D7 C210C5 JNZ TAERR ;THE BYTE MUST BE ZERO FOR AUTO XEQ 1332 C4DA 2A27C8 LHLD XEQAD ;GET THE TAPE ADDRESS 1333 C4DD C34CC4 JMP EXEC1 ;AND GO OFF TO IT 1334 ; 13351 1336 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1337+ 19:09 05/27/2017 1338+ PAGE 24 1339 1340 1341 1342 ; 1343 ; 1344 ; THIS ROUTINE IS USED TO SAVE PROGRAMS AND DATA ON 1345 ; THE CASSETTE UNIT. 1346 ; 1347 ; 1348 C4E0 TSAVE EQU $ ;SAVE MEMORY IMAGE TO TAPE 1349 C4E0 CD51C4 CALL NAME0 ;GET NAME AND UNIT 1350 C4E3 CD78C3 CALL SCONV ;GET START ADDRESS 1351 C4E6 E5 PUSH H ;SAVE START ADDR FOR SIZE COMPUTATION LATER 1352 C4E7 CD78C3 CALL SCONV ;GET END ADDR (REQUIRED) 1353 C4EA E3 XTHL ;HL=START ADDR NOW, STACK=END ADDR 1354 C4EB E5 PUSH H ;STACK =START FOLLOWED BY END 1355 C4EC CDA5C3 CALL PSCAN ;SEE IF RETRIEVE FROM ADDR 1356 C4EF 2225C8 SHLD LOADR ;EITHER ACTUAL START, OR OVERRIDE INTO HDR 1357 C4F2 E1 POP H ;HL=START ADDR 1358 C4F3 D1 POP D ;DE=END ADDR 1359 C4F4 E5 PUSH H ;PUT START BACK ONTO STACK 1360 C4F5 7B MOV A,E ;SIZE=END-START+1 1361 C4F6 95 SUB L 1362 C4F7 6F MOV L,A 1363 C4F8 7A MOV A,D 1364 C4F9 DE00 SBI 0 ;THIS EQUALS A "SBB H" 1365 C4FB 94 SUB H ;THIS IS NEEDED 1366 C4FC 67 MOV H,A 1367 C4FD 23 INX H 1368 C4FE 2223C8 SHLD BLOCK ;STORE THE SIZE 1369 C501 E5 PUSH H ;SAVE AS THE BLOCK SIZE 1370 ; 1371 C502 CD44C5 CALL ALOAD ;GET UNIT AND SPEED 1372 C505 211CC8 LXI H,THEAD ;PT TO HEADER TO WRITE 1373 C508 CDADC7 CALL WHEAD ;TURN TAPE ON, THEN WRITE HEADER 1374 C50B D1 POP D ;GET BACK THE SIZE 1375 C50C E1 POP H ;AND GET BACK THE ACTUAL START ADDR 1376 C50D C38DC7 JMP WTAP1 ;WRITE THE BLK (W/EXTRA PUSH) 1377 ; 1378 ; OUTPUT ERROR AND HEADER 1379 ; 1380 C510 CD42C3 TAERR: CALL CRLF 1381 C513 1606 MVI D,6 1382 C515 2121C5 LXI H,ERRM 1383 C518 CD66C5 CALL NLOOP ;OUTPUT ERROR 1384 C51B CD4CC5 CALL NAOUT ;THEN THE HEADER 1385 C51E C315C2 JMP COMN1 1386 ; 1387 C521 4552524F ERRM: DB 'ERROR ' 1388 C525 5220 1389 1390 ; 1391 ; 1392 ; CAT COMMAND 13931 1394 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1395+ 19:09 05/27/2017 1396+ PAGE 25 1397 1398 1399 1400 ; 1401 ; THIS ROUTINE READS HEADERS FROM THE TAPE AND OUTPUTS 1402 ; THEM TO THE OUTPUT DEVICE. IT CONTINUES UNTIL THE 1403 ; MODE KEY IS DEPRESSED. 1404 ; 1405 C527 TLIST EQU $ ;PRODUCE A LIST OF FILES ON A TAPE 1406 C527 CD51C4 CALL NAME0 ;GET UNIT IF ANY (NAME IS IGNORED) 1407 C52A CD42C3 CALL CRLF ;START ON A FRESH LINE 1408 ; 1409 ; 1410 C52D CD44C5 LLIST: CALL ALOAD 1411 C530 0601 MVI B,1 1412 C532 CDEDC7 CALL TON ;TURN ON THE TAPE 1413 C535 CD1FC7 LIST1: CALL RHEAD 1414 C538 DA15C2 JC COMN1 ;TRUN OFF THE TAPE UNIT 1415 C53B C235C5 JNZ LIST1 1416 C53E CD4CC5 CALL NAOUT ;OUTPUT THE HEADER 1417 C541 C32DC5 JMP LLIST 1418 ; 1419 ; 1420 ; THIS ROUTINE GETS THE CASSETTE UNIT NUMBER AND 1421 ; SPEED TO REGISTER "A" FOR THE TAPE CALLS 1422 ; 1423 C544 2154C8 ALOAD: LXI H,FNUMF ;POINT TO THE UNIT SPECIFICATION 1424 C547 3A0DC8 LDA TSPD ;GET THE TAPE SPEED 1425 C54A B6 ORA M ;PUT THEM TOGETHER 1426 C54B C9 RET ;AND GO BACK 1427 ; 1428 ; THIS ROUTINE OUTPUTS THE NAME AND PARAMETERS OF 1429 ; THEAD TO THE OUTPUT DEVICE. 1430 ; 1431 ; 1432 C54C 1608 NAOUT: MVI D,8 1433 C54E 211BC8 LXI H,THEAD-1 ;POINT TO THE HEADER 1434 C551 CD66C5 CALL NLOOP ;OUTPUT THE HEADER 1435 C554 CDF7C3 CALL BOUT ;ANOTHER BLANK 1436 C557 2A25C8 LHLD LOADR ;NOW THE LOAD ADDRESS 1437 C55A CDD9C3 CALL ADOUT ;PUT IT OUT 1438 C55D 2A23C8 LHLD BLOCK ;AND THE BLOCK SIZE 1439 C560 CDD9C3 CALL ADOUT 1440 C563 C342C3 JMP CRLF ;DO THE CRLF AND RETURN 1441 ; 1442 ; 1443 C566 7E NLOOP: MOV A,M ;GET CHARACTER 1444 C567 B7 ORA A 1445 C568 C26DC5 JNZ CHRLI ;IF IT ISN'T A ZERO 1446 C56B 3E20 MVI A,' ' ;SPACE OTHERWISE 1447 C56D CHRLI EQU $ ;CHAR IS OK TO SEND 1448 C56D CD10C4 CALL OUTH ;OUTPUT IT FROM A REG 1449 C570 23 INX H 1450 C571 15 DCR D 14511 1452 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1453+ 19:09 05/27/2017 1454+ PAGE 26 1455 1456 1457 1458 C572 C266C5 JNZ NLOOP 1459 C575 C9 RET 1460 ; 1461 ; 1462 ; 1463 ; 1464 ; "SET" COMMAND 1465 ; 1466 ; THIS ROUTINE GETS THE ASSOCIATED PARAMETER AND 1467 ; DISPATCHES TO THE PROPER ROUTINE FOR SETTING 1468 ; MEMORY VALUES. 1469 ; 1470 C576 CD59C3 CSET: CALL SBLK ;SCAN TO SECONDARY COMMAND 1471 C579 CA6BC4 JZ ERR1 ;MUST HAVE AT LEAST SOMETHING!! 1472 C57C D5 PUSH D ;SAVE SCAN ADDRESS 1473 C57D CD78C3 CALL SCONV ;CONVERT FOLLOWING VALUE 1474 C580 E3 XTHL ;HL=SAVED SCAN ADDR AND STACK=VALUE 1475 C581 1111C3 LXI D,SETAB ;SECONDARY COMMAND TABLE 1476 C584 CD91C2 CALL FDCOM ;TRY TO LOCATE IT 1477 C587 C382C2 JMP DISP0 ;OFF TO IT OR ERROR IF NOT IN TBL 1478 ; 1479 ; 1480 ; THIS ROUTINE SETS THE TAPE SPEED 1481 ; 1482 C58A TASPD EQU $ ;GET CONVERTED VALUE 1483 C58A B7 ORA A ;IS IT ZERO? 1484 C58B CA90C5 JZ SETSP ;YES--THAT IS A PROPER SPEED 1485 C58E 3E20 MVI A,32 ;NO--SET SPEED PROPERLY THEN 1486 C590 320DC8 SETSP: STA TSPD 1487 C593 C9 RET 1488 ; 1489 ; 1490 C594 STSPD EQU $ ;VDM ESCAPE SEQUENCE COMES HERE 1491 C594 78 MOV A,B ;GET CHAR FOR FOLLOWING DISPD 1492 C595 DISPD EQU $ ;SET DISPLAY SPEED 1493 C595 320BC8 STA SPEED 1494 C598 C9 RET 1495 ; 1496 ; 1497 C599 SETIN EQU $ ;SET AN INPUT PSUEDO PORT 1498 C599 3206C8 STA IPORT 1499 C59C C9 RET 1500 ; 1501 ; 1502 C59D SETOT EQU $ ;SET AN OUTPUT PSUEDO PORT 1503 C59D 3207C8 STA OPORT 1504 C5A0 C9 RET 1505 ; 1506 ; 1507 C5A1 SETCI EQU $ ;DEFINE USER INPUT RTN ADDR 1508 C5A1 2200C8 SHLD UIPRT 15091 1510 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1511+ 19:09 05/27/2017 1512+ PAGE 27 1513 1514 1515 1516 C5A4 C9 RET 1517 ; 1518 ; 1519 C5A5 SETCO EQU $ ;DEFINE USER OUTPUT RTN ADDR 1520 C5A5 2202C8 SHLD UOPRT 1521 C5A8 C9 RET 1522 ; 1523 ; 1524 C5A9 SETTY EQU $ ;SET TAPE HDR TYPE 1525 C5A9 3222C8 STA HTYPE 1526 C5AC C9 RET 1527 ; 1528 ; 1529 C5AD SETXQ EQU $ ;SET TAPE-EXECUTE ADDDR FOR HDR 1530 C5AD 2227C8 SHLD XEQAD 1531 C5B0 C9 RET 1532 ; 1533 ; 1534 C5B1 SETNU EQU $ ;HERE TO SET NUMBER OF NULLS 1535 C5B1 3210C8 STA NUCNT ;THIS IS IT 1536 C5B4 C9 RET 1537 ; 1538 ; 1539 C5B5 SETCR EQU $ ;SET CRC TO BE NORMAL, OR IGNORE CRC ERRORS 1540 C5B5 3211C8 STA IGNCR ;FF=IGNORE CRC ERRORS, ELSE=NORMAL 1541 C5B8 C9 RET 1542 ; 1543 ; 1544 C5B9 CUSET EQU $ ;TRY TO SET/CLEAR CUSTOM ROUTINE ADDR 1545 C5B9 CD51C4 CALL NAME0 ;GET A NAME (S/B 2 CHARS OR MORE) 1546 C5BC 2118C2 LXI H,COMND ;PT HERE IN CASE ADDR NOT GIVEN 1547 C5BF CDA5C3 CALL PSCAN ;GET OPTIONAL OPERAND IF ANY 1548 C5C2 E5 PUSH H ;SAVE THAT VALUE (IF ANY) 1549 C5C3 211CC8 LXI H,THEAD ;PT TO NAME 1550 C5C6 CD8EC2 CALL FDCOU ;SEE IF NAME IS KNOWN IN CUST TABLE 1551 C5C9 CACFC5 JZ CUSE2 ;NO--PROCEED TO KNOW IT 1552 C5CC 1B DCX D ;DE PT TO 1ST CHAR OF NAME IN TBL 1553 C5CD 3600 MVI M,0 ;(HL CAME BACK PT'ING TO THEAD) CLR THIS NAME 1554 C5CF CUSE2 EQU $ ;ENTER NEW ONE IN TBL 1555 C5CF 7E MOV A,M ;GET 1ST CHAR OF NAME 1556 C5D0 12 STAX D ;PUT NAME INTO TABLE 1557 C5D1 13 INX D 1558 C5D2 23 INX H 1559 C5D3 7E MOV A,M ;GET 2ND CHAR OF NAME 1560 C5D4 12 STAX D ;NAME IS NOW POSTED 1561 C5D5 13 INX D ;PT TO 1ST BYTE OF ADDR 1562 C5D6 E1 POP H ;RESTORE SAVED RTN ADDR 1563 C5D7 EB XCHG ;DE=RTN ADDR, HL=THIS CU ENTRY 1564 C5D8 73 MOV M,E ;LO BYTE 1565 C5D9 23 INX H 1566 C5DA 72 MOV M,D ;AND HI BYTE 15671 1568 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1569+ 19:09 05/27/2017 1570+ PAGE 28 1571 1572 1573 1574 C5DB C9 RET ;ALL DONE 1575 ; 1576 ; 1577 ; -*- 1578 ; 1579 ; 1580 ; 1581 ; 1582 ; THE FOLLOWING ROUTINES PROVIDE "BYTE BY BYTE" ACCESS 1583 ; TO THE CASSETTE TAPES ON EITHER A READ OR WRITE BASIS. 1584 ; 1585 ; THE TAPE IS READ ONE BLOCK AT A TIME AND INDIVIDUAL 1586 ; TRANSFERS OF DATA HANDLED BY MANAGING A BUFFER AREA. 1587 ; 1588 ; THE BUFFER AREA IS CONTROLLED BY A FILE CONTROL BLOCK 1589 ; (FCB) WHOSE STRUCTURE IS: 1590 ; 1591 ; 1592 ; 7 BYTES FOR EACH OF THE TWO FILES STRUCTURED AS 1593 ; FOLLOWS: 1594 ; 1595 ; 1 BYTE - ACCESS CONTROL 00 IF CLOSED 1596 ; FF IF READING 1597 ; FE IF WRITING 1598 ; 1 BYTE - READ COUNTER 1599 ; 1 BYTE - BUFFER POSITION POINTER 1600 ; 2 BYTE - CONTROL HEADER ADDRESS 1601 ; 2 BYTE - BUFFER LOCATION ADDRESS 1602 ; 1603 ; 1604 ; 1605 ; THIS ROUTINE "OPENS" THE CASSETTE UNIT FOR ACCESS 1606 ; 1607 ; ON ENTRY: A - HAS THE TAPE UNIT NUMBER (1 OR 2) 1608 ; HL - HAS USER SUPPLIED HEADER FOR TAPE FILE 1609 ; 1610 ; 1611 ; NORMAL RETURN: ALL REGISTERS ARE ALTERED 1612 ; BLOCK IS READY FOR ACCESS 1613 ; 1614 ; ERROR RETURN: CARRY BIT IS SET 1615 ; 1616 ; ERRORS: BLOCK ALREADY OPEN 1617 ; 1618 ; 1619 C5DC E5 BOPEN: PUSH H ;SAVE HEADER ADDRESS 1620 C5DD CD2FC6 CALL LFCB ;GET ADDRESS OF FILE CONTROL 1621 C5E0 C2F6C5 JNZ TERE2 ;FILE WAS ALREADY OPEN 1622 C5E3 3601 MVI M,1 ;NOW IT IS 1623 C5E5 23 INX H ;POINT TO READ COUNT 1624 C5E6 77 MOV M,A ;ZERO 16251 1626 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1627+ 19:09 05/27/2017 1628+ PAGE 29 1629 1630 1631 1632 C5E7 23 INX H ;POINT TO BUFFER CURSOR 1633 C5E8 77 MOV M,A ;PUT IN THE ZERO COUNT 1634 ; 1635 ; ALLOCATE THE BUFFER 1636 ; 1637 C5E9 1163C8 LXI D,FBUF1 ;POINT TO BUFFER AREA 1638 C5EC 3A54C8 LDA FNUMF ;GET WHICH ONE WE ARE GOING TO USE 1639 C5EF 82 ADD D 1640 C5F0 57 MOV D,A ;256 BIT ADD 1641 ; 1642 C5F1 C1 UBUF: POP B ;HEADER ADDRESS 1643 C5F2 B7 ORA A ;CLEAR CARRY AND RETURN AFTER STORING PARAMS 1644 C5F3 C3B2C6 JMP PSTOR ;STORE THE VALUES 1645 ; 1646 ; GENERAL ERROR RETURN POINTS FOR STACK CONTROL 1647 ; 1648 C5F6 E1 TERE2: POP H 1649 C5F7 D1 TERE1: POP D 1650 C5F8 AF TERE0: XRA A ;CLEAR ALL FLAGS 1651 C5F9 37 STC ;SET ERROR 1652 C5FA C9 RET 1653 ; 1654 ; 1655 C5FB 3D EOFER: DCR A ;SET MINUS FLAGS 1656 C5FC 37 STC ;AND CARRY 1657 C5FD D1 POP D ;CLEAR THE STACK 1658 C5FE C9 RET ;THE FLAGS TELL ALL 1659 ; 1660 ; 1661 ; 1662 ; 1663 ; THIS ROUTINE CLOSES THE FILE BUFFER TO ALLOW ACCESS 1664 ; FOR A DIFFERENT CASSETTE OR PROGRAM. IF THE FILE 1665 ; OPERATIONS WERE "WRITE" THEN THE LAST BLOCK IS WRITTED 1666 ; OUT AND AN "END OF FILE" WRITTEN TO THE TAPE. IF 1667 ; THE OPERATIONS WERE "READS" THEN THE FILE IS JUST 1668 ; MADE READY FOR NEW USE. 1669 ; 1670 ; ON ENTRY: A - HAS WHICH UNIT (1 OR 2) 1671 ; 1672 ; ERROR RETURNS: FILE WASN'T OPEN 1673 ; 1674 ; 1675 C5FF CD2FC6 PCLOS: CALL LFCB ;GET CONTROL BLOCK ADDRESS 1676 C602 C8 RZ ;WASN'T OPEN, CARRY IS SET FROM LFCB 1677 C603 B7 ORA A ;CLEAR CARRY 1678 C604 3C INR A ;SET CONDITION FLAGS 1679 C605 3600 MVI M,0 ;CLOSE THE CONTROL BYTE 1680 C607 C8 RZ ;WE WERE READING...NOTHING MORE TO DO 1681 ; 1682 ; THE FILE OPERATIONS WERE "WRITES" 16831 1684 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1685+ 19:09 05/27/2017 1686+ PAGE 30 1687 1688 1689 1690 ; 1691 ; PUT THE CURRENT BLOCK ON THE TAPE 1692 ; (EVEN IF ONLY ONE BYTE) 1693 ; THEN WRITE AN END OF FILE TO THE TAPE 1694 ; 1695 ; 1696 C608 23 INX H 1697 C609 23 INX H 1698 C60A 7E MOV A,M ;GET CURSOR POSITION 1699 C60B 7E MOV A,M ;GET CURSOR POSITION 1700 C60C CDBBC6 CALL PLOAD ;BC GET HEADER ADDRESS, DE BUFFER ADDRESS 1701 C60F C5 PUSH B ;HEADER TO STACK 1702 C610 210700 LXI H,BLKOF ;OFFSET TO BLOCK SIZE 1703 C613 09 DAD B 1704 C614 B7 ORA A ;TEST COUNT 1705 C615 CA27C6 JZ EOFW ;NO BYTES...JUST WRITE EOF 1706 ; 1707 ; WRITE LAST BLOCK 1708 ; 1709 C618 E5 PUSH H ;SAVE BLOCK SIZE POINTER FOR EOF 1710 C619 77 MOV M,A ;PUT IN COUNT 1711 C61A 23 INX H 1712 C61B 3600 MVI M,0 ;ZERO THE HIGHER BYTE 1713 C61D 23 INX H 1714 C61E 73 MOV M,E ;BUFFER ADDRESS 1715 C61F 23 INX H 1716 C620 72 MOV M,D 1717 C621 60 MOV H,B 1718 C622 69 MOV L,C ;PUT HEADER ADDRESS IN HL 1719 C623 CD79C7 CALL WFBLK ;GO WRITE IT OUT 1720 C626 E1 POP H ;BLOCK SIZE POINTER 1721 ; 1722 ; NOW WRITE END OF FILE TO CASSETTE 1723 ; 1724 C627 AF EOFW: XRA A ;PUT IN ZEROS FOR SIZE: EOF MARK IS ZERO BYTES! 1725 C628 77 MOV M,A 1726 C629 23 INX H 1727 C62A 77 MOV M,A 1728 C62B E1 POP H ;HEADER ADDRESS 1729 C62C C379C7 JMP WFBLK ;WRITE IT OUT AND RETURN 1730 ; 1731 ; 1732 ; 1733 ; 1734 ; THIS ROUTINE LOCATES THE FILE CONTROL BLOCK POINTED TO 1735 ; BY REGISTER "A". ON RETURN HL POINT TO THE CONTROL BYT 1736 ; AND REGISTER "A" HAS THE CONTROL WORD WITH THE FLAGS 1737 ; SET FOR IMMEDIATE CONDITION DECISIONS. 1738 ; 1739 ; 1740 C62F 2155C8 LFCB: LXI H,FCBAS ;POINT TO THE BASE OF IT 17411 1742 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1743+ 19:09 05/27/2017 1744+ PAGE 31 1745 1746 1747 1748 C632 1F RAR ;MOVE THE 1 & 2 TO 0 & 1 LIKE COMPUTERS LIKE 1749 C633 E601 ANI 1 ;SMALL NUMBERS ARE THE RULE 1750 C635 3254C8 STA FNUMF ;CURRENT ACCESS FILE NUMBER 1751 C638 CA3EC6 JZ LFCB1 ;UNIT ONE (VALUE OF ZERO) 1752 C63B 215CC8 LXI H,FCBA2 ;UNIT TWO--PT TO ITS FCB 1753 C63E LFCB1 EQU $ ;HL PT TO PROPER FCB 1754 C63E 7E MOV A,M ;PICK UP FLAGS FM FCB 1755 C63F B7 ORA A ;SET FLAGS BASED ON CONTROL WORD 1756 C640 37 STC ;SET CARRY IN CASE OF IMMEDIATE ERROR RETURN 1757 C641 C9 RET 1758 ; 1759 ; 1760 ; 1761 ; 1762 ; READ TAPE BYTE ROUTINE 1763 ; 1764 ; ENTRY: - A - HAS FILE NUMBER 1765 ; EXIT: NORMAL - A - HAS BYTE 1766 ; ERROR 1767 ; CARRY SET - IF FILE NOT OPEN OR 1768 ; PREVIOUS OPERATIONS WERE WRITE 1769 ; CARRY & MINUS - END OF FILE ENCOUNTERED 1770 ; 1771 ; 1772 ; 1773 ; 1774 C642 CD2FC6 RTBYT: CALL LFCB ;LOCATE THE FILE CONTROL BLOCK 1775 C645 C8 RZ ;FILE NOT OPEN 1776 C646 3C INR A ;TEST IF FF 1777 C647 FAF8C5 JM TERE0 ;ERROR WAS WRITING 1778 C64A 36FF MVI M,(-1) AND 0FFH ;SET IT AS READ (IN CASE IT WAS JUST OPENED) 1779 C64C 23 INX H 1780 C64D 7E MOV A,M ;GET READ COUNT 1781 C64E E5 PUSH H ;SAVE COUNT ADDRESS 1782 C64F 23 INX H 1783 C650 CDBBC6 CALL PLOAD ;GET THE OTHER PARAMETERS 1784 C653 E1 POP H 1785 C654 B7 ORA A 1786 C655 C271C6 JNZ GTBYT ;IF NOT EMPTY GO GET BYTE 1787 ; 1788 ; CURSOR POSITION WAS ZERO...READ A NEW BLOCK INTO 1789 ; THE BUFFER. 1790 ; 1791 C658 D5 RDNBLK: PUSH D ;BUFFER POINTER 1792 C659 E5 PUSH H ;TABLE ADDRESS 1793 C65A 23 INX H 1794 C65B CDA2C6 CALL PHEAD ;PREPARE THE HEADER FOR READ 1795 C65E CDC4C6 CALL RFBLK ;READ IN THE BLOCK 1796 C661 DAF6C5 JC TERE2 ;ERROR POP OFF STACK BEFORE RETURN 1797 C664 E1 POP H 1798 C665 7B MOV A,E ;LOW BYTE OF COUNT (WILL BE ZERO IF 256) 17991 1800 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1801+ 19:09 05/27/2017 1802+ PAGE 32 1803 1804 1805 1806 C666 B2 ORA D ;SEE IF BOTH ARE ZERO 1807 C667 CAFBC5 JZ EOFER ;BYTE COUNT WAS ZERO....END OF FILE 1808 C66A 73 MOV M,E ;NEW COUNT ( ZERO IS 256 AT THIS POINT) 1809 C66B 23 INX H ;BUFFER LOCATION POINTER 1810 C66C 3600 MVI M,0 1811 C66E 2B DCX H 1812 C66F 7B MOV A,E ;COUNT TO A 1813 C670 D1 POP D ;GET BACK BUFFER ADDRESS 1814 ; 1815 ; 1816 ; 1817 ; THIS ROUTINE GETS ONE BYTE FROM THE BUFFER 1818 ; AND RETURNS IT IN REGISTER "A". IF THE END 1819 ; OF THE BUFFER IS REACHED IT MOVES THE POINTER 1820 ; TO THE BEGINNING OF THE BUFFER FOR THE NEXT 1821 ; LOAD. 1822 ; 1823 C671 3D GTBYT: DCR A ;BUMP THE COUNT 1824 C672 77 MOV M,A ;RESTORE IT 1825 C673 23 INX H 1826 C674 7E MOV A,M ;GET BUFFER POSITION 1827 C675 34 INR M ;BUMP IT 1828 ; 1829 C676 83 ADD E 1830 C677 5F MOV E,A ;DE NOW POINT TO CORRECT BUFFER POSITION 1831 C678 D27CC6 JNC RT1 1832 C67B 14 INR D 1833 C67C 1A RT1: LDAX D ;GET CHARACTER FROM BUFFER 1834 C67D B7 ORA A ;CLEAR CARRY 1835 C67E C9 RET ;ALL DONE 1836 ; 1837 ; 1838 ; 1839 ; 1840 ; THIS ROUTINE IS USED TO WRITE A BYTE TO THE FILE 1841 ; 1842 ; ON ENTRY: A - HAS FILE NUMBER 1843 ; B - HAS DATA BYTE 1844 ; 1845 ; 1846 C67F CD2FC6 WTBYT: CALL LFCB ;GET CONTROL BLOCK 1847 C682 C8 RZ ;FILE WASN'T OPEN 1848 C683 3C INR A 1849 C684 C8 RZ ;FILE WAS READ 1850 C685 36FE MVI M,0FEH ;SET IT TO WRITE 1851 C687 23 INX H 1852 C688 23 INX H 1853 C689 78 MOV A,B ;GET CHARACTER 1854 C68A F5 PUSH PSW 1855 C68B E5 PUSH H ;SAVE CONTROL ADDRESS+2 1856 ; 18571 1858 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1859+ 19:09 05/27/2017 1860+ PAGE 33 1861 1862 1863 1864 ; NOW DO THE WRITE 1865 ; 1866 C68C CDBBC6 CALL PLOAD ;BC GETS HEADER ADDR, DE BUFFER ADDRESS 1867 C68F E1 POP H 1868 C690 7E MOV A,M ;COUNT BYTE 1869 C691 83 ADD E 1870 C692 5F MOV E,A 1871 C693 D297C6 JNC WT1 1872 C696 14 INR D 1873 C697 F1 WT1: POP PSW ;CHARACTER 1874 C698 12 STAX D ;PUT CHR IN BUFFER 1875 C699 B7 ORA A ;CLEAR FLAGS 1876 C69A 34 INR M ;INCREMENT THE COUNT 1877 C69B C0 RNZ ;RETURN IF COUNT DIDN'T ROLL OVER 1878 ; 1879 ; THE BUFFER IS FULL. WRITE IT TO TAPE AND RESET 1880 ; CONTROL BLOCK. 1881 ; 1882 C69C CDA2C6 CALL PHEAD ;PREPARE THE HEADER 1883 C69F C379C7 JMP WFBLK ;WRITE IT OUT AND RETURN 1884 ; 1885 ; 1886 ; 1887 ; 1888 ; THIS ROUTINE PUTS THE BLOCK SIZE (256) AND BUFFER 1889 ; ADDRESS IN THE FILE HEADER. 1890 ; 1891 C6A2 CDBBC6 PHEAD: CALL PLOAD ;GET HEADER AND BUFFER ADDRESSES 1892 C6A5 C5 PUSH B ;HEADER ADDRESS 1893 C6A6 210600 LXI H,BLKOF-1 ;PSTOR DOES AN INCREMENT 1894 C6A9 09 DAD B ;HL POINT TO BLOCKSIZE ENTRY 1895 C6AA 010001 LXI B,256 1896 C6AD CDB2C6 CALL PSTOR 1897 C6B0 E1 POP H ;HL RETURN WITH HEADER ADDRESS 1898 C6B1 C9 RET 1899 ; 1900 ; 1901 C6B2 23 PSTOR: INX H 1902 C6B3 71 MOV M,C 1903 C6B4 23 INX H 1904 C6B5 70 MOV M,B 1905 C6B6 23 INX H 1906 C6B7 73 MOV M,E 1907 C6B8 23 INX H 1908 C6B9 72 MOV M,D 1909 C6BA C9 RET 1910 ; 1911 ; 1912 C6BB 23 PLOAD: INX H 1913 C6BC 4E MOV C,M 1914 C6BD 23 INX H 19151 1916 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1917+ 19:09 05/27/2017 1918+ PAGE 34 1919 1920 1921 1922 C6BE 46 MOV B,M 1923 C6BF 23 INX H 1924 C6C0 5E MOV E,M 1925 C6C1 23 INX H 1926 C6C2 56 MOV D,M 1927 C6C3 C9 RET 1928 ; 1929 ; 1930 ; 1931 ; 1932 ; 1933 ; THIS ROUTINE SETS THE CORRECT UNIT FOR SYSTEM READS 1934 C6C4 CDDCC7 RFBLK: CALL GTUNT ;SET UP A=UNIT WITH SPEED 1935 ; 1936 ; 1937 ; 1938 ; 1939 ; TAPE READ ROUTINES 1940 ; 1941 ; ON-ENTRY: A HAS UNIT AND SPEED 1942 ; HL POINT TO HEADER BLOCK 1943 ; DE HAVE OPTIONAL PUT ADDRESS 1944 ; 1945 ; ON EXIT: CARRY IS SET IF ERROR OCCURED 1946 ; TAPE UNITS ARE OFF 1947 ; 1948 ; 1949 C6C7 D5 RTAPE: PUSH D ;SAVE OPTIONAL ADDRESS 1950 C6C8 0603 MVI B,3 ;SHORT DELAY 1951 C6CA CDEDC7 CALL TON 1952 C6CD DB07 IN TDATA ;CLEAR THE UART FLAGS 1953 ; 1954 C6CF E5 PTAP1: PUSH H ;HEADER ADDRESS 1955 C6D0 CD1FC7 CALL RHEAD ;GO READ HEADER 1956 C6D3 E1 POP H 1957 C6D4 DA02C7 JC TERR ;IF AN ERROR OR ESC WAS RECEIVED 1958 C6D7 C2CFC6 JNZ PTAP1 ;IF VALID HEADER NOT FOUND 1959 ; 1960 ; FOUND A VALID HEADER NOW DO COMPARE 1961 ; 1962 C6DA E5 PUSH H ;GET BACK AND RESAVE ADDRESS 1963 C6DB 111CC8 LXI D,THEAD 1964 C6DE CDD0C7 CALL DHCMP ;COMPARE DE-HL HEADERS 1965 C6E1 E1 POP H 1966 C6E2 C2CFC6 JNZ PTAP1 1967 ; 1968 ; 1969 C6E5 D1 POP D ;OPTIONAL "PUT" ADDRESS 1970 C6E6 7A MOV A,D 1971 C6E7 B3 ORA E ;SEE IF DE IS ZERO 1972 C6E8 2A23C8 LHLD BLOCK ;GET BLOCK SIZE 19731 1974 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 1975+ 19:09 05/27/2017 1976+ PAGE 35 1977 1978 1979 1980 C6EB EB XCHG ;...TO DE 1981 ; DE HAS HBLOCK....HL HAS USER OPTION 1982 C6EC C2F2C6 JNZ RTAP ;IF DE WAS ZERO GET TAPE LOAD ADDRESS 1983 C6EF 2A25C8 LHLD LOADR ;GET TAPE LOAD ADDRESS 1984 ; 1985 ; 1986 ; THIS ROUTINE READS "DE" BYTES FROM THE TAPE 1987 ; TO ADDRESS HL. THE BYTES MUST BE FROM ONE 1988 ; CONTIGUOUS PHYSICAL BLOCK ON THE TAPE. 1989 ; 1990 ; HL HAS "PUT" ADDRESS 1991 ; DE HAS SIZE OF TAPE BLOCK 1992 ; 1993 C6F2 D5 RTAP: PUSH D ;SAVE SIZE FOR RETURN TO CALLING PROGRAM 1994 ; 1995 C6F3 RTAP2 EQU $ ;HERE TO LOOP RDING BLKS 1996 C6F3 CD11C7 CALL DCRCT ;DROP COUNT, B=LEN THIS BLK 1997 C6F6 CA0CC7 JZ RTOFF ;ZERO=ALL DONE 1998 ; 1999 C6F9 CD40C7 CALL RHED1 ;READ THAT MANY BYTES 2000 C6FC DA02C7 JC TERR ;IF ERROR OR ESC 2001 C6FF CAF3C6 JZ RTAP2 ;RD OK--READ SOME MORE 2002 ; 2003 ; ERROR RETURN 2004 ; 2005 C702 AF TERR: XRA A 2006 C703 37 STC ;SET ERROR FLAGS 2007 C704 C30DC7 JMP RTOF1 2008 ; 2009 ; 2010 C707 0601 TOFF: MVI B,1 2011 C709 CDEFC7 CALL DELAY 2012 C70C AF RTOFF: XRA A 2013 C70D D306 RTOF1: OUT TAPPT 2014 C70F D1 POP D ;RETURN BYTE COUNT 2015 C710 C9 RET 2016 ; 2017 ; 2018 C711 DCRCT EQU $ ;COMMON RTN TO COUNT DOWN BLK LENGTHS 2019 C711 AF XRA A ;CLR FOR LATER TESTS 2020 C712 47 MOV B,A ;SET THIS BLK LEN=256 2021 C713 B2 ORA D ;IS AMNT LEFT < 256 2022 C714 C21CC7 JNZ DCRC2 ;NO--REDUCE AMNT BY 256 2023 C717 B3 ORA E ;IS ENTIRE COUNT ZERO 2024 C718 C8 RZ ;ALL DONE--ZERO=THIS CONDITION 2025 C719 43 MOV B,E ;SET THIS BLK LEN TO AMNT REMAINING 2026 C71A 5A MOV E,D ;MAKE ENTIRE COUNT ZERO NOW 2027 C71B C9 RET ;ALL DONE (NON-ZERO FLAG) 2028 C71C DCRC2 EQU $ ;REDUCE COUNT BY 256 2029 C71C 15 DCR D ;DROP BY 256 2030 C71D B7 ORA A ;FORCE NON-ZERO FLAG 20311 2032 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 2033+ 19:09 05/27/2017 2034+ PAGE 36 2035 2036 2037 2038 C71E C9 RET ;NON-ZERO=NOT DONE YET (BLK LEN=256) 2039 ; 2040 ; 2041 ; READ THE HEADER 2042 ; 2043 C71F 060A RHEAD: MVI B,10 ;FIND 10 NULLS 2044 C721 CD59C7 RHEA1: CALL STAT 2045 C724 D8 RC ;IF ESCAPE 2046 C725 DB07 IN TDATA ;IGNORE ERROR CONDITIONS 2047 C727 B7 ORA A ;ZERO? 2048 C728 C21FC7 JNZ RHEAD 2049 C72B 05 DCR B 2050 C72C C221C7 JNZ RHEA1 ;LOOP UNTIL 10 IN A ROW 2051 ; 2052 ; WAIT FOR THE START CHARACTER 2053 ; 2054 C72F CD6CC7 SOHL: CALL TAPIN 2055 C732 D8 RC ;ERROR OR ESCAPE 2056 C733 FE01 CPI 1 ;ARE WE AT THE 01 YET (START CHAR) 2057 C735 DA2FC7 JC SOHL ;NO, BUT STIL ZEROES 2058 C738 C21FC7 JNZ RHEAD ;NO, LOOK FOR ANOTHER 10 NULLS 2059 ; 2060 ; WE HAVE 10 (OR MORE) NULLS FOLLOWED IMMEDIATELY 2061 ; BY AN 01. NOW READ THE HEADER. 2062 ; 2063 C73B 211CC8 LXI H,THEAD ;POINT TO BUFFER 2064 C73E 0610 MVI B,HLEN ;LENGTH TO READ 2065 ; 2066 C740 RHED1 EQU $ ;RD A BLOCK INTO HL FOR B BYTES 2067 C740 0E00 MVI C,0 ;INIT THE CRC 2068 C742 RHED2 EQU $ ;LOOP HERE 2069 C742 CD6CC7 CALL TAPIN ;GET A BYTE 2070 C745 D8 RC 2071 C746 77 MOV M,A ;STORE IT 2072 C747 23 INX H ;INCREMENT ADDRESS 2073 C748 CDA6C7 CALL DOCRC ;GO COMPUTE THE CRC 2074 C74B 05 DCR B ;WHOLE HEADER YET? 2075 C74C C242C7 JNZ RHED2 ;DO ALL THE BYTES 2076 ; 2077 ; THIS ROUTINE GETS THE NEXT BYTE AND COMPARES IT 2078 ; TO THE VALUE IN REGISTER C. THE FLAGS ARE SET ON 2079 ; RETURN. 2080 ; 2081 C74F CD6CC7 CALL TAPIN ;GET CRC BYTE 2082 C752 A9 XRA C ;CLR CARRY AND SET ZERO IF MATCH, ELSE NON-ZERO 2083 C753 C8 RZ ;CRC IS FINE 2084 C754 3A11C8 LDA IGNCR ;BAD CRC, SHD WE STILL ACCEPT IT 2085 C757 3C INR A ;SEE IF IT WAS FF, IF FF THEN ZERO SAYS IGN ERR 2086 ; NOW, CRC ERR DETECTION DEPENDS ON IGNCR. 2087 C758 C9 RET 2088 ; 20891 2090 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 2091+ 19:09 05/27/2017 2092+ PAGE 37 2093 2094 2095 2096 ; THIS ROUTINE GETS THE NEXT AVAILABLE BYTE FROM THE 2097 ; TAPE. WHILE WAITING FOR THE BYTE THE KEYBOARD IS TESTED 2098 ; FOR AN ESC COMMAND. IF RECEIVED THE TAPE LOAD IS 2099 ; TERMINATED AND A RETURN TO THE COMMAND MODE IS MADE. 2100 ; 2101 C759 DB06 STAT: IN TAPPT ;TAPE STATUS PORT 2102 C75B 2F CMA ;*UM* MITS ACR USES ACTIVE LOW 2103 C75C E601 ANI TDR 2104 C75E C0 RNZ 2105 C75F CD1FC0 CALL SINP ;CHECK INPUT 2106 C762 CA59C7 JZ STAT ;NOTHING THERE YET 2107 C765 E67F ANI 7FH ;CLEAR PARITY 1ST 2108 C767 C259C7 JNZ STAT ;EITHER MODE OR CTL-@ 2109 C76A 37 STC ;SET ERROR FLAG 2110 C76B C9 RET ;AND RETURN 2111 ; 2112 ; 2113 ; 2114 C76C CD59C7 TAPIN: CALL STAT ;WAIT UNTIL A CHARACTER IS AVAILABLE 2115 C76F D8 RC 2116 ; 2117 C770 DB06 TREDY: IN TAPPT ;TAPE STATUS 2118 C772 E618 ANI TFE+TOE ;DATA ERROR? 2119 C774 DB07 IN TDATA ;GET THE DATA 2120 C776 C8 RZ ;IF NO ERRORS 2121 C777 37 STC ;SET ERROR FLAG 2122 C778 C9 RET 2123 ; 2124 ; 2125 ; THIS ROUTINE GETS THE CORRECT UNIT FOR SYSTEM WRITES 2126 C779 CDDCC7 WFBLK: CALL GTUNT ;SET UP A WITH UNIT AND SPEED 2127 ; 2128 ; 2129 ; 2130 ; WRITE TAPE BLOCK ROUTINE 2131 ; 2132 ; ON ENTRY: A HAS UNIT AND SPEED 2133 ; HL HAS POINTER TO HEADER 2134 ; 2135 ; 2136 C77C WTAPE EQU $ ;HERE TO WRITE TAPE 2137 C77C E5 PUSH H ;SAVE HEADER ADDRESS 2138 C77D CDADC7 CALL WHEAD ;TURN ON, THEN WRITE HDR 2139 C780 E1 POP H 2140 C781 110700 LXI D,BLKOF ;OFFSET TO BLOCK SIZE IN HEADER 2141 C784 19 DAD D ;HL POINT TO BLOCK SIZE 2142 C785 5E MOV E,M 2143 C786 23 INX H 2144 C787 56 MOV D,M ;DE HAVE SIZE 2145 C788 23 INX H 2146 C789 7E MOV A,M 21471 2148 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 2149+ 19:09 05/27/2017 2150+ PAGE 38 2151 2152 2153 2154 C78A 23 INX H 2155 C78B 66 MOV H,M 2156 C78C 6F MOV L,A ;HL HAVE STARTING ADDRESS 2157 ; 2158 ; THIS ROUTINE WRITES ONE PHYSICAL BLOCK ON THE 2159 ; TAPE "DE" BYTES LONG FROM ADDRESS "HL". 2160 ; 2161 ; 2162 C78D WTAP1 EQU $ ;HERE FOR THE EXTRA PUSH 2163 C78D E5 PUSH H ;A DUMMY PUSH FOR LATER EXIT 2164 C78E WTAP2 EQU $ ;LOOP HERE UNTIL ENTIRE AMOUNT READ 2165 C78E CD11C7 CALL DCRCT ;DROP COUNT IN DE AND SET UP B W/LEN THIS BLK 2166 C791 CA07C7 JZ TOFF ;RETURNS ZERO IF ALL DONE 2167 C794 CDC1C7 CALL WTBL ;WRITE BLOCK FOR BYTES IN B (256) 2168 C797 C38EC7 JMP WTAP2 ;LOOP UNTIL ALL DONE 2169 ; 2170 ; 2171 C79A F5 WRTAP: PUSH PSW 2172 C79B DB06 WRWAT: IN TAPPT ;TAPE STATUS 2173 C79D 2F CMA ;*UM* MITS ACR USES ACTIVE LOW 2174 C79E E680 ANI TTBE ;IS TAPE READY FOR A CHAR YET 2175 C7A0 CA9BC7 JZ WRWAT ;NO--WAIT 2176 C7A3 F1 POP PSW ;YES--RESTORE CHAR TO OUTPUT 2177 C7A4 D307 OUT TDATA ;SEND CHAR TO TAPE 2178 ; 2179 C7A6 DOCRC EQU $ ;A COMMON CRC COMPUTATION ROUTINE 2180 C7A6 91 SUB C 2181 C7A7 4F MOV C,A 2182 C7A8 A9 XRA C 2183 C7A9 2F CMA 2184 C7AA 91 SUB C 2185 C7AB 4F MOV C,A 2186 C7AC C9 RET ;ONE BYTE NOW WRITTEN 2187 ; 2188 ; 2189 ; THIS ROUTINE WRITES THE HEADER POINTED TO BY 2190 ; HL TO THE TAPE. 2191 ; 2192 C7AD WHEAD EQU $ ;HERE TO 1ST TURN ON THE TAPE 2193 C7AD CDEBC7 CALL WTON ;TURN IT ON, THEN WRITE HEADER 2194 C7B0 1632 MVI D,50 ;WRITE 50 ZEROS 2195 C7B2 AF NULOP: XRA A 2196 C7B3 CD9AC7 CALL WRTAP 2197 C7B6 15 DCR D 2198 C7B7 C2B2C7 JNZ NULOP 2199 ; 2200 C7BA 3E01 MVI A,1 2201 C7BC CD9AC7 CALL WRTAP 2202 C7BF 0610 MVI B,HLEN ;LENGTH TO WRITE OUT 2203 ; 2204 C7C1 0E00 WTBL: MVI C,0 ;RESET CRC BYTE 22051 2206 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 2207+ 19:09 05/27/2017 2208+ PAGE 39 2209 2210 2211 2212 C7C3 7E WLOOP: MOV A,M ;GET CHARACTER 2213 C7C4 CD9AC7 CALL WRTAP ;WRITE IT TO THE TAPE 2214 C7C7 05 DCR B 2215 C7C8 23 INX H 2216 C7C9 C2C3C7 JNZ WLOOP 2217 C7CC 79 MOV A,C ;GET CRC 2218 C7CD C39AC7 JMP WRTAP ;PUT IT ON THE TAPE AND RETURN 2219 ; 2220 ; 2221 ; THIS ROUTINE COMPARES THE HEADER IN THEAD TO 2222 ; THE USER SUPPLIED HEADER IN ADDRESS HL. 2223 ; ON RETURN IF ZERO IS SET THE TWO NAMES COMPARED 2224 ; 2225 C7D0 0605 DHCMP: MVI B,5 2226 C7D2 1A DHLOP: LDAX D 2227 C7D3 BE CMP M 2228 C7D4 C0 RNZ 2229 C7D5 05 DCR B 2230 C7D6 C8 RZ ;IF ALL FIVE COMPARED 2231 C7D7 23 INX H 2232 C7D8 13 INX D 2233 C7D9 C3D2C7 JMP DHLOP 2234 ; 2235 C7DC GTUNT EQU $ ;SET A=SPEED + UNIT 2236 C7DC 3A54C8 LDA FNUMF ;GET UNIT 2237 C7DF B7 ORA A ;SEE WHICH UNIT 2238 C7E0 3A0DC8 LDA TSPD ;BUT 1ST GET SPEED 2239 C7E3 C2E8C7 JNZ GTUN2 ;MAKE IT UNIT TWO 2240 C7E6 C640 ADI TAPE2 ;THIS ONCE=UNIT 2, TWICE=UNIT 1 2241 C7E8 C640 GTUN2: ADI TAPE2 ;UNIT AND SPEED NOW SET IN A 2242 C7EA C9 RET ;ALL DONE 2243 ; 2244 C7EB 0604 WTON: MVI B,4 ;SET LOOP DELAY (BIT LONGER ON A WRITE) 2245 C7ED TON EQU $ ;HERE TO TURN A TAPE ON THEN DELAY 2246 C7ED D306 OUT TAPPT ;GET TAPE MOVING, THEN DELAY 2247 ; 2248 C7EF 110000 DELAY: LXI D,0 2249 C7F2 1B DLOP1: DCX D 2250 C7F3 7A MOV A,D 2251 C7F4 B3 ORA E 2252 C7F5 C2F2C7 JNZ DLOP1 2253 C7F8 05 DCR B 2254 C7F9 C2EFC7 JNZ DELAY 2255 C7FC C9 RET 2256 ; 2257 ; 2258 ;**** -- END OF PROGRAM-- 2259 ; 2260 ; 2261 ; 2262 ; 22631 2264 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 2265+ 19:09 05/27/2017 2266+ PAGE 40 2267 2268 2269 2270 ; S Y S T E M E Q U A T E S 2271 ; 2272 ; 2273 ; VDM PARAMETERS 2274 ; 2275 CC00 VDMEM EQU 0CC00H ;VDM SCREEN MEMORY 2276 ; 2277 ; 2278 ; KEYBOARD SPECIAL KEY ASSIGNMENTS 2279 ; 2280 ; THESE DEFINITIONS ARE DESIGNED TO ALLOW 2281 ; COMPATABILITY WITH SOLOS(TM). THESE ARE THE 2282 ; SAME KEYS WITH BIT 7 (X'80') STRIPPED OFF. 2283 ; 2284 001A DOWN EQU 1AH ;CTL Z 2285 0017 UP EQU 17H ;CTL W 2286 0001 LEFT EQU 01H ;CTL A 2287 0013 RIGHT EQU 13H ;CTL S 2288 000B CLEAR EQU 0BH ;CTL K 2289 000E HOME EQU 0EH ;CTL N 2290 0000 MODE EQU 00H ;CTL-@ 2291 ;BACKS EQU 5FH ;BACKSPACE 2292 0008 BACKS EQU 08H ;*UM* 2293 000A LF EQU 10 2294 000D CR EQU 13 2295 0020 BLANK EQU ' ' 2296 0020 SPACE EQU BLANK 2297 0018 CX EQU 'X'-40H 2298 001B ESC EQU 1BH 2299 ; 2300 ; PORT ASSIGNMENTS 2301 ; 2302 0000 STAPT EQU 0 ;STATUS PORT GENERAL 2303 ;STKBD EQU STAPT ;PROCTEC 3P+S 2304 0004 STKBD EQU 4 ;*UM* MITS PIO 2305 0001 SDATA EQU 1 ;SERIAL DATA 2306 0012 SIO2S EQU 18 ;*UM* STATUS SIO2 B 2307 0013 SIO2D EQU 19 ;*UM* DATA SIO2 B 2308 0002 PDATA EQU 2 ;PARALLEL DATA 2309 ;KDATA EQU 3 ;KEYBOARD DATA PROCTEC 3P+S 2310 0005 KDATA EQU 5 ;*UM* KEYBOARD DATA MITS PIO 2311 00C8 DSTAT EQU 0C8H ;VDM CONTROL PORT 2312 ;TAPPT EQU 0FAH ;TAPE STATUS PORT PROCTEC SOL-20 2313 0006 TAPPT EQU 06H ;*UM* TAPE STATUS PORT MITS ACR 2314 ;TDATA EQU 0FBH ;TAPE DATA PORT PROCTEC SOL-20 2315 0007 TDATA EQU 07H ;*UM* TAPE DATA PORT MITS ACR 2316 00FF SENSE EQU 0FFH ;SENSE SWITCHES 2317 ; 2318 ; 2319 ; 2320 ; BIT ASSIGNMENT MASKS 23211 2322 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 2323+ 19:09 05/27/2017 2324+ PAGE 41 2325 2326 2327 2328 ; 2329 0001 SCD EQU 1 ;SERIAL CARRIER DETECT 2330 0002 SDSR EQU 2 ;SERIAL DATA SET READY 2331 0004 SPE EQU 4 ;SERIAL PARITY ERROR 2332 0008 SFE EQU 8 ;SERIAL FRAMING ERROR 2333 0010 SOE EQU 16 ;SERIAL OVERRUN ERROR 2334 0020 SCTS EQU 32 ;SERIAL CLEAR TO SEND 2335 ;SDR EQU 64 ;SERIAL DATA READY PROCTEC 3P+S 2336 0001 SDR EQU 1 ;*UM* SERIAL DATA READY MITS SIO 2337 0001 SDR2 EQU 1 ;*UM* SERIAL DATA READY MITS 2SIO 2338 ;STBE EQU 128 ;SERIAL TRANSMITTER BUFFER EMPTY PROCTEC 3P+S 2339 0080 STBE EQU 128 ;*UM* SERIAL TRANSMITTER BUFFER EMPTY MITS SIO 2340 0002 STBE2 EQU 2 ;*UM* SERIAL TRANSMITTER BUFFER EMPTY MITS 2SIO 2341 ; 2342 0001 KDR EQU 1 ;KEYBOARD DATA READY 2343 0002 PDR EQU 2 ;PARALLEL DATA READY 2344 0004 PXDR EQU 4 ;PARALLEL DEVICE READY 2345 ;TFE EQU 8 ;TAPE FRAMING ERROR PROCTEC CUTS 2346 0010 TFE EQU 16 ;*UM* TAPE FRAMING ERROR MITS ACR 2347 ;TOE EQU 16 ;TAPE OVERFLOW ERROR PROCTEC CUTS 2348 0008 TOE EQU 8 ;*UM* TAPE OVERFLOW ERROR MITS ACR 2349 ;TDR EQU 64 ;TAPE DATA READY PROCTEC CUTS 2350 0001 TDR EQU 1 ;*UM* TAPE DATA READY MITS ACR 2351 0080 TTBE EQU 128 ;TAPE TRANSMITTER BUFFER EMPTY 2352 ; 2353 0001 SOK EQU 1 ;SCROLL OK FLAG 2354 ; 2355 0080 TAPE1 EQU 80H ;1=TURN TAPE ONE ON 2356 0040 TAPE2 EQU 40H ;1=TURN TAPE TWO ON 2357 ; 2358 ; 2359 ; 2360 ; 2361 ; S Y S T E M G L O B A L A R E A 2362 ; 2363 C800 ORG START+0800H ;RAM STARTS JUST AFTER ROM 2364 ; 2365 C800 SYSRAM EQU $ ;START OF SYSTEM RAM 2366 CBFF SYSTP EQU SYSRAM+3FFH ;STACK WORKS FM TOP DOWN 2367 ; 2368 ; 2369 ; PARAMETERS STORED IN RAM 2370 ; 2371 C800 UIPRT: DS 2 ;USER DEFINED INPUT RTN IF NON ZERO 2372 C802 UOPRT: DS 2 ;USER DEFINED OUTPUT RTN IF NON ZERO 2373 C804 DFLTS: DS 2 ;DEFAULT PSUEDO I/O PORTS 2374 C806 IPORT: DS 1 ;CRNT INPUT PSUEDO PORT 2375 C807 OPORT: DS 1 ;CRNT OUTPUT PSUEDO PORT 2376 C808 NCHAR: DS 1 ;CURRENT CHARACTER POSITION 2377 C809 LINE: DS 1 ;CURRENT LINE POSITION 2378 C80A BOT: DS 1 ;BEGINNING OF TEXT DISPLACEMENT 23791 2380 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 2381+ 19:09 05/27/2017 2382+ PAGE 42 2383 2384 2385 2386 C80B SPEED: DS 1 ;SPEED CONTROL BYTE 2387 C80C ESCFL: DS 1 ;ESCAPE FLAG CONTROL BYTE 2388 C80D TSPD: DS 1 ;CURRENT TAPE SPEED 2389 C80E INPTR: DS 2 ;PTR TO NEXT CHAR POSITION IN INLIN 2390 C810 NUCNT: DS 1 ;NUMBER OF NULLS AFTER CRLF 2391 C811 IGNCR: DS 1 ;IGN CRC ERR FLAG, FF=IGN CRC ERRS, ELSE=NORMAL 2392 ; 2393 C812 DS 10 ;ROOM FOR FUTURE EXPANSION 2394 ; 2395 ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2396 ; T H I S I S T H E H E A D E R L A Y O U T * 2397 ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2398 ; 2399 C81C THEAD: DS 5 ;NAME 2400 C821 DS 1 ;THIS BYTE MUST BE ZERO 2401 C822 HTYPE: DS 1 ;TYPE 2402 C823 BLOCK: DS 2 ;BLOCK SIZE 2403 C825 LOADR: DS 2 ;LOAD ADDRESS 2404 C827 XEQAD: DS 2 ;AUTO EXECUTE ADDRESS 2405 C829 HSPR: DS 3 ;SPARES 2406 ; 2407 0010 HLEN EQU $-THEAD ;LENGTH OF HEADER 2408 0007 BLKOF EQU BLOCK-THEAD ;OFFSET TO BLOCK SIZE 2409 C82C DHEAD: DS HLEN ;A DUMMY HDR FOR COMPARES WHILE RD'ING 2410 ; 2411 ; 2412 C83C CUTAB: DS 6*4 ;ROOM FOR UP TO 6 CUSTOM USER COMMANDS 2413 ; 2414 ; 2415 C854 FNUMF: DS 1 ;FOR CURRENT FILE OPERATIONS 2416 C855 FCBAS: DS 7 ;1ST FILE CONTROL BLOCK 2417 C85C FCBA2: DS 7 ;2ND FILE CONTROL BLOCK 2418 C863 FBUF1: DS 2*256 ;SYSTEM FILE BUFFER BASE 2419 CA63 DS 1 ;"BELL" (X'07') FLAGS START OF INPUT BFR 2420 CA64 INLIN: DS 80 ;ROOM FOR THE INPUT LINE 2421 CAB4 USARE EQU $ ;START OF USER AREA 2422 ; 2423 ; REMEMBER THAT THE STACK WORKS ITS WAY DOWN-FROM 2424 ; THE END OF THIS 1K RAM AREA. 2425 ; 2426 ; -*- 2427 END 2428 NO PROGRAM ERRORS 24291 2430 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 2431+ 19:09 05/27/2017 2432+ PAGE 43 2433 2434 2435 2436 SYMBOL TABLE 2437 2438 * 01 2439 2440 A 0007 ADOUT C3D9 AINP C022 * ALOAD C544 2441 AOUT C01C * ARET C1C3 * ARET1 C1C5 ARET2 C1CA 2442 B 0000 BACKS 0008 BLANK 0020 BLKOF 0007 2443 BLOCK C823 BOPEN C5DC BOT C80A BOUT C3F7 2444 C 0001 CHAR C0B8 CHRLI C56D CLEAR 000B 2445 CLERA C1DC CLIN1 C123 CLIN2 C118 CLINE C11D * 2446 COMN1 C215 COMND C218 COMTA C2BD CONT C264 * 2447 COPRC C26A CR 000D CREM C15F CRLF C342 2448 CSET C576 CUR C0F5 CURET C1CE CURSC C0F3 2449 CUSE2 C5CF CUSET C5B9 CUTAB C83C CX 0018 * 2450 D 0002 DCRC2 C71C DCRCT C711 DEFLT C494 2451 DELAY C7EF DFLTS C804 DHCMP C7D0 DHEAD C82C 2452 DHLOP C7D2 DISP0 C282 DISP1 C28B DISPD C595 2453 DISPT C287 DLOOP C3B6 DLOP1 C7F2 DLP1 C3C1 2454 DLP1A C3D0 DOCRC C7A6 DOWN 001A DSTAT 00C8 2455 DUMP C3AD E 0003 ENLO1 C427 ENLO3 C444 2456 ENLOP C418 ENTER C414 EOFER C5FB EOFW C627 2457 ERAS1 C0FF ERAS3 C112 ERR1 C46B ERR2 C46C 2458 ERRIT C065 ERRM C521 ERRO1 C070 ERROT C06C 2459 ESC 001B ESCFL C80C ESCS C187 ESCSP C190 2460 EXEC C449 EXEC1 C44C FBUF1 C863 FCBA2 C85C 2461 FCBAS C855 FCLOS C00A * FDCOM C291 FDCOU C28E 2462 FNUMF C854 FOPEN C007 * GCLI0 C227 GCLI1 C232 2463 GCLI2 C25F GCLI3 C261 GCLIN C239 GOBAC C08F 2464 GOBK C0A0 GTBYT C671 GTUN2 C7E8 GTUNT C7DC 2465 H 0004 HBOUT C3DE HCONV C38B * HCOV1 C39B 2466 HEOU1 C405 HEOUT C3FC HLEN 0010 HOME 000E 2467 HSPR C829 * HTYPE C822 IGNCR C811 INIT C001 * 2468 INLIN CA64 INPTR C80E IOPRC C026 IPORT C806 2469 ITAB C309 KDATA 0005 KDR 0001 KREA1 C035 2470 L 0005 LEFT 0001 LF 000A LFCB C62F 2471 LFCB1 C63E LINE C809 LIST1 C535 LLIST C52D 2472 LOADR C825 M 0006 MODE 0000 * NAME C454 2473 NAME0 C451 NAME1 C459 NAOUT C54C NCHAR C808 2474 NCOM C2A3 NEXT C0A4 NFIL C480 NLOOP C566 2475 NUCNT C810 NULOP C7B2 NULOT C350 OCHAR C0BC 2476 OK C0E5 OPORT C807 OTAB C301 OUTH C410 2477 OUTPR C02E PARIT C052 PAROT C05A PBACK C167 2478 PCLOS C5FF PCR C170 PCUR C138 PDATA 0002 * 2479 PDOWN C0EF PDR 0002 * PERSE C0F9 PESC C181 2480 PHEAD C6A2 PHOME C109 PLEFT C134 PLF C175 2481 PLOAD C6BB PRIT C13E PROMP C33A PSCAN C3A5 2482 PSTOR C6B2 PSW 0006 PTAP1 C6CF PUP C12D 2483 PXDR 0004 * RDBLK C013 * RDBYT C00D * RDNBL C658 * 2484 RETRN C004 * RFBLK C6C4 RHEA1 C721 RHEAD C71F 2485 RHED1 C740 RHED2 C742 RIGHT 0013 RT1 C67C 2486 RTAP C6F2 RTAP2 C6F3 RTAPE C6C7 RTBYT C642 24871 2488 8080 MACRO ASSEMBLER, VER 3.0 ERRORS = 0 2489+ 19:09 05/27/2017 2490+ PAGE 44 2491 SYMBOL TABLE 2492 2493 2494 RTOF1 C70D RTOFF C70C SBLK C359 SBLK1 C35B 2495 SCD 0001 * SCHR C36C SCHR1 C36E SCONV C378 2496 SCROL C0D0 * SCTS 0020 * SDATA 0001 SDR 0001 2497 SDR2 0001 SDSR 0002 * SECON C1B8 SENSE 00FF 2498 SEROT C047 SETAB C311 SETCI C5A1 SETCO C5A5 2499 SETCR C5B5 SETIN C599 SETNU C5B1 SETOT C59D 2500 SETSP C590 SETTY C5A9 SETX C1B0 SETXQ C5AD 2501 SETY C1B4 SFE 0008 * SHE1 C381 SHEX C37E 2502 SINP C01F SIO2D 0013 SIO2S 0012 SOE 0010 * 2503 SOHL C72F SOK 0001 * SOUT C019 SP 0006 2504 SPACE 0020 SPE 0004 * SPEED C80B SREA1 C03E 2505 SROL C0D4 STAPT 0000 START C000 STAT C759 2506 STBE 0080 STBE2 0002 STKBD 0004 STRTA C1D7 2507 STRTB C1F4 STRTC C1FF STRTD C20F STSPD C594 2508 STUNT C49C STUP C2AA SYSRA C800 SYSTP CBFF 2509 TAERR C510 TAPE1 0080 TAPE2 0040 TAPIN C76C 2510 TAPPT 0006 TASPD C58A TBL C2E2 TDATA 0007 2511 TDR 0001 TERE0 C5F8 TERE1 C5F7 * TERE2 C5F6 2512 TERR C702 TFE 0010 THEAD C81C TIMER C09B 2513 TLIST C527 TLOA2 C4AF * TLOA3 C4BB TLOAD C4A1 2514 TOE 0008 TOFF C707 TON C7ED TREDY C770 * 2515 TSAVE C4E0 TSPD C80D TSRCH C0A6 TTBE 0080 2516 TXEQ C4A0 UBUF C5F1 * UIPRT C800 UOPRT C802 2517 UP 0017 USARE CAB4 * VDAD C14C VDAD2 C149 2518 VDADD C145 VDM01 C078 VDMEM CC00 WFBLK C779 2519 WHEAD C7AD WLOOP C7C3 WRBLK C016 * WRBYT C010 * 2520 WRTAP C79A WRWAT C79B WT1 C697 WTAP1 C78D 2521 WTAP2 C78E WTAPE C77C WTBL C7C1 WTBYT C67F 2522 WTLP1 C3F1 WTON C7EB XEQAD C827 2523 2524