CP/M RMAC ASSEM 1.1 #001 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 1 title 'SAVE.RSX - CP/M 3.0 save routine. July 1982' 2 ; ************************************************* 3 ; * 4 ; * Title: SAVE.RSX Resident System eXtension 5 ; * Date: 7/28/82 6 ; * Author: Thomas J. Mason 7 ; * 8 ; * Modified: 9 ; * 11/30/82 - Thomas J. Mason 10 ; * Added trap for function 60 to fix PUT and SAVE 11 ; * bios vector mods. 12 ; * 13 ; ********************************************************* 14 ; 15 ; Copyright (c) 1982 16 ; Digital Research 17 ; PO Box 579 18 ; Pacific Grove, Ca. 93950 19 ; 20 FFFF = TRUE equ 0FFFFh 21 0000 = FALSE equ not TRUE 22 ; 23 FFFF = PATCH18 equ true ;to lengthen console buffer 18 Oct 97 rhp 24 ; 25 ; BIOS and BDOS Jump vectors 26 ; 27 0000 = WBOOT equ 0 28 0001 = WBTADR equ 1 ;address of boot in BIOS 29 0005 = BDOS equ 5 ;BDOS jump vector 30 0006 = BDOSAD equ 6 ;location of instructions 31 005C = DFCB equ 05Ch ;default FCB 32 ; 33 ; BDOS Function calls 34 ; 35 0006 = BDOSAD equ 6 ;BDOS jump address 36 0009 = PSTRING equ 9 ;print string 37 000A = BUFIN equ 10 ;console buffer input 38 0010 = CFILE equ 16 ;file close 39 0013 = DFILE equ 19 ;file delete 40 0015 = WFILE equ 21 ;file write 41 0016 = MFILE equ 22 ;make file 42 001A = SETDMA equ 26 ;set DMA function 43 002D = BDOSER equ 45 ;Set BDOS error mode 44 0031 = GETSCB equ 49 ;get/set scb func # 45 003B = LDRSX equ 59 ;function for RSX load 46 003C = CALRSX equ 60 ;call rsx func # 47 006D = CONMOD equ 109 ;GET/SET Console Mode 48 ; 49 ; Non Printable ASCII characters 50 ; 51 0003 = CTL$C equ 03 ;CONTROL-C 52 000D = CR equ 13 ;ASCII Carrige Return 53 000A = LF equ 10 ;ASCII Line Feed 54 ; 55 001E = VERSION equ 30 56 ; CP/M RMAC ASSEM 1.1 #002 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 57 ; Buffer size 58 ; 59 if PATCH18 60 000E = CONMAX equ 14 ;console buffer maximum 61 else 62 CONMAX equ 13 ;console buffer maximum 63 endif 64 ; 65 0010 = STKSZE equ 010h ;size of stack 66 0068 = SCBOST equ 068h ;page boundary + to jmp instr 67 00FE = RETDSP equ 0FEh ;RETurn and DiSPlay mode 68 00C3 = JUMP equ 0C3h ;opcode for jump 69 0021 = LXIH equ 21h ;lxi instr to poke 70 007F = BSNLY equ 07Fh ;restore bios jump table only 71 00F9 = CMMON equ 0F9h ;offset of common memory base from pg. bound 72 ; 73 ; ********************************* 74 ; * * 75 ; * The Save Program * 76 ; * * 77 ; ********************************* 78 ; 79 0000 0000000000 db 0,0,0,0,0,0 80 0006 C31B00 jmp PREFIX 81 NEXTJ: 82 0009 C3 db JUMP ;jump 83 NEXT: 84 000A 0000 db 0,0 ;next module in line 85 PREV: 86 000C 0500 dw 5 ;previous, initialized to 5 87 000E 00 STKYBT: db 00h ;for warm start 88 000F 00 db 0 89 0010 5341564520 db 'SAVE ' 90 0018 ds 3 91 ; 92 ; 93 ; This is the check performed every time the BDOS is 94 ; called to see if the RSX is to be invoked 95 ; 96 PREFIX: 97 001B 79 mov a,c ;set up for compare 98 001C FE3C cpi CALRSX 99 001E C23100 jnz GETGOING 100 101 0021 C5 push b 102 0022 D5 push d 103 0023 E5 push h 104 0024 210000 lxi h,0000h ;zero out HL 105 0027 19 dad d ; -> RSXPB 106 0028 7E mov a,m ;get the byte 107 0029 FEA0 cpi 160 ; sub function defined 108 109 002B E1 pop h 110 002C D1 pop d 111 002D C1 pop b 112 002E CA8B01 jz GOODBYE ;remove this RSX CP/M RMAC ASSEM 1.1 #003 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 113 114 GETGOING: 115 ; 116 0031 FE3B cpi LDRSX ;do the compare 117 0033 CA3A00 jz START 118 0036 2A0A00 lhld NEXT ;get address for continue 119 0039 E9 pchl ;get going..... 120 ; 121 ; 122 ; 123 START: 124 ; 125 ; They are equal so get the BIOS address to point here 126 ; in case of a Func 0 call 127 ; 128 003A C5 push b ;save state 129 003B D5 push d ; of registers 130 ; 131 ; check for jump byte before the SCB 132 003C CDA901 call GETSET$SCB 133 003F 22C203 shld SCBADR ;save address for later 134 ; 135 0042 2EFA mvi l,CMMON+1 ;offset into scb to check BIOS 136 0044 7E mov a,m ;get byte 137 0045 B7 ora a ;check for zero 138 0046 3E00 mvi a,FALSE ;store for insurance 139 0048 32C103 sta CHGJMP ;non-banked = FALSE 140 004B CA6000 jz NBNKED ;high byte zero if non-banked 141 ; 142 004E 2AC203 lhld SCBADR ;restor SCB 143 0051 2E68 mvi l,SCBOST ;offset from page for instr 144 0053 7E mov a,m ;get byte 145 0054 FEC3 cpi JUMP ;is it a jump? 146 0056 C26000 jnz MORRSX ;we are not alone 147 0059 3EFF mvi a,TRUE 148 005B 32C103 sta CHGJMP ;set flag 149 005E 3621 mvi m,LXIH ;put in lxi h,xxxx mnemonic 150 ; 151 MORRSX: 152 ; continue with processing 153 NBNKED: 154 ; 155 ; 156 0060 2A0100 lhld WBTADR ;get address at 01h 157 0063 23 inx h ;now points to address of jmp xxxx 158 0064 7E mov a,m ;get low order byte 159 0065 32BA03 sta BIOSAD 160 0068 23 inx h ;next byte 161 0069 7E mov a,m 162 006A 32BB03 sta BIOSAD+1 ;high order byte 163 ; 164 ; Now poke the BIOS address to point to 165 ; the save routine. 166 ; 167 006D 118000 lxi d,BEGIN ;begining of routine 168 0070 72 mov m,d CP/M RMAC ASSEM 1.1 #004 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 169 0071 2B dcx h ;point back to first byte 170 0072 73 mov m,e ;low order 171 ; 172 0073 0E2D mvi c,BDOSER ;now set BDOS errormode 173 0075 1EFE mvi e,RETDSP ;to trap any hard 174 0077 CD0500 call BDOS ;errors 175 ; 176 ; 177 007A D1 pop d 178 007B C1 pop b 179 007C 2A0A00 lhld NEXT 180 007F E9 pchl ;continue on 181 ; 182 BEGIN: 183 ; Start of the save routine 184 ; Notify the user which program is running 185 ; 186 0080 31AE04 lxi sp,STACK ;initialize stack 187 0083 11D503 lxi d,SIGNON ;prompt 188 0086 CDE901 call PSTR 189 ; 190 ; Get the file from the user 191 ; 192 FLEGET: 193 0089 11F103 lxi d,FLEPRMPT ;ask for file name 194 008C CDE901 call PSTR 195 008F CDDA01 call GETBUF 196 ; zero at end of string for parser 197 0092 21C603 lxi h,CONBUF-1 ;address of # 198 0095 7E mov a,m ;get it 199 0096 FE00 cpi 0 200 0098 CA8001 jz REPLCE 201 009B 23 inx h ;HL->CONBUF 202 009C 1600 mvi d,0 ;zero out high order 203 009E 5F mov e,a ;fill low 204 009F 19 dad d ;add to h 205 00A0 3600 mvi m,00 ;zero out byte for parse 206 00A2 E5 push h 207 ; 208 ; 209 00A3 CDEF01 call PARSE 210 00A6 7C mov a,h 211 00A7 FEFF cpi 0FFh 212 00A9 CA8900 jz FLEGET 213 ; 214 00AC E1 pop h ;get end of string address back 215 00AD 23 inx h 216 00AE 363F mvi m,'?' ;put in question mark 217 00B0 23 inx h ;bump 218 00B1 3620 mvi m,' ' ;blank in string 219 00B3 23 inx h ;bump 220 00B4 3624 mvi m,'$' ;end of string 221 ; 222 00B6 0E11 mvi c,17 ;Search for first 223 00B8 115C00 lxi d,DFCB 224 00BB CD0500 call BDOS ;find it CP/M RMAC ASSEM 1.1 #005 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 225 00BE 3C inr a ;bump Acc 226 00BF CAD900 jz FLECLR ;file no present skip prompt 227 ; 228 00C2 111604 lxi d,DELFLE 229 00C5 CDE901 call PSTR ;print out delete prompt 230 00C8 11C703 lxi d,CONBUF ;buffer address 231 00CB CDE901 call PSTR ;print out filename 232 00CE CDDA01 call GETBUF ;get answer 233 00D1 CD3803 call GNC ;get the next char 234 00D4 FE59 cpi 'Y' ;is it yes 235 00D6 C28900 jnz FLEGET ;another name if not 236 ; 237 ; Delete any existing file, then make a new one 238 FLECLR: 239 00D9 0E13 mvi c,DFILE ;file delete func 240 00DB 115C00 lxi d,DFCB ;default FCB 241 00DE CD0500 call BDOS ;real BDOS call 242 ; 243 00E1 3E00 mvi a,0 244 00E3 217C00 lxi h,07ch ;M -> record count in FCB 245 00E6 77 mov m,a ;zero out record count 246 ; 247 00E7 0E16 mvi c,MFILE ;make file function 248 00E9 115C00 lxi d,DFCB ;default FCB 249 00EC CD0500 call BDOS 250 ; Get the address of start of write 251 ; 252 STRADD: 253 00EF 112004 lxi d,SPRMPT ;first address 254 00F2 CDE901 call PSTR 255 00F5 CDDA01 call GETBUF 256 ; 257 00F8 3AC603 lda BUFFER+1 ;get # of chars read 258 00FB FE00 cpi 0 259 00FD CAEF00 jz STRADD 260 ; 261 0100 CD5603 call SCANAD ;get address 262 0103 DAEF00 jc STRADD 263 ; 264 0106 22B603 shld SADDR ;store in SADDR 265 ; 266 ; Get the finish address 267 ENDADD: 268 0109 113904 lxi d,FPRMPT ;load prompt 269 010C CDE901 call PSTR ;print 270 010F CDDA01 call GETBUF ;read in 271 ; 272 0112 3AC603 lda BUFFER+1 273 0115 FE00 cpi 0 274 0117 CA0901 jz ENDADD 275 ; 276 011A CD5603 call SCANAD ;get finish address 277 011D DA0901 jc ENDADD 278 ; 279 0120 22B803 shld FADDR ;store it 280 0123 EB xchg CP/M RMAC ASSEM 1.1 #006 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 281 0124 2AB603 lhld SADDR 282 0127 EB xchg 283 ; 284 0128 CDCF01 call CHECK 285 012B DAEF00 jc STRADD 286 ; 287 ; 288 012E 2AB603 lhld SADDR ;beginning DMA address 289 0131 EB xchg ;DE=DMA address 290 ; 291 ; Write the first record then check the beginning address 292 ; if DMA address ends up larger exit 293 ; 294 WLOOP: 295 0132 CDB201 call WFLAG 296 0135 D5 push d ;save DMA address 297 0136 0E1A mvi c,SETDMA 298 0138 CD0500 call BDOS ;set DMA address 299 ; 300 013B 0E15 mvi c,WFILE 301 013D 115C00 lxi d,DFCB 302 0140 CD0500 call BDOS ;write 303 ; 304 ; Check for directory space on disk for extents 305 0143 116904 lxi d,NODIR 306 0146 FE01 cpi 01h ;no more directory 307 0148 CA7D01 jz FINIS 308 ; 309 ; CHECK data block error 310 014B 118604 lxi d,NOBLK 311 014E FE02 cpi 02h 312 0150 CA7D01 jz FINIS ;out of disk space! 313 ; final check 314 0153 B7 ora a ;if bad write occured... 315 0154 C28001 jnz REPLCE ;restore BIOS address 316 ; 317 ; Write OK now check write address 318 0157 D1 pop d ;get DMA address 319 0158 218000 lxi h,080h 320 015B 19 dad d 321 015C EB xchg 322 015D 2AB803 lhld FADDR ;HL=end of write 323 ; 324 0160 CDCF01 call CHECK 325 ; 326 0163 3ABE03 lda ONEFLG 327 0166 FEFF cpi TRUE 328 0168 C23201 jnz WLOOP ;WLOOP if not done 329 ; 330 ; Else, Close file and print out ending prompt 331 CLOSE: 332 016B 0E10 mvi c,CFILE ;close function 333 016D 115C00 lxi d,DFCB ;get filename 334 0170 CD0500 call BDOS 335 ; 336 0173 3C inr a ;check for close error CP/M RMAC ASSEM 1.1 #007 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 337 0174 115504 lxi d,CERROR 338 0177 CA7D01 jz FINIS ;maybe write protected 339 ; 340 ;good copy 341 017A 115204 lxi d,ENDMSG 342 FINIS: 343 017D CDE901 call PSTR 344 ; 345 ; Replace the BIOS Address to correct one 346 REPLCE: 347 0180 2ABA03 lhld BIOSAD ;HL=BIOS warm jump 348 0183 EB xchg ;DE=" " " 349 0184 2A0100 lhld WBTADR 350 0187 23 inx h 351 0188 73 mov m,e 352 0189 23 inx h 353 018A 72 mov m,d 354 ; 355 GOODBYE: 356 018B 3EFF mvi a,0FFh 357 018D 320E00 sta STKYBT ;change sticky byte for 358 ; ; removal of RSX 359 ; 360 ; check to see if JMP changed for BANKED system 361 0190 3AC103 lda CHGJMP 362 0193 FEFF cpi TRUE ;has it been done? 363 0195 C29F01 jnz CHGBIOS 364 0198 2AC203 lhld SCBADR ;retreive SCB address 365 019B 2E68 mvi l,SCBOST ;points to page + offset 366 019D 36C3 mvi m,JUMP ;restore original code 367 ; 368 CHGBIOS: 369 019F 0E0D mvi c,13 ;reset the disk system 370 01A1 CD0500 call BDOS 371 ; 372 01A4 0E00 mvi c,0 ;set up for wboot 373 01A6 CD0500 call BDOS 374 ;**************************************** 375 ;* * 376 ;* Logical end of the program * 377 ;* * 378 ;**************************************** 379 ; 380 GETSET$SCB: 381 01A9 0E31 mvi c,GETSCB 382 01AB 11B403 lxi d,SCBPB 383 01AE CD0500 call BDOS 384 01B1 C9 ret 385 ; 386 WFLAG: 387 01B2 3E00 mvi a,FALSE 388 01B4 32BE03 sta ONEFLG 389 01B7 3AC003 lda RSLT+1 390 01BA FE00 cpi 00h 391 01BC C0 rnz 392 01BD 3ABF03 lda RSLT CP/M RMAC ASSEM 1.1 #008 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 393 01C0 FE80 cpi 080h 394 01C2 DAC901 jc WFLAG1 395 01C5 CAC901 jz WFLAG1 396 01C8 C9 ret 397 ; 398 WFLAG1: 399 01C9 3EFF mvi a,TRUE 400 01CB 32BE03 sta ONEFLG 401 01CE C9 ret 402 ; 403 ; 404 ; 405 CHECK: 406 ; Subtract the two to find out if finished 407 01CF 7D mov a,l ;low order 408 01D0 93 sub e ;subtraction 409 01D1 32BF03 sta RSLT 410 01D4 7C mov a,h ;now ... 411 01D5 9A sbb d ;high order subtraction 412 01D6 32C003 sta RSLT+1 ;saved 413 01D9 C9 ret 414 ; 415 GETBUF: 416 ;buffer input routine 417 ; 418 01DA 21C703 lxi h,CONBUF ;address of buffer 419 01DD 22BC03 shld NEXTCOM ;store it 420 01E0 0E0A mvi c,BUFIN 421 01E2 11C503 lxi d,BUFFER 422 01E5 CD0500 call BDOS 423 01E8 C9 ret 424 ; 425 PSTR: 426 ; String output routine for messages 427 ; 428 01E9 0E09 mvi c,PSTRING 429 01EB CD0500 call BDOS 430 01EE C9 ret 431 ; 432 PARSE: 433 ; General purpose parser 434 ; 435 ; Filename = [d:]file[.type][;password] 436 ; 437 ; FCB assignments 438 ; 439 ; 0 => drive, 0=default, 1=A, 2=B 440 ; 1-8 => file, converted to upper case, 441 ; padded with blanks 442 ; 9-11 => type, converted to upper case, 443 ; padded with blanks 444 ; 12-15 => set to zero 445 ; 16-23 => passwords, converted to upper case, 446 ; padded with blanks 447 ; 24-25 => address of password field in "filename", 448 ; set to zero if password length=0. CP/M RMAC ASSEM 1.1 #009 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 449 ; 26 => length of password (0-8) 450 ; 451 ; Upon return, HL is set to FFFFh if BC locates 452 ; an invalid file name; 453 ; otherwise, HL is set to 0000h if the delimiter 454 ; following the file name is a 00h (null) 455 ; or a 0Dh (CR); 456 ; otherwise, HL is set to the address of the delimiter 457 ; following the file name. 458 ; 459 ; 460 01EF 210000 lxi h,0 461 01F2 E5 push h 462 01F3 E5 push h 463 01F4 11C703 lxi d,CONBUF ;set up source address 464 01F7 215C00 lxi h,DFCB ;set up dest address 465 01FA CD2803 call DEBLNK ;scan the blanks 466 01FD CDE602 call DELIM ;check for delimeter 467 0200 C20C02 jnz PARSE1 468 0203 79 mov a,c 469 0204 B7 ora a 470 0205 C28E02 jnz PARSE9 471 0208 77 mov m,a 472 0209 C33D02 jmp PARSE3 473 ; 474 PARSE1: 475 020C 47 mov b,a 476 020D 13 inx d 477 020E 1A ldax d 478 020F FE3A cpi ':' 479 0211 C23A02 jnz PARSE2 480 ; 481 0214 78 mov a,b 482 0215 D641 sui 'A' 483 0217 DA8E02 jc PARSE9 484 021A FE10 cpi 16 485 021C D28E02 jnc PARSE9 486 021F 3C inr a 487 0220 77 mov m,a 488 0221 13 inx d 489 0222 CDE602 call DELIM 490 0225 C23D02 jnz PARSE3 491 0228 FE2E cpi '.' 492 022A CA8E02 jz PARSE9 493 022D FE3A cpi ':' 494 022F CA8E02 jz PARSE9 495 0232 FE3B cpi ';' 496 0234 CA8E02 jz PARSE9 497 0237 C33D02 jmp PARSE3 498 ; 499 PARSE2: 500 023A 1B dcx d 501 023B 3600 mvi m,0 502 PARSE3: 503 023D 0608 mvi b,8 504 023F CD9402 call SETFLD CP/M RMAC ASSEM 1.1 #010 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 505 0242 0603 mvi b,3 506 0244 FE2E cpi '.' 507 0246 CA4F02 jz PARSE4 508 0249 CDDE02 call PADFLD 509 024C C35302 jmp PARSE5 510 ; 511 PARSE4: 512 024F 13 inx d 513 0250 CD9402 call SETFLD 514 PARSE5: 515 0253 0604 mvi b,4 516 PARSE6: 517 0255 23 inx h 518 0256 3600 mvi m,0 519 0258 05 dcr b 520 0259 C25502 jnz PARSE6 521 025C 0608 mvi b,8 522 025E FE3B cpi ';' 523 0260 CA6902 jz PARSE7 524 0263 CDDE02 call PADFLD 525 0266 C36D02 jmp PARSE8 526 PARSE7: 527 0269 13 inx d 528 026A CDB702 call PWFLD 529 PARSE8: 530 026D D5 push d 531 026E CD2803 call DEBLNK 532 0271 CDE602 call DELIM 533 0274 C27C02 jnz PARSE81 534 0277 33 inx sp 535 0278 33 inx sp 536 0279 C37D02 jmp PARSE82 537 PARSE81: 538 027C D1 pop d 539 PARSE82: 540 027D 79 mov a,c 541 027E B7 ora a 542 027F C1 pop b 543 0280 79 mov a,c 544 0281 C1 pop b 545 0282 23 inx h 546 0283 71 mov m,c 547 0284 23 inx h 548 0285 70 mov m,b 549 0286 23 inx h 550 0287 77 mov m,a 551 0288 EB xchg 552 0289 C0 rnz 553 028A 210000 lxi h,0 554 028D C9 ret 555 PARSE9: 556 028E E1 pop h 557 028F E1 pop h 558 0290 21FFFF lxi h,0FFFFh 559 0293 C9 ret 560 ; CP/M RMAC ASSEM 1.1 #011 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 561 SETFLD: 562 0294 CDE602 call DELIM 563 0297 CADE02 jz PADFLD 564 029A 23 inx h 565 029B FE2A cpi '*' 566 029D C2A902 jnz SETFD1 567 02A0 363F mvi m,'?' 568 02A2 05 dcr b 569 02A3 C29402 jnz SETFLD 570 02A6 C3AB02 jmp SETFD2 571 SETFD1: 572 02A9 77 mov m,a 573 02AA 05 dcr b 574 SETFD2: 575 02AB 13 inx d 576 02AC C29402 jnz SETFLD 577 SETFD3: 578 02AF CDE602 call DELIM 579 02B2 C8 rz 580 02B3 E1 pop h 581 02B4 C38E02 jmp PARSE9 582 ; 583 PWFLD: 584 02B7 CDE602 call DELIM 585 02BA CADE02 jz PADFLD 586 02BD 33 inx sp 587 02BE 33 inx sp 588 02BF 33 inx sp 589 02C0 33 inx sp 590 02C1 33 inx sp 591 02C2 33 inx sp 592 02C3 D5 push d 593 02C4 E5 push h 594 02C5 2E00 mvi l,0 595 02C7 E3 xthl 596 02C8 3B dcx sp 597 02C9 3B dcx sp 598 PWFLD1: 599 02CA 33 inx sp 600 02CB 33 inx sp 601 02CC E3 xthl 602 02CD 2C inr l 603 02CE E3 xthl 604 02CF 3B dcx sp 605 02D0 3B dcx sp 606 02D1 23 inx h 607 02D2 77 mov m,a 608 02D3 13 inx d 609 02D4 05 dcr b 610 02D5 CAAF02 jz SETFD3 611 02D8 CDE602 call DELIM 612 02DB C2CA02 jnz PWFLD1 613 ; 614 PADFLD: 615 02DE 23 inx h 616 02DF 3620 mvi m,' ' CP/M RMAC ASSEM 1.1 #012 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 617 02E1 05 dcr b 618 02E2 C2DE02 jnz PADFLD 619 02E5 C9 ret 620 ; 621 DELIM: 622 02E6 1A ldax d 623 02E7 4F mov c,a 624 02E8 B7 ora a 625 02E9 C8 rz 626 02EA 0E00 mvi c,0 627 02EC FE0D cpi 0Dh 628 02EE C8 rz 629 02EF 4F mov c,a 630 02F0 FE09 cpi 09h 631 02F2 C8 rz 632 02F3 FE20 cpi ' ' 633 02F5 DA2403 jc DELIM2 634 02F8 C8 rz 635 02F9 FE2E cpi '.' 636 02FB C8 rz 637 02FC FE3A cpi ':' 638 02FE C8 rz 639 02FF FE3B cpi ';' 640 0301 C8 rz 641 0302 FE3D cpi '=' 642 0304 C8 rz 643 0305 FE2C cpi ',' 644 0307 C8 rz 645 0308 FE2F cpi '/' 646 030A C8 rz 647 030B FE5B cpi '[' 648 030D C8 rz 649 030E FE5D cpi ']' 650 0310 C8 rz 651 0311 FE3C cpi '<' 652 0313 C8 rz 653 0314 FE3E cpi '>' 654 0316 C8 rz 655 0317 FE61 cpi 'a' 656 0319 D8 rc 657 031A FE7B cpi 'z'+1 658 031C D22103 jnc DELIM1 659 031F E65F ani 05Fh 660 DELIM1: 661 0321 E67F ani 07Fh 662 0323 C9 ret 663 DELIM2: 664 0324 E1 pop h 665 0325 C38E02 jmp PARSE9 666 ; 667 DEBLNK: 668 0328 1A ldax d 669 0329 FE20 cpi ' ' 670 032B CA3403 jz DBLNK1 671 032E FE09 cpi 09h 672 0330 CA3403 jz DBLNK1 CP/M RMAC ASSEM 1.1 #013 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 673 0333 C9 ret 674 DBLNK1: 675 0334 13 inx d 676 0335 C32803 jmp DEBLNK 677 ; End of the Parser 678 ; 679 ; GET a character from the console buffer 680 GNC: 681 0338 E5 push h 682 0339 21C603 lxi h,CONBUF-1 ;get length 683 033C 7E mov a,m 684 033D B7 ora a ;zero? 685 033E 3E0D mvi a,CR ;return with CR if so 686 0340 CA4C03 jz GNCRET 687 0343 35 dcr m ;lenght = length-1 688 0344 2ABC03 lhld NEXTCOM ;next char address 689 0347 7E mov a,m 690 0348 23 inx h ;bump to next 691 0349 22BC03 shld NEXTCOM ;update 692 GNCRET: 693 034C E1 pop h 694 TRANS: 695 034D FE7F cpi 7Fh ;Rubout? 696 034F C8 rz 697 0350 FE61 cpi ('A' or 0100000b) 698 0352 D8 rc 699 0353 E65F ani 1011111b ; clear upper case bit 700 0355 C9 ret 701 ; 702 ; 703 ; Scan the buffer for the address read in ASCII from the terminal 704 ; 705 SCANAD: 706 0356 110000 lxi d,00h ;zero out address 707 0359 D5 push d ;and save 708 ; 709 035A 3AC603 lda CONBUF-1 ;get character count 710 035D FE05 cpi 05 ;5 is too many 711 035F DA6603 jc SCAN0 712 0362 37 stc ;set carry for routine 713 0363 C3B103 jmp SCNRET 714 SCAN0: 715 0366 CD3803 call GNC ;get a char 716 0369 FE0D cpi CR ;end? 717 036B CAB103 jz SCNRET ;to scnret if so 718 036E FE30 cpi '0' ;is it >0? 719 0370 D27603 jnc SCAN01 ;bad character 720 0373 C3B103 jmp SCNRET 721 SCAN01: 722 0376 FE40 cpi '@' 723 0378 C27F03 jnz SCAN02 ;bad character 724 037B 37 stc 725 037C C3B103 jmp SCNRET ;return on bad file 726 SCAN02: 727 037F D28703 jnc SCAN1 ;must be A-F 728 0382 D630 sui 030h ;normalize 0-9 CP/M RMAC ASSEM 1.1 #014 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 729 0384 C39203 jmp SCAN2 730 SCAN1: 731 0387 FE47 cpi 'G' ;is it out of range? 732 0389 DA9003 jc SCAN11 733 038C 37 stc 734 038D C3B103 jmp SCNRET 735 SCAN11: 736 0390 D637 sui 037h ;normalize 737 SCAN2: 738 0392 6F mov l,a ;character in low of DE 739 0393 3AC603 lda CONBUF-1 ;get # left 740 0396 C601 adi 1 ;readjust 741 0398 4F mov c,a 742 0399 2600 mvi h,00 ;zero out high order 743 SCAN3: 744 039B 0D dcr c ;dec to set flag 745 039C CAA603 jz SCAN4 ;were done 746 039F 29 dad h ;shift 1bit left 747 03A0 29 dad h ;same 748 03A1 29 dad h ;same 749 03A2 29 dad h ;finally 750 03A3 C39B03 jmp SCAN3 ;back for more 751 ; 752 SCAN4: 753 03A6 D1 pop d ;ready for or 754 03A7 7A mov a,d ;high order 755 03A8 B4 ora h ; 756 03A9 57 mov d,a 757 03AA 7B mov a,e ;low order 758 03AB B5 ora l ;ORed 759 03AC 5F mov e,a ;back 760 03AD D5 push d ;save 761 03AE C36603 jmp SCAN0 ;get more characters 762 SCNRET: 763 03B1 D1 pop d ;hl = address 764 03B2 EB xchg ;DE->HL 765 03B3 C9 ret 766 ; 767 ; 768 ; ********************************* 769 ; * * 770 ; * Data Structures * 771 ; * * 772 ; ********************************* 773 ; 774 SCBPB: 775 03B4 3A db 03Ah ;SCB address 776 03B5 00 db 0 777 ; 778 03B6 0000 SADDR: dw 0 ;write start address 779 03B8 0000 FADDR: dw 0 ;write finish address 780 03BA 0000 BIOSAD: dw 0 ;WarmBOOT bios address 781 03BC 0000 NEXTCOM: dw 0 ;address of next character to read 782 03BE 00 ONEFLG: db 0 783 03BF 0000 RSLT: dw 0 784 03C1 00 CHGJMP db FALSE CP/M RMAC ASSEM 1.1 #015 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 785 ; 786 03C2 0000 SCBADR: dw 0 ;Scb address 787 ; 788 03C4 00 BIOSMD: db 0 ;if non-zero change LXI @jmpadr to 789 ;JUMP when removed. 790 ; 791 03C5 0E BUFFER: db CONMAX 792 03C6 00 db 0 ;# of console characters read 793 03C7 CONBUF: ds CONMAX 794 ; 795 03D5 0D0A43502FSIGNON: db CR,LF,'CP/M 3 SAVE - Version ',VERSION/10+'0','.',VERSION mod 10+'0','$' 796 03F1 0D0A456E74FLEPRMPT: db CR,LF,'Enter file ' 797 03FE 2874797065 db '(type RETURN to exit): $' 798 0416 0D0A44656CDELFLE: db CR,LF,'Delete $' 799 0420 0D0A426567SPRMPT: db CR,LF,'Beginning hex address $' 800 0439 0D0A456E64FPRMPT: db CR,LF,'Ending hex address $' 801 0452 0D0A24 ENDMSG: db CR,LF,'$' 802 ; 803 ; Error messages...... 804 0455 0D0A455252CERROR: db CR,LF,'ERROR: Bad close.$' 805 0469 0D0A455252NODIR: db CR,LF,'ERROR: No directory space.$' 806 0486 0D0A455252NOBLK: db CR,LF,'ERROR: No disk space.$' 807 ; 808 ; Stack for program 809 049E ds STKSZE 810 STACK: 811 04AE end ;Physical end of program CP/M RMAC ASSEM 1.1 #016 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 BDOS 0005 29# 174 224 241 249 298 302 334 370 373 383 422 429 BDOSAD 0006 30# 35# BDOSER 002D 43# 172 BEGIN 0080 167 182# BIOSAD 03BA 159 162 347 780# BIOSMD 03C4 788# BSNLY 007F 70# BUFFER 03C5 257 272 421 791# BUFIN 000A 37# 420 CALRSX 003C 46# 98 CERROR 0455 337 804# CFILE 0010 38# 332 CHECK 01CF 284 324 405# CHGBIOS 019F 363 368# CHGJMP 03C1 139 148 361 784# CLOSE 016B 331# CMMON 00F9 71# 135 CONBUF 03C7 197 230 418 463 682 709 739 793# CONMAX 000E 60# 62# 791 793 CONMOD 006D 47# CR 000D 52# 685 716 795 796 798 799 800 801 804 805 806 CTLC 0003 51# DBLNK1 0334 670 672 674# DEBLNK 0328 465 531 667# 676 DELFLE 0416 228 798# DELIM 02E6 466 489 532 562 578 584 611 621# DELIM1 0321 658 660# DELIM2 0324 633 663# DFCB 005C 31# 223 240 248 301 333 464 DFILE 0013 39# 239 ENDADD 0109 267# 274 277 ENDMSG 0452 341 801# FADDR 03B8 279 322 779# FALSE 0000 21# 138 387 784 FINIS 017D 307 312 338 342# FLECLR 00D9 226 238# FLEGET 0089 192# 212 235 FLEPRMPT 03F1 193 796# FPRMPT 0439 268 800# GETBUF 01DA 195 232 255 270 415# GETGOING 0031 99 114# GETSCB 0031 44# 381 GETSETSCB 01A9 132 380# GNC 0338 233 680# 715 GNCRET 034C 686 692# GOODBYE 018B 112 355# JUMP 00C3 68# 82 145 366 LDRSX 003B 45# 116 LF 000A 53# 795 796 798 799 800 801 804 805 806 LXIH 0021 69# 149 MFILE 0016 41# 247 MORRSX 0060 146 151# NBNKED 0060 140 153# NEXT 000A 83# 118 179 CP/M RMAC ASSEM 1.1 #017 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 NEXTCOM 03BC 419 688 691 781# NEXTJ 0009 81# NOBLK 0486 310 806# NODIR 0469 305 805# ONEFLG 03BE 326 388 400 782# PADFLD 02DE 508 524 563 585 614# 618 PARSE 01EF 209 432# PARSE1 020C 467 474# PARSE2 023A 479 499# PARSE3 023D 472 490 497 502# PARSE4 024F 507 511# PARSE5 0253 509 514# PARSE6 0255 516# 520 PARSE7 0269 523 526# PARSE8 026D 525 529# PARSE81 027C 533 537# PARSE82 027D 536 539# PARSE9 028E 470 483 485 492 494 496 555# 581 665 PATCH18 FFFF 23# 59 PREFIX 001B 80 96# PREV 000C 85# PSTR 01E9 188 194 229 231 254 269 343 425# PSTRING 0009 36# 428 PWFLD 02B7 528 583# PWFLD1 02CA 598# 612 REPLCE 0180 200 315 346# RETDSP 00FE 67# 173 RSLT 03BF 389 392 409 412 783# SADDR 03B6 264 281 288 778# SCAN0 0366 711 714# 761 SCAN01 0376 719 721# SCAN02 037F 723 726# SCAN1 0387 727 730# SCAN11 0390 732 735# SCAN2 0392 729 737# SCAN3 039B 743# 750 SCAN4 03A6 745 752# SCANAD 0356 261 276 705# SCBADR 03C2 133 142 364 786# SCBOST 0068 66# 143 365 SCBPB 03B4 382 774# SCNRET 03B1 713 717 720 725 734 762# SETDMA 001A 42# 297 SETFD1 02A9 566 571# SETFD2 02AB 570 574# SETFD3 02AF 577# 610 SETFLD 0294 504 513 561# 569 576 SIGNON 03D5 187 795# SPRMPT 0420 253 799# STACK 04AE 186 810# START 003A 117 123# STKSZE 0010 65# 809 STKYBT 000E 87# 357 STRADD 00EF 252# 259 262 285 TRANS 034D 694# TRUE FFFF 20# 21 23 147 327 362 399 CP/M RMAC ASSEM 1.1 #018 SAVE.RSX - CP/M 3.0 SAVE ROUTINE. JULY 1982 VERSION 001E 55# 795 795 WBOOT 0000 27# WBTADR 0001 28# 156 349 WFILE 0015 40# 300 WFLAG 01B2 295 386# WFLAG1 01C9 394 395 398# WLOOP 0132 294# 328