[Copyright 1999,2002 Frank Durda IV, All Rights Reserved. Mirroring of any material on this page in any form is expressly prohibited. The official web site for this material is: http://nemesis.lonestar.org Contact this address for use clearances: clearance at nemesis.lonestar.org Comments and queries to this address: web_software_2011 at nemesis.lonestar.org]
MISOSYS EDAS-4.3 04/11/99 22:40:07 SYS1 - LS-DOS 6.2 Page 00001 00001 ;SYS1/ASM - LS-DOS 6.2 00003 ; 003A 00004 LD___A EQU 3AH ;LD A,(nnnn) 00005 ; 0000 00006 @SMALL EQU 0 ;Switch for "SMALL" or 00007 ; "FULL" library 00008 ; 8000 00009 LIBA EQU 08000H A000 00010 LIBB EQU 0A000H ;Set bit 5 C000 00011 LIBC EQU 0C000H ;Set bit 6 000A 00012 LF EQU 10 000D 00013 CR EQU 13 00014 *LIST OFF ;Get SYS0/EQU 00352 *LIST ON 0000 00353 *GET COPYCOM:3 ;Copyright message 00354 ; COPYCOM - File for Copyright COMment block 00355 ; 0000 00356 *GET BUILDVER/ASM:3 00357 ; 00358 ; Buildver/asm is a bit of a kludge since not all utilities can load 00359 ; equates from LDOS60 and still compile. LOWCORE and everybody else 00360 ; relies on this setting, and it eventually ends up in LDOS60/EQU 00361 ; for programs that can use that. 00362 ; FFFF 00363 @BLD631 EQU -1 ;<631>Build 631 distribution (LEVEL 1B) 00364 ; These switches activate patches made since the 1B release. 00365 ; It is important that all earlier patches be enabled when a higher 00366 ; patch is enabled. 00367 ; Patches C thru F were published in TMQ IV.iv, page 32 (NOTE: the 00368 ; patch addresses listed for SPOOL in SPOOL1/FIX are 19H high.) FFFF 00369 @BLD631C EQU -1 ;<631>Apply 1C patches (SETKI) FFFF 00370 @BLD631D EQU -1 ;<631>Apply 1D patches (DIR) FFFF 00371 @BLD631E EQU -1 ;<631>Apply 1E patches (DIR & MEMDISK/DCT) FFFF 00372 @BLD631F EQU -1 ;<631>Apply 1F patches (SPOOL) 00373 ; Patches G and H were published in TMQ V.i, pages 10 and 18/19. FFFF 00374 @BLD631G EQU -1 ;<631>Apply 1G patches (//KEYIN,DIR,DO *) FFFF 00375 @BLD631H EQU -1 ;<631>Apply 1H patches (MEMORY) 00376 ; 00377 ;End of BUILDVER/ASM 00378 IF @BLD631 00380 ELSE 00381 COM '<*(C) 1982,3,4,6 by LSI*>' 00382 ENDIF 00383 ; 1E00 00384 ORG 1E00H 00385 ; 1E00 1802 00386 SYS1 JR SYS1BGN ;Hop around pointer 1E02 241F 00387 DW LIBTBL$ ;LIBTBL pointer 1E04 E670 00388 SYS1BGN AND 70H ;Strip all but ept 1E06 C8 00389 RET Z ;Back on zero entry 1E07 FE10 00390 CP 10H ;Ck for @EXIT 1E09 2836 00391 JR Z,CMD 1E0B FE40 00392 CP 40H ;Ck for FSPEC 1E0D CA5E20 00393 JP Z,FSPEC 1E10 FE50 00394 CP 50H ;Ck for FEXT 1E12 CAD120 00395 JP Z,FEXT 1E15 FE60 00396 CP 60H ;Ck for PARAM 1E17 CAD721 00397 JP Z,PARAM 1E1A FE70 00398 CP 70H ;Ck for vacant entry 1E1C C8 00399 RET Z 00400 ; 00401 ; Entry code for CMNDI (30) and CMNDR (20) SVCs 00402 ; 1E1D 112004 00403 LD DE,INBUF$ ;Move 79 characters 1E20 D5 00404 PUSH DE ; from (HL) to buffer 1E21 014F00 00405 LD BC,79 1E24 EDB0 00406 LDIR 1E26 EB 00407 EX DE,HL ;Terminate with ETX 1E27 3603 00408 LD (HL),3 1E29 E1 00409 POP HL ;Recover buffer start 1E2A FE30 00410 CP 30H ;Ck entry for CMNDI 1E2C 280E 00411 JR Z,CMD30 ;Go on CMNDI 1E2E CD5305 00412 CALL @CKBRKC ;Clear the Break bit 1E31 3A6C00 00413 LD A,(CFLAG$) 1E34 F602 00414 OR 2 ;Set CMNDR bit 1E36 326C00 00415 LD (CFLAG$),A ;Put it back 1E39 C3BC1E 00416 JP CMD20 ; & go on CMNDR 00417 ; 00418 ; Entry for @EXIT & @CMNDI 00419 ; 1E3C CD461E 00420 CMD30 CALL CLEANUP ;Reset Break, stack, etc. 1E3F 1871 00421 JR CMD3A 00422 ; 1E41 CD461E 00423 CMD CALL CLEANUP ;Reset Break, stack, etc. 1E44 1848 00424 JR CMDCONT 00425 ; 00426 CLEANUP 1E46 F3 00427 DI ;Stop for a moment 1E47 210000 00428 LD HL,0 ;Reset vectored BREAK 1E4A CD6F19 00429 CALL @BREAK ; to system 1E4D E1 00430 POP HL ;P/u local RETurn 1E4E 318003 00431 LD SP,STACK$ ;Reset stack pointer 1E51 010B1B 00432 LD BC,@EXIT ;Establish ret address 1E54 C5 00433 PUSH BC 1E55 E5 00434 PUSH HL ;Put back local return 1E56 3A7C00 00435 LD A,(SFLAG$) ;DEBUG to be on or off? 1E59 07 00436 RLCA 1E5A 3EC9 00437 LD A,0C9H ;Bit 7, 1=on, 0=off 1E5C 3001 00438 JR NC,DBGOFF ;Go if OFF 1E5E AF 00439 XOR A ; else reset to on 1E5F 329F19 00440 DBGOFF LD (@DBGHK),A 1E62 217400 00441 LD HL,KFLAG$ ;Point to KFLAG$ 1E65 3EF9 00442 LD A,11111001B ;Reset pause and enter 1E67 A6 00443 AND (HL) ;Merge together 1E68 77 00444 LD (HL),A 1E69 217C00 00445 LD HL,SFLAG$ ;Point to SFLAG 1E6C 3EF8 00446 LD A,11111000B ;Reset 3 lo bits 1E6E A6 00447 AND (HL) ;Merge with old 1E6F 77 00448 LD (HL),A 1E70 21FF2F 00449 LD HL,2FFFH ;Reset LOW$ 1E73 221E00 00450 LD (LOW$),HL 00451 ; 00452 ; Reset video ram handler pointer 00453 ; 1E76 216E08 00454 LD HL,OPREG_SV_AREA 1E79 223508 00455 LD (OPREG_SV_PTR),HL 1E7C 3A6C00 00456 LD A,(CFLAG$) ;P/u CFLAG 1E7F E620 00457 AND 20H ;Leave only bit 5 1E81 326C00 00458 LD (CFLAG$),A ; and put it back 1E84 212004 00459 LD HL,INBUF$ ;Point to command line 1E87 E5 00460 PUSH HL ;Xfer start 1E88 C1 00461 POP BC ; to BC 1E89 FB 00462 EI 1E8A CD5305 00463 CALL @CKBRKC ;Check and clear BREAK 1E8D C9 00464 RET ;Local cleanup done 00465 ; 1E8E 3A6E00 00466 CMDCONT LD A,(EFLAG$) ;P/u ECI flag 1E91 B7 00467 OR A ;Check if set 1E92 2803 00468 JR Z,CMD1A ;Go if normal 1E94 F68F 00469 OR 10001111B ;Set for SYS13 but 00470 ; leave user entry code 1E96 EF 00471 RST 40 00472 ; 1E97 21E022 00473 CMD1A LD HL,RDYMSG$ ;Display ready message 1E9A CD2D05 00474 CALL @DSPLY 1E9D 216C00 00475 CMD2 LD HL,CFLAG$ ;Let the world know we 1EA0 CBD6 00476 SET 2,(HL) ; are in the command 1EA2 E5 00477 PUSH HL ; interpreter 1EA3 212004 00478 LD HL,INBUF$ ;Get 79 chars max 1EA6 01004F 00479 LD BC,79<8 ;No fill char for now 1EA9 CD8505 00480 CALL @KEYIN 1EAC E3 00481 EX (SP),HL ;Turn off the interpreter 1EAD CB96 00482 RES 2,(HL) ; bit & reget the buffer 1EAF E1 00483 POP HL 1EB0 388F 00484 JR C,CMD ;Jump on00485 ; 00486 ; Entry from @EXIT & @CMNDI 00487 ; 00488 CMD3A 1EB2 7E 00489 LD A,(HL) ;Check for comment 1EB3 FE2E 00490 CP '.' ;If so go before CR 1EB5 2805 00491 JR Z,CMD20 ; is displayed 00492 ; 1EB7 3E0D 00493 LD A,CR ;Do a line feed on 1EB9 CD4206 00494 CALL @DSP ; CMNDI and @EXIT 00495 ; 00496 ; Entry from @CMNDR plus the above 00497 ; 00498 ; Always bring in bank 0 00499 ; 1EBC AF 00500 CMD20 XOR A ;Prepare for bank-0 1EBD 47 00501 LD B,A ;Set function and 1EBE 4F 00502 LD C,A ; bank number to 0 1EBF CD7708 00503 CALL @BANK ;Invoke bank 0 00504 ; 00505 ; Process the command entry 00506 ; 1EC2 CD0305 00507 CALL @LOGER ;Log the entry 1EC5 11E000 00508 LD DE,CFCB$ ;Point to command FCB 1EC8 7E 00509 LD A,(HL) ;Jump on comment 1EC9 FE2E 00510 CP '.' 1ECB 2838 00511 JR Z,COMMENT 1ECD FE2A 00512 CP '*' ;Check if alternate CMD 1ECF 2006 00513 JR NZ,CKNOEXC ; processor needed 1ED1 E5 00514 PUSH HL 1ED2 C1 00515 POP BC ;Get Buffer in BC 1ED3 23 00516 INC HL ;Move HL past '*' 1ED4 3EFF 00517 LD A,0FFH ;Set up for SYS13 entry 1ED6 EF 00518 RST 40 ; # 7, and do it 1ED7 D621 00519 CKNOEXC SUB '!' ;Test for program force 1ED9 2001 00520 JR NZ,NOEXC 1EDB 23 00521 INC HL ;Bump past the '!' 1EDC 32E61E 00522 NOEXC LD (TSTEXC+1),A 1EDF CD5E20 00523 CALL FSPEC ;Fetch command spec 1EE2 201D 00524 JR NZ,WHAT ;Jump on error 1EE4 E5 00525 PUSH HL ;Save terminator pointer 1EE5 3E00 00526 TSTEXC LD A,0 ;Test if prog force 1EE7 B7 00527 OR A 1EE8 2808 00528 JR Z,NOTLIB ;Jump if starting "!" 1EEA 01241F 00529 LD BC,LIBTBL$ ;Pt to tbl of LIB cmds 1EED CD5721 00530 CALL @FNDPRM ;Check for a match 1EF0 281F 00531 JR Z,CMD4 ;Jump if it is 1EF2 21DD22 00532 NOTLIB LD HL,DFTEXT ;Else assume prg file, so 1EF5 CDD120 00533 CALL FEXT ; default 'EXT' to CMD 1EF8 E1 00534 POP HL ;Rcvr terminator pointer 1EF9 3A6C00 00535 LD A,(CFLAG$) ;Ck LIB only execution 1EFC E610 00536 AND 10H ;CFLAG$ bit-4 1EFE CA1D1B 00537 JP Z,@RUN ;The program else WHAT? 00538 ; 00539 ; Process non-entry 00540 ; 1F01 21FFFF 00541 WHAT LD HL,-1 ;Set to show abort 1F04 C9 00542 RET 00543 ; 00544 ; Process "dot" comment 00545 ; 1F05 3A7C00 00546 COMMENT LD A,(SFLAG$) ;Ret if in effect 1F08 CB6F 00547 BIT 5,A ; else get another 1F0A CA9D1E 00548 JP Z,CMD2 ; input line 1F0D 210000 00549 LD HL,0 ;Set for no error 1F10 C9 00550 RET 00551 ; 00552 ; Process LIB command 00553 ; 1F11 E1 00554 CMD4 POP HL ;Rcvr terminator pointer 1F12 3EC9 00555 LD A,0C9H ;Turn off DEBUG 1F14 329F19 00556 LD (@DBGHK),A 1F17 7A 00557 LD A,D ;Test bit 7 of high 1F18 07 00558 RLCA ; order LIB address 1F19 D5 00559 PUSH DE ;Ret to address of 1F1A D0 00560 RET NC ; vector if bit 7 = 0 1F1B D1 00561 POP DE 1F1C 43 00562 LD B,E ;Else put overlay # in 1F1D 07 00563 RLCA ;Calculate needed library 1F1E 07 00564 RLCA ; by rotating 7-5 into 1F1F C684 00565 ADD A,84H ; 2-0 & adding RST base 1F21 EF 00566 RST 28H 00567 ; 00568 ; BOOT code brings back the ROM 00569 ; 1F22 AF 00570 BOOTIT XOR A ;SVC-0 => @IPL 1F23 EF 00571 RST 40 00572 ; 00573 ; LIBRARY look-up table starts here 00574 ; 1F24 00575 LIBTBL$ EQU $ ;Start of library table 00576 ; 00577 IF @SMALL 00578 ; 00579 ; Use this table for SMALL (OEM) library 00580 ; 00581 ; DB 'APPEND' 00582 ; DW LIBA!31H 00583 DB 'ATTRIB' 00584 DW LIBB!51H 00585 DB 'AUTO ' 00586 DW LIBB!11H 00587 ;DB 'BOOT ' 00588 ; DW BOOTIT 00589 ; DB 'BUILD ' 00590 ; DW LIBB!33H 00591 ; DB 'CAT ' 00592 ; DW LIBA!20H 00593 ; DB 'CLS ' 00594 ; DW LIBA!24H 00595 DB 'COPY ' 00596 DW LIBA!32H 00597 ; DB 'CREATE' 00598 ; DW LIBB!13H 00599 DB 'DATE ' 00600 DW LIBB!15H 00601 ; DB 'DEBUG ' 00602 ; DW LIBB!14H 00603 ; DB 'DEVICE' 00604 ; DW LIBA!61H 00605 DB 'DIR ' 00606 DW LIBA!21H 00607 DB 'DO ' 00608 DW LIBA!91H 00609 ; DB 'DUMP ' 00610 ; DW LIBB!71H 00611 DB 'FILTER' 00612 DW LIBA!66H 00613 DB 'FORMS ' 00614 DW LIBC!0B1H 00615 ; DB 'FREE ' 00616 ; DW LIBB!22H 00617 ; DB 'LIB ' 00618 ; DW LIBA!19H 00619 ; DB 'LINK ' 00620 ; DW LIBA!62H 00621 ; DB 'LIST ' 00622 ; DW LIBA!41H 00623 ; DB 'LOAD ' 00624 ; DW LIBA!81H 00625 ; DB 'MEMORY' 00626 ; DW LIBA!1EH 00627 ; DB 'PURGE ' 00628 ; DW LIBB!72H 00629 DB 'REMOVE' 00630 DW LIBA!18H 00631 ; DB 'RENAME' 00632 ; DW LIBA!53H 00633 ; DB 'RESET ' 00634 ; DW LIBA!63H 00635 ; DB 'ROUTE ' 00636 ; DW LIBA!64H 00637 ; DB 'RUN ' 00638 ; DW LIBA!82H 00639 DB 'SET ' 00640 DW LIBA!65H 00641 ; DB 'SETCOM' 00642 ; DW LIBC!0B2H 00643 ; DB 'SETKI ' 00644 ; DW LIBC!0B3H 00645 ; DB 'SPOOL ' 00646 ; DW LIBC!0A2H 00647 DB 'SYSGEN' 00648 DW LIBC!1CH 00649 DB 'SYSTEM' 00650 DW LIBC!0A1H 00651 DB 'TIME ' 00652 DW LIBB!16H 00653 ; DB 'TOF ' 00654 ; DW LIBA!25H 00655 DB 'VERIFY' 00656 DW LIBB!1BH 00657 NOP ;Patch 'K' here for KILL 00658 ; DB 'ILL ' 00659 ; DW LIBA!18H 00660 NOP 00661 ; 00662 ; 00663 ELSE 00664 ; 00665 ; This table for FULL library 00666 ; 1F24 41 00667 DB 'APPEND' 50 50 45 4E 44 1F2A 3180 00668 DW LIBA!31H 1F2C 41 00669 DB 'ATTRIB' 54 54 52 49 42 1F32 51A0 00670 DW LIBB!51H 1F34 41 00671 DB 'AUTO ' 55 54 4F 20 20 1F3A 11A0 00672 DW LIBB!11H 1F3C 42 00673 DB 'BOOT ' 4F 4F 54 20 20 1F42 221F 00674 DW BOOTIT 1F44 42 00675 DB 'BUILD ' 55 49 4C 44 20 1F4A 33A0 00676 DW LIBB!33H 1F4C 43 00677 DB 'CAT ' 41 54 20 20 20 1F52 2080 00678 DW LIBA!20H 1F54 43 00679 DB 'CLS ' 4C 53 20 20 20 1F5A 2480 00680 DW LIBA!24H 1F5C 43 00681 DB 'COPY ' 4F 50 59 20 20 1F62 3280 00682 DW LIBA!32H 1F64 43 00683 DB 'CREATE' 52 45 41 54 45 1F6A 13A0 00684 DW LIBB!13H 1F6C 44 00685 DB 'DATE ' 41 54 45 20 20 1F72 15A0 00686 DW LIBB!15H 1F74 44 00687 DB 'DEBUG ' 45 42 55 47 20 1F7A 14A0 00688 DW LIBB!14H 1F7C 44 00689 DB 'DEVICE' 45 56 49 43 45 1F82 6180 00690 DW LIBA!61H 1F84 44 00691 DB 'DIR ' 49 52 20 20 20 1F8A 2180 00692 DW LIBA!21H 1F8C 44 00693 DB 'DO ' 4F 20 20 20 20 1F92 9180 00694 DW LIBA!91H 1F94 44 00695 DB 'DUMP ' 55 4D 50 20 20 1F9A 71A0 00696 DW LIBB!71H 1F9C 46 00697 DB 'FILTER' 49 4C 54 45 52 1FA2 6680 00698 DW LIBA!66H 1FA4 46 00699 DB 'FORMS ' 4F 52 4D 53 20 1FAA B1C0 00700 DW LIBC!0B1H 1FAC 46 00701 DB 'FREE ' 52 45 45 20 20 1FB2 22A0 00702 DW LIBB!22H 1FB4 49 00703 DB 'ID ' 44 20 20 20 20 1FBA 2680 00704 DW LIBA!26H 1FBC 4C 00705 DB 'LIB ' 49 42 20 20 20 1FC2 1980 00706 DW LIBA!19H 1FC4 4C 00707 DB 'LINK ' 49 4E 4B 20 20 1FCA 6280 00708 DW LIBA!62H 1FCC 4C 00709 DB 'LIST ' 49 53 54 20 20 1FD2 4180 00710 DW LIBA!41H 1FD4 4C 00711 DB 'LOAD ' 4F 41 44 20 20 1FDA 8180 00712 DW LIBA!81H 1FDC 4D 00713 DB 'MEMORY' 45 4D 4F 52 59 1FE2 1E80 00714 DW LIBA!1EH 1FE4 50 00715 DB 'PURGE ' 55 52 47 45 20 1FEA 72A0 00716 DW LIBB!72H 1FEC 52 00717 DB 'REMOVE' 45 4D 4F 56 45 1FF2 1880 00718 DW LIBA!18H 1FF4 52 00719 DB 'RENAME' 45 4E 41 4D 45 1FFA 5380 00720 DW LIBA!53H 1FFC 52 00721 DB 'RESET ' 45 53 45 54 20 2002 6380 00722 DW LIBA!63H 2004 52 00723 DB 'ROUTE ' 4F 55 54 45 20 200A 6480 00724 DW LIBA!64H 200C 52 00725 DB 'RUN ' 55 4E 20 20 20 2012 8280 00726 DW LIBA!82H 2014 53 00727 DB 'SET ' 45 54 20 20 20 201A 6580 00728 DW LIBA!65H 201C 53 00729 DB 'SETCOM' 45 54 43 4F 4D 2022 B2C0 00730 DW LIBC!0B2H 2024 53 00731 DB 'SETKI ' 45 54 4B 49 20 202A B3C0 00732 DW LIBC!0B3H 202C 53 00733 DB 'SPOOL ' 50 4F 4F 4C 20 2032 A2C0 00734 DW LIBC!0A2H 2034 53 00735 DB 'SYSGEN' 59 53 47 45 4E 203A 1CC0 00736 DW LIBC!1CH 203C 53 00737 DB 'SYSTEM' 59 53 54 45 4D 2042 A1C0 00738 DW LIBC!0A1H 2044 54 00739 DB 'TIME ' 49 4D 45 20 20 204A 16A0 00740 DW LIBB!16H 204C 54 00741 DB 'TOF ' 4F 46 20 20 20 2052 2580 00742 DW LIBA!25H 2054 56 00743 DB 'VERIFY' 45 52 49 46 59 205A 1BA0 00744 DW LIBB!1BH 205C 00 00745 NOP ;Patch 'K' here for KILL 00746 ; DB 'ILL ' 00747 ; DW LIBA!18H 205D 00 00748 NOP 00749 ; 00750 ENDIF 00751 ; 00752 ; 00753 ; Routine to fetch a filespec/devicespec 00754 ; 205E D5 00755 FSPEC PUSH DE ;Save pointer to DCB 205F CD0521 00756 CALL @PARSER ;Parse expected command 2062 203D 00757 JR NZ,FSP5 ;NZ=not file, ck for device 2064 FE2F 00758 CP '/' ;EXT separator? 2066 2007 00759 JR NZ,FSP1 2068 12 00760 LD (DE),A ;File extent coming, 2069 13 00761 INC DE ; get it 206A 0603 00762 LD B,3 ;EXT is 3-chars max 206C CD0721 00763 CALL @PAR1 206F FE2E 00764 FSP1 CP '.' ;Password entered? 2071 2007 00765 JR NZ,FSP2 2073 12 00766 LD (DE),A ;Password coming, 2074 13 00767 INC DE ; get it also 2075 CD0521 00768 CALL @PARSER 2078 2034 00769 JR NZ,FSP6 ;Return if error 207A FE3A 00770 FSP2 CP ':' ;Drive entered? 207C 2009 00771 JR NZ,FSP3 207E 12 00772 LD (DE),A ;A one-byte drive 207F 13 00773 INC DE ; has been had 2080 0601 00774 LD B,1 2082 CD0721 00775 CALL @PAR1 2085 2027 00776 JR NZ,FSP6 ;Return if error 2087 FE21 00777 FSP3 CP '!' ;Update EOF always? 2089 2004 00778 JR NZ,FSP4 208B 12 00779 LD (DE),A ;Yes, slow but accurate 208C 13 00780 INC DE ;Inc buffer pointers 208D 23 00781 INC HL 208E 7E 00782 LD A,(HL) 208F 4F 00783 FSP4 LD C,A ;Save separator char 2090 3E03 00784 LD A,3 2092 12 00785 LD (DE),A ;Stuff an ETX 00786 IF @BLD631 00787 ELSE 00788 XOR A 00789 ENDIF 2093 79 00790 LD A,C ;P/u separator 2094 D1 00791 POP DE ;P/u start of DCB 2095 D5 00792 PUSH DE 2096 01B020 00793 LD BC,PREPTBL ;Ck on prepositions 2099 CD5721 00794 CALL @FNDPRM 209C D1 00795 POP DE ;Can use TO, ON, 209D 28BF 00796 JR Z,FSPEC ; OVER, USING 209F AF 00797 XOR A 20A0 C9 00798 RET 20A1 FE2A 00799 FSP5 CP '*' ;Ck on device spec 20A3 2009 00800 JR NZ,FSP6 ;Jump if not device 20A5 12 00801 LD (DE),A ; else stuff the '*' 20A6 13 00802 INC DE 20A7 0602 00803 LD B,2 ;Xfer two char device 20A9 CD0721 00804 CALL @PAR1 20AC 28E1 00805 JR Z,FSP4 ;Terminate buffer 20AE D1 00806 FSP6 POP DE 20AF C9 00807 RET 00808 ; 00809 ; Preposition table 00810 ; 20B0 54 00811 PREPTBL DB 'TO ' 4F 20 20 20 20 20B6 001D 00812 DW SBUFF$ 20B8 4F 00813 DB 'ON ' 4E 20 20 20 20 20BE 001D 00814 DW SBUFF$ 20C0 4F 00815 DB 'OVER ' 56 45 52 20 20 20C6 001D 00816 DW SBUFF$ 20C8 55 00817 DB 'USING ' 53 49 4E 47 20 20CE 001D 00818 DW SBUFF$ 20D0 00 00819 NOP 00820 ; 00821 ; Fetch default file extension 00822 ; 20D1 D5 00823 FEXT PUSH DE ;Save FCB pointer 20D2 E5 00824 PUSH HL ;Save EXT default pointer 20D3 EB 00825 EX DE,HL ;Exchange pointers 20D4 23 00826 INC HL 20D5 0609 00827 LD B,9 ;Init for 9-char test 20D7 7E 00828 FEX1 LD A,(HL) ;Ret if extension start 20D8 FE2F 00829 CP '/' ; is found 20DA 280D 00830 JR Z,FEX3 20DC 380E 00831 JR C,FEX4 ;Jump on other separator 20DE FE3A 00832 CP ':' ;Jump on digit 0-9 20E0 3804 00833 JR C,FEX2 20E2 FE41 00834 CP 'A' ;Jump on special char 20E4 3806 00835 JR C,FEX4 20E6 23 00836 FEX2 INC HL ;Advance past A-Z,0-9 20E7 10EE 00837 DJNZ FEX1 20E9 E1 00838 FEX3 POP HL ;User entered file ext 20EA D1 00839 POP DE ;FCB start 20EB C9 00840 RET 00841 ; 00842 ; Use default extension 00843 ; 20EC 010F00 00844 FEX4 LD BC,15 ;Point to position past 20EF 09 00845 ADD HL,BC ; the filespec 20F0 54 00846 LD D,H 20F1 5D 00847 LD E,L 20F2 13 00848 INC DE ;Make room for '/EXT' 20F3 13 00849 INC DE ; which is 4 chars 20F4 13 00850 INC DE 20F5 13 00851 INC DE 20F6 03 00852 INC BC ;Now move 16 bytes 20F7 EDB8 00853 LDDR 20F9 E1 00854 POP HL ;Recover pointer to EXT 20FA 23 00855 INC HL ;Point to 3rd char 20FB 23 00856 INC HL 20FC 0E03 00857 LD C,3 ;Move in 3 chars 20FE EDB8 00858 LDDR 2100 3E2F 00859 LD A,'/' ;Put in the slash 2102 12 00860 LD (DE),A 2103 D1 00861 POP DE ;Point back to FCB 2104 C9 00862 RET 00863 ; 00864 ; Get the code for the @PARAM SVC 00865 ; 2105 00866 *GET PARAM:3 00867 ;PARAM/ASM - LS-DOS 6.2 00868 ; 00869 ; Parse a field 00870 ; (HL) => command line 00871 ; (DE) => FCB area 00872 ; (HL) <= 1st byte past non- 00873 ; except 13, 3, "(" 00874 ; Z <= found valid field 00875 ; NZ <= found invalid field 00876 ; 2105 0608 00877 @PARSER LD B,8 ;Set length 2107 78 00878 @PAR1 LD A,B 2108 324521 00879 LD (PAR6+1),A ;Stuff length for test 210B 04 00880 INC B 210C 7E 00881 PAR2 LD A,(HL) 210D FE03 00882 CP 3 ;ETX? 210F 2826 00883 JR Z,PAR5 2111 FE0D 00884 CP CR ; ? 2113 2822 00885 JR Z,PAR5 2115 FE28 00886 CP '(' ;Begin of parm? 2117 281E 00887 JR Z,PAR5 2119 23 00888 INC HL ;Bump pointer to next 211A CD4921 00889 CALL TST09AZ ;Test if 0-9,A-Z 211D 300A 00890 JR NC,PAR3 ;Go if one of the above 211F FE61 00891 CP 'a' ;Check on lower case 2121 3814 00892 JR C,PAR5 ;Jump on non-alpha 2123 FE7B 00893 CP 'z'+1 ;Is it a-z? 2125 3010 00894 JR NC,PAR5 ;Jump on non-alpha 2127 CBAF 00895 RES 5,A ;Convert lower to upper 2129 05 00896 PAR3 DEC B ;Count down 212A 2808 00897 JR Z,PAR4 212C 12 00898 LD (DE),A ;Xfer the char 212D AF 00899 XOR A ;Show at least 1 valid 212E 324521 00900 LD (PAR6+1),A ;Char was detected 2131 13 00901 INC DE ;Bump FCB pointer 2132 18D8 00902 JR PAR2 ;Loop 2134 04 00903 PAR4 INC B ;Here on max chars ck'd 2135 18D5 00904 JR PAR2 2137 4F 00905 PAR5 LD C,A ;Save separator 00906 IF @BLD631 2138 FE20 00907 CP ' ' ;<631> 213A 2005 00908 JR NZ,PAR5A ;<631> 213C FE 00909 DB 0FEH ;<631>Single byte skip 213D 23 00910 PAR5B: INC HL ;<631> 213E BE 00911 CP (HL) ;<631> 213F 28FC 00912 JR Z,PAR5B ;<631> 2141 3E03 00913 PAR5A: LD A,3 ;<631> 2143 12 00914 LD (DE),A ;<631> 00915 ELSE 00916 LD A,3 ;Stuff ETX 00917 LD (DE),A 00918 ; 00919 ; Skip over spaces 00920 ; 00921 LD A,C ;Was separator a space? 00922 CP ' ' 00923 JR NZ,PAR6 ;Don't skip if not 00924 PAR5A CP (HL) ;Next char a space? 00925 INC HL 00926 JR Z,PAR5A ;Loop until not 00927 DEC HL ;Backup to last non-space 00928 ENDIF 00929 ; 00930 ; Return status of field validity 00931 ; 2144 3E00 00932 PAR6 LD A,0 ;Set Z-flag if at least 2146 B7 00933 OR A ; 1 valid char detected 2147 79 00934 LD A,C ;Recover separator char 2148 C9 00935 RET 00936 ; 00937 ; Test if 0-9 or A-Z 00938 ; 2149 FE30 00939 TST09AZ CP '0' ;Special character? 214B D8 00940 RET C ;Go if not in range 214C FE3A 00941 CP '9'+1 ;Jump on digit 0-9 214E 3805 00942 JR C,EXITC ;Go if 0-9 & make NC 2150 FE41 00943 CP 'A' ;Jump on spec char 2152 D8 00944 RET C ;Go if 3B-40 2153 FE5B 00945 CP 'Z'+1 ;Jump on A-Z 2155 3F 00946 EXITC CCF ;Switch flag of result 2156 C9 00947 RET 00948 ; 00949 ; Find parameter in table 00950 ; (HL) => pointer to line 00951 ; (DE) => pointer to buffer area 00952 ; (BC) => pointer to parameter table 00953 ; (BC) <= pointer to possible response byte 00954 ; (DE) <= parm vector address 00955 ; Z <= set if found 00956 ; NZ <= if not found in table 00957 ; 2157 E5 00958 @FNDPRM PUSH HL 2158 60 00959 LD H,B ;Xfer table addr 2159 69 00960 LD L,C 215A 7E 00961 LD A,(HL) ;P/u 1st byte of table 215B 07 00962 RLCA ; & test for enhanced 215C F5 00963 PUSH AF ; table format 215D 3001 00964 JR NC,FND1 215F 23 00965 INC HL ;Bump past indicator 2160 F1 00966 FND1 POP AF ;Old or enhanced format? 2161 F5 00967 PUSH AF 2162 3E05 00968 LD A,5 ;Init for old lengths 2164 010201 00969 LD BC,1<8!2 2167 3006 00970 JR NC,FND1A ;Branch if old format 2169 7E 00971 LD A,(HL) ; else get parm length 216A E60F 00972 AND 0FH ;Strip flags 216C 3D 00973 DEC A ;Adjust for length-1 216D 04 00974 INC B ;Update offset to address 216E 23 00975 INC HL ;Bump past TYPE byte 216F 329D21 00976 FND1A LD (FND3A+1),A ;Stuff the lengths 2172 80 00977 ADD A,B 2173 32B721 00978 LD (FND5A+1),A 2176 81 00979 ADD A,C 2177 327F21 00980 LD (FND2+1),A 217A 1A 00981 LD A,(DE) ;P/u command line byte 217B BE 00982 CP (HL) ;Match 1st char of table? 217C 280C 00983 JR Z,FND3 ;Jump if 1st char matches 217E 010800 00984 FND2 LD BC,8 ; else bypass that entry 2181 09 00985 ADD HL,BC 2182 7E 00986 LD A,(HL) ;Test for table end 2183 B7 00987 OR A 2184 20DA 00988 JR NZ,FND1 ;Loop if more 2186 E1 00989 POP HL ;Clean flag from stack 2187 E1 00990 POP HL ;Rcvr saved reg & 2188 3C 00991 INC A ; set NZ for not found 2189 C9 00992 RET 218A F1 00993 FND3 POP AF ;Ck old or new table 218B F5 00994 PUSH AF 218C 300E 00995 JR NC,FND3A ;Go if old format table 218E 2B 00996 DEC HL ;Ck if type byte permits 218F CB66 00997 BIT 4,(HL) ; single-char abbrev 2191 23 00998 INC HL 2192 2808 00999 JR Z,FND3A ;Go on no abbrev 2194 13 01000 INC DE ;Make sure the next char 2195 1A 01001 LD A,(DE) ; is not in the range 2196 1B 01002 DEC DE ; <0-9,A-Z> before 2197 CD4921 01003 CALL TST09AZ ; assuming abbrev 219A 381A 01004 JR C,FND5A ;Go on 1-char abbrevs 219C 0605 01005 FND3A LD B,5 ;5 more chars to match 219E E5 01006 PUSH HL 219F D5 01007 PUSH DE 21A0 78 01008 LD A,B ;Don't if trailing length 21A1 B7 01009 OR A ; is zero 21A2 2810 01010 JR Z,FND5 21A4 13 01011 FND4 INC DE 21A5 23 01012 INC HL 21A6 1A 01013 LD A,(DE) 21A7 FE03 01014 CP 3 ;ETX? 21A9 2822 01015 JR Z,FND7 21AB FE0D 01016 CP CR ;Jump on 21AD 281E 01017 JR Z,FND7 21AF BE 01018 CP (HL) ;Match? 21B0 2016 01019 JR NZ,FND6 ;Jump if not 21B2 10F0 01020 DJNZ FND4 ; else loop 21B4 D1 01021 FND5 POP DE ;Parm matched 21B5 E1 01022 POP HL ;Recover begin of parm 21B6 010600 01023 FND5A LD BC,6 ;Point to address field 21B9 09 01024 ADD HL,BC 21BA 4D 01025 LD C,L ;Save the response-byte 21BB 44 01026 LD B,H ; pointer in BC 21BC 0B 01027 DEC BC 21BD 5E 01028 LD E,(HL) ;P/u parm table address 21BE 23 01029 INC HL 21BF 56 01030 LD D,(HL) 21C0 F1 01031 POP AF ;If not enhanced, change 21C1 3802 01032 JR C,$+4 ; pointer to bucket 21C3 061D 01033 LD B,SBUFF$<-8 ; so we don't alter user 21C5 E1 01034 POP HL ;Recover line position 21C6 AF 01035 XOR A ;Show found 21C7 C9 01036 RET 21C8 CD4921 01037 FND6 CALL TST09AZ ;Ck if 0-9, A-Z 21CB 3005 01038 JR NC,FND8 ;Go if in range of above 21CD 7E 01039 FND7 LD A,(HL) ;Loop if table has 21CE FE20 01040 CP ' ' ; trailing spaces 21D0 28E2 01041 JR Z,FND5 21D2 D1 01042 FND8 POP DE 21D3 E1 01043 POP HL 21D4 18A8 01044 JR FND2 01045 ; 01046 ; PARAM routine 01047 ; (HL) => param line 01048 ; (DE) => parm table 01049 ; (DE) <= table address value 01050 ; C <= # of parm 01051 ; Z = OK 01052 ; NZ = parm error 01053 ; 21D6 23 01054 PARAM0 INC HL ;Bump the pointer 21D7 7E 01055 PARAM LD A,(HL) ; and p/u char 21D8 FE0D 01056 CP CR 21DA C8 01057 RET Z ;Return on enter 21DB FE20 01058 CP ' ' 21DD 28F7 01059 JR Z,PARAM0 ;Loop on space 21DF FE28 01060 CP '(' 21E1 205D 01061 JR NZ,PARAM5 ;Jump if not left paren 21E3 1A 01062 LD A,(DE) ;Check if enhanced table 21E4 07 01063 RLCA 21E5 3016 01064 JR NC,PARAM1 21E7 D5 01065 PUSH DE ;Save pointer to start 21E8 13 01066 INC DE ;Point to 1st TYPE byte 21E9 E5 01067 PUSH HL ;Save this posn 01068 ; 21EA 1A 01069 $?1 LD A,(DE) ;P/u TYPE byte 21EB E60F 01070 AND 0FH 21ED 280C 01071 JR Z,$?2 ;Exit on end of table 21EF 6F 01072 LD L,A ;Point to response byte 01073 IF @BLD631 21F0 AF 01074 XOR A ;<631> 21F1 67 01075 LD H,A ;<631> 01076 ELSE 01077 LD H,0 01078 ENDIF 21F2 2C 01079 INC L 21F3 19 01080 ADD HL,DE 01081 IF @BLD631 21F4 77 01082 LD (HL),A ;<631>Zero the response 01083 ELSE 01084 LD (HL),0 ;Zero the response 01085 ENDIF 21F5 23 01086 INC HL ;Bump to the next TYPE 21F6 23 01087 INC HL 21F7 23 01088 INC HL 21F8 EB 01089 EX DE,HL ;Table pointer back to DE 21F9 18EF 01090 JR $?1 ;Loop thru all response bytes 01091 ; 21FB E1 01092 $?2 POP HL ;Rcvr reg 21FC D1 01093 POP DE ; & start of parm table 21FD D5 01094 PARAM1 PUSH DE 21FE 060F 01095 LD B,15 ;Max 15-char field 2200 11001D 01096 LD DE,SBUFF$ ;Point to buffer region 2203 23 01097 INC HL ;Bypass the '(' 2204 CD0721 01098 CALL @PAR1 ;Get the field 2207 2B 01099 DEC HL ;Backup to separator 2208 D1 01100 POP DE 2209 2013 01101 JR NZ,ERROUT ;Return if bad field 220B FE0D 01102 CP CR ;If separator was a CR, 220D 2001 01103 JR NZ,$+3 ; we need to counteract 220F 23 01104 INC HL ; the DEC HL above 2210 D5 01105 PUSH DE 2211 42 01106 LD B,D ;Table pointer to BC 2212 4B 01107 LD C,E 2213 11001D 01108 LD DE,SBUFF$ ;Parm in table? 2216 CD5721 01109 CALL @FNDPRM 2219 C5 01110 PUSH BC ;Save response pointer 221A 2805 01111 JR Z,PARAM3 ;Jump if found in table 01112 ; 01113 ; Parameter not in table - NZ condition 01114 ; 221C D1 01115 PARAM2 POP DE ;Pop response pointer 221D D1 01116 POP DE ;Pop parm table pointer 221E 3E2C 01117 ERROUT LD A,44 ;Set up PARM ERROR 2220 C9 01118 RET 01119 ; 01120 ; Parameter found in table - parse the value 01121 ; 2221 7E 01122 PARAM3 LD A,(HL) ;Test for assignment 2222 FE3D 01123 CP '=' 01124 IF @BLD631 2224 010000 01125 LD BC,0 2227 2819 01126 JR Z,ASSIGN ;<631>Jump if parm=value 2229 0B 01127 DEC BC ;<631> 01128 ELSE 01129 JR Z,ASSIGN ;Jump if parm=value 01130 LD BC,-1 ; else set symbol TRUE 01131 ENDIF 222A E3 01132 PARMSW EX (SP),HL ;Get response byte 222B CBF6 01133 SET 6,(HL) ;Turn on FLAG-SWITCH 01134 ; 01135 ; Valid parm argument parsed into reg BC 01136 ; 222D EB 01137 PARAM4 EX DE,HL ;Address pointer to HL 222E 71 01138 LD (HL),C ;Stuff lo-order value 222F 23 01139 INC HL 2230 70 01140 LD (HL),B ;Stuff hi-order value 2231 E1 01141 POP HL ;Rcvr parm line pointer 2232 D1 01142 POP DE ;Rcvr parm table pointer 2233 7E 01143 LD A,(HL) 2234 FE2C 01144 CP ',' ;Comma separator? 2236 28C5 01145 JR Z,PARAM1 2238 FE0D 01146 CP CR 01147 IF @BLD631 223A C8 01148 RET Z ;<631> 01149 ELSE 01150 JR Z,PARAM5 01151 ENDIF 223B FE29 01152 CP ')' ;Closing paren? 223D 20DF 01153 JR NZ,ERROUT ;Leave with ERROR 223F 23 01154 INC HL ;Bump line pointer 2240 AF 01155 PARAM5 XOR A ;Show all OK 2241 C9 01156 RET 01157 ; 01158 ; Parameter assignment statement 01159 ; 2242 23 01160 ASSIGN INC HL ;Advance token past '=' 2243 7E 01161 LD A,(HL) 2244 FE22 01162 CP '"' ;Double quote string? 2246 282A 01163 JR Z,STRING 2248 FE41 01164 CP 'A' ;Ck on digit or 224A 3815 01165 JR C,ASS3 ; special character 224C CBAF 01166 RES 5,A ;Strip l/c if present 224E FE58 01167 CP 'X' ;Hexadecimal? 2250 2807 01168 JR Z,ASS1 2252 CD9022 01169 CALL ONOFF ;Ck on Y, N, ON, OFF 2255 28D3 01170 JR Z,PARMSW ;Set FLAG-SWITCH if OK 2257 18C3 01171 JR PARAM2 ; else error exit 2259 23 01172 ASS1 INC HL 225A CDB322 01173 CALL HEXVAL ;Ck on hex format 225D 20BD 01174 JR NZ,PARAM2 ;Error if bad format 225F 1807 01175 JR ASS3A ; else bypass & set resp 01176 ; 01177 ; Is the parameter numeric or flag ? 01178 ; 2261 FE30 01179 ASS3 CP '0' ;Parameter=number ? 2263 F5 01180 PUSH AF ;CF = 0 if number 2264 CDE103 01181 CALL @DECHEX ;Cvt # @ HL to bin in DE 2267 F1 01182 POP AF 2268 E3 01183 ASS3A EX (SP),HL ;Get response pointer 2269 3003 01184 JR NC,ASS4 ;Show numeric if CF=0 226B CBF6 01185 SET 6,(HL) ; otherwise show switch 226D 3A 01186 DB LD___A ;Skip next instruction 226E CBFE 01187 ASS4 SET 7,(HL) ;Set Numeric response bit 2270 18BB 01188 JR PARAM4 01189 ; 01190 ; Parameter string entry 01191 ; 2272 23 01192 STRING INC HL ;Bypass '"' 2273 44 01193 LD B,H ;Save starting address 2274 4D 01194 LD C,L 2275 7E 01195 STR1 LD A,(HL) ;P/u a char 2276 FE20 01196 CP 20H 2278 38A2 01197 JR C,PARAM2 ;Exit on control char 227A 23 01198 INC HL ;Bump pointer 227B FE22 01199 CP '"' ;Closing double quote 227D 20F6 01200 JR NZ,STR1 227F E5 01201 PUSH HL ;Save current pointer 2280 ED42 01202 SBC HL,BC ;Calc length of string 2282 7D 01203 LD A,L 2283 3D 01204 DEC A ;Adjust for INC HL 2284 FE20 01205 CP 32 ;If len > 31, set to 0 2286 3801 01206 JR C,$+3 2288 AF 01207 XOR A 2289 E1 01208 POP HL ;Rcvr pointer 228A E3 01209 EX (SP),HL ;Get response byte 228B F620 01210 OR 20H ;Set FLAG-STRING 228D 77 01211 LD (HL),A 228E 189D 01212 JR PARAM4 01213 ; 01214 ; Check for Yes, No, On, Off 01215 ; 01216 IF @BLD631 01217 ONOFF: ;<631> 01218 ELSE 01219 ONOFF LD BC,0 ;Init to FALSE 01220 ENDIF 2290 D659 01221 SUB 'Y' ;Is it Yes? 2292 2811 01222 JR Z,ONO1 ;Jump on yes 2294 C60B 01223 ADD A,'Y'-'N' ;Is it No? 2296 280E 01224 JR Z,ONO2 ;Jump on no 2298 3D 01225 DEC A ;Is it 'O'n or 'O'ff? 2299 C0 01226 RET NZ ;Return if not on/off 229A 23 01227 INC HL ;Bump pointer to next 229B 7E 01228 LD A,(HL) ; character & p/u 229C CBAF 01229 RES 5,A ;Set lower to upper 229E FE46 01230 CP 'F' 22A0 2804 01231 JR Z,ONO2 ;Jump on off 22A2 FE4E 01232 CP 'N' 22A4 C0 01233 RET NZ ;Return if not on 01234 IF @BLD631 22A5 0B 01235 ONO1 DEC BC ;<631>Init to true 01236 ELSE 01237 ONO1 LD BC,-1 ;Init to true 01238 ENDIF 22A6 23 01239 ONO2 INC HL ;Ignore trailing part 22A7 7E 01240 LD A,(HL) ; of word until closing 22A8 FE29 01241 CP ')' ; ")" or comma separator 22AA C8 01242 RET Z ; or CR 22AB FE0D 01243 CP CR 22AD C8 01244 RET Z 22AE FE2C 01245 CP ',' 22B0 C8 01246 RET Z 22B1 18F3 01247 JR ONO2 ;Loop 01248 ; 01249 ; Process hexadecimal assignment 01250 ; 01251 IF @BLD631 01252 HEXVAL: ;<631> 01253 ELSE 01254 HEXVAL LD BC,0 ;Init value to zero 01255 ENDIF 22B3 7E 01256 LD A,(HL) ;P/u a char 22B4 FE27 01257 CP 27H ;Must be single quote 22B6 C0 01258 RET NZ ;Ret if not 22B7 23 01259 HEX1 INC HL ;Bump past it 22B8 7E 01260 LD A,(HL) ;P/u possible hex digit 22B9 D630 01261 SUB 30H ;Begin conversion 22BB 380C 01262 JR C,HEX2 ;Jump if < "0" 22BD FE0A 01263 CP 10 ;Ck for 0-9 22BF 3810 01264 JR C,HEX3 ;Jump if digit is 0-9 22C1 CBAF 01265 RES 5,A ;Strip l/c if present 22C3 D607 01266 SUB 7 ; else ck A-F 22C5 FE10 01267 CP 16 22C7 3808 01268 JR C,HEX3 ;Jump if A-F 22C9 7E 01269 HEX2 LD A,(HL) ;Test for closing quote 22CA FE27 01270 CP 27H 22CC 23 01271 INC HL ;Bump pointer 22CD C8 01272 RET Z ;Ret if closing quote 22CE 2B 01273 DEC HL ; else backup, set OK, 22CF AF 01274 XOR A ; then return 22D0 C9 01275 RET 22D1 C5 01276 HEX3 PUSH BC ;Exchange BC & HL 22D2 E3 01277 EX (SP),HL ; and save HL 22D3 29 01278 ADD HL,HL ;Multiply by 16 22D4 29 01279 ADD HL,HL 22D5 29 01280 ADD HL,HL 22D6 29 01281 ADD HL,HL 22D7 44 01282 LD B,H ;Merge new digit 22D8 85 01283 ADD A,L 22D9 4F 01284 LD C,A 22DA E1 01285 POP HL ;Recover pointer 22DB 18DA 01286 JR HEX1 ;Loop 01287 ; 22DD 43 01288 DFTEXT DB 'CMD' ;Default extension 4D 44 22E0 0A 01289 RDYMSG$ DB LF,14,'LS-DOS Ready',CR 0E 4C 53 2D 44 4F 53 20 52 65 61 64 79 0D 01290 ; ELSE 01291 ;RDYMSG$ DB LF,14,'TRSDOS Ready',CR 01292 ; ENDIF 22EF 01293 LAST EQU $ 01294 IFGT $,DIRBUF$ 01295 ERR 'Module too big' 01296 ENDIF 23FE 01297 ORG MAXCOR$-2 23FE EF04 01298 DW LAST-SYS1 ;Size of overlay 1E00 01299 END SYS1 1E00 is the transfer address 00000 Total errors
[Copyright 1999,2002 Frank Durda IV, All Rights Reserved. Mirroring of any material on this page in any form is expressly prohibited. The official web site for this material is: http://nemesis.lonestar.org Contact this address for use clearances: clearance at nemesis.lonestar.org Comments and queries to this address: web_software_2011 at nemesis.lonestar.org]