LS-DOS 6.3.1 - LOWCORE Assembly Listing (HTML format version)

[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/19/99 01:05:35 FREE - LS-DOS 6.2            Page 00001 

              00001 ;LBFREE/ASM - FREE Command
              00003 ;
0008          00004 TPL     EQU     8               ;Tracks per Line = 8
0002          00005 @DSP    EQU     2               ;@DSP SVC #
0006          00006 @PRT    EQU     6               ;@PRT SVC #
000A          00007 @DSPLY  EQU     10              ;@DSPLY SVC #
000E          00008 @PRINT  EQU     14              ;@PRINT SVC #
0001          00009 @KEY    EQU     1               ;@KEY SVC #
              00010 ;
0000          00011 *GET    BUILDVER/ASM:3
              00012 ;
              00013 ;       Buildver/asm is a bit of a kludge since not all utilities can load
              00014 ;       equates from LDOS60 and still compile.  LOWCORE and everybody else
              00015 ;       relies on this setting, and it eventually ends up in LDOS60/EQU
              00016 ;       for programs that can use that.
              00017 ;
FFFF          00018 @BLD631         EQU     -1      ;<631>Build 631 distribution (LEVEL 1B)
              00019 ;       These switches activate patches made since the 1B release.
              00020 ;       It is important that all earlier patches be enabled when a higher
              00021 ;       patch is enabled.
              00022 ;       Patches C thru F were published in TMQ IV.iv, page 32 (NOTE: the
              00023 ;       patch addresses listed for SPOOL in SPOOL1/FIX are 19H high.)
FFFF          00024 @BLD631C        EQU     -1      ;<631>Apply 1C patches (SETKI)
FFFF          00025 @BLD631D        EQU     -1      ;<631>Apply 1D patches (DIR)
FFFF          00026 @BLD631E        EQU     -1      ;<631>Apply 1E patches (DIR & MEMDISK/DCT)
FFFF          00027 @BLD631F        EQU     -1      ;<631>Apply 1F patches (SPOOL)
              00028 ;       Patches G and H were published in TMQ V.i, pages 10 and 18/19.
FFFF          00029 @BLD631G        EQU     -1      ;<631>Apply 1G patches (//KEYIN,DIR,DO *)
FFFF          00030 @BLD631H        EQU     -1      ;<631>Apply 1H patches (MEMORY)
              00031 ;
              00032 ;End of BUILDVER/ASM
0000          00033 *GET    SVCMAC:3                ;SVC Macro equivalents
              00034 ;SVCMAC/ASM - LS-DOS Version VI
              00035 *LIST   OFF
              00427 *LIST   ON
0000          00429 *GET    VALUES:3                ;Misc. equates
              00430 ;VALUES/ASM - Version 6
              00431 *LIST OFF
              00458 *LIST ON
              00459 ;
2400          00460         ORG     2400H
              00461 ;
2400          00462 FREEMAP EQU     $
              00463         IF      @BLD631
2400 ED731124 00464         LD      (SAVESP+1),SP   ;<631>Save SP address for exit
2404          00465         @@CKBRKC                ;<631>See if break down
2404+3E6A     00466         LD      A,106
2406+EF       00467         RST     40
2407 37       00468         SCF                     ;<631>
2408 2004     00469         JR      NZ,ABORT1       ;<631>Abort
240A CD2224   00470         CALL    FREE            ;<631>Show Free Space
240D AF       00471 EXIT:   XOR     A               ;<631>Clear Cflag
240E ED62     00472 ABORT1: SBC     HL,HL           ;<631>Depending on Cflag, exit 0000 or FFFF
2410 310000   00473 SAVESP: LD      SP,$-$          ;<631>P/u old SP address
2413          00474         @@CKBRKC                ;<631>Clear 
2413+3E6A     00475         LD      A,106
2415+EF       00476         RST     40
2416 C9       00477         RET                     ;<631>
              00478         ELSE
              00479 ;
              00480         @@CKBRKC                ;See if break down
              00481         JR      Z,BEGINA        ;Ok if not,
              00482         LD      HL,-1           ;  else abort
              00483         RET
              00484 ;
              00485 ;        not hit - execute module
              00486 ;
              00487 BEGINA
              00488         LD      (SAVESP+1),SP   ;Save SP address for exit
              00489         CALL    FREE            ;Show Free Space
              00490 ;
              00491 ;       Finished - Clear out  & return
              00492 ;
              00493 EXIT    LD      HL,0            ;HL = 0 (normal exit)
              00494 SAVESP  LD      SP,$-$          ;P/u old SP address
              00495         @@CKBRKC                ;Clear 
              00496         RET
              00497         ENDIF
              00498 ;
              00499 ;       Error Handler - Display message & Abort
              00500 ;
2417 6F       00501 IOERR   LD      L,A             ;Set HL = Error #
2418 2600     00502         LD      H,0
241A F6C0     00503         OR      0C0H            ;Short error - & RETurn
241C 4F       00504         LD      C,A             ;Stuff error # in C
241D          00505         @@ERROR                 ;Display error
241D+3E1A     00506         LD      A,26
241F+EF       00507         RST     40
2420 18EE     00508         JR      SAVESP          ;Exit
              00509 ;
              00510 ;       FREE - Display Free Disk Space
              00511 ;
              00512 FREE
2422          00513         @@FLAGS                 ;IY => System Flags
2422+3E65     00514         LD      A,101
2424+EF       00515         RST     40
              00516 ;
              00517 ;       Stuff Address of SFLAG$ into routine
              00518 ;
2425 111200   00519         LD      DE,SFLAG$       ;DE => Offset to SFLAG$
2428 FD19     00520         ADD     IY,DE           ;IY => SFLAG$
242A FD226726 00521         LD      (SFLAG1+1),IY   ;Save for later test
              00522 ;
              00523 ;       Position to parameters or end of line
              00524 ;
242E E5       00525         PUSH    HL              ;Save command ptr
242F 7E       00526 SKPLP   LD      A,(HL)          ;P/u char
2430 FE28     00527         CP      '('             ;Parameter(s) ?
2432 2807     00528         JR      Z,GETPRMS       ;Yes - get parameters
2434 FE0D     00529         CP      CR              ;End of line ?
2436 2809     00530         JR      Z,GETHL         ;Recover command ptr
2438 23       00531         INC     HL              ;Bump ptr
2439 18F4     00532         JR      SKPLP           ;No - go til terminator
              00533 ;
              00534 ;       Process any parameters if entered
              00535 ;
243B 111C28   00536 GETPRMS LD      DE,PRMTBL$      ;DE => Parameter table
243E          00537         @@PARAM                 ;@PARAM
243E+3E11     00538         LD      A,17
2440+EF       00539         RST     40
2441 E1       00540 GETHL   POP     HL              ;Recover cmdline ptr
2442 C21724   00541         JP      NZ,IOERR        ;NZ - parameter error
              00542 ;
              00543 ;       Anything after FREE command entered ?
              00544 ;
2445 7E       00545         LD      A,(HL)          ;P/u first character
2446 FE29     00546         CP      '('+1           ;End of line ?
2448 3811     00547         JR      C,FREE0         ;Display lines
              00548 ;
              00549 ;       P/u next character if character is a colon
              00550 ;
244A FE3A     00551         CP      ':'             ;Drivspec ?
244C 2002     00552         JR      NZ,CKIFDRV      ;No - check if numeric
244E 23       00553         INC     HL              ;Yes - p/u next char
244F 7E       00554         LD      A,(HL)
              00555 ;
              00556 ;       Convert drive # to binary (if legal) & save
              00557 ;
2450 D630     00558 CKIFDRV SUB     '0'             ;Legal drive Number ?
              00559         IF      @BLD631
              00560         ELSE
              00561         JR      C,ILDRNUM       ;No - illegal drive #
              00562         ENDIF
2452 FE08     00563         CP      7+1
2454 383B     00564         JR      C,MAP           ;Less than 8 - good
              00565 ;
              00566 ;       Illegal Drive Number - display & Abort
              00567 ;
2456 3E20     00568 ILDRNUM LD      A,32            ;"Illegal Drive Number"
2458 C31724   00569         JP      IOERR           ;Display & Abort
              00570 ;
              00571 ;       Output a C/R to *PR if output is to *PR
              00572 ;
245B 2A4626   00573 FREE0   LD      HL,(PPARM+1)    ;P/u P parm
245E 2C       00574         INC     L               ;Specified ?
245F 200A     00575         JR      NZ,FREE0A       ;No - don't PRINT
2461 0E20     00576         LD      C,' '           ;Output space
2463 CD3F27   00577         CALL    PRT             ;  to printer
2466 0E0D     00578         LD      C,CR            ;Output C/R
2468 CD3F27   00579         CALL    PRT             ;  to printer
246B 0E00     00580 FREE0A  LD      C,0             ;Init drive # to 0
              00581 ;
              00582 ;       Is there a disk in the drive ?
              00583 ;
246D C5       00584 FREE1   PUSH    BC              ;Save drive #
246E          00585         @@GTDCT                 ;IY => DCT
246E+3E51     00586         LD      A,81
2470+EF       00587         RST     40
2471 FD7E00   00588         LD      A,(IY)          ;Drive on line ?
2474 FEC3     00589         CP      0C3H
2476 2012     00590         JR      NZ,NXTDRV       ;No - get next drive
2478          00591         @@CKDRV                 ;Disk in drive ?
2478+3E21     00592         LD      A,33
247A+EF       00593         RST     40
              00594 ;
              00595 ;       Check if the  was hit
              00596 ;
247B F5       00597         PUSH    AF              ;Save @CKDRV condition
247C CD7D26   00598         CALL    CKBREAK         ;Check 
247F F1       00599         POP     AF              ;Recover @CKDRV cond
              00600 ;
              00601 ;       Display  if @CKDRV fails
              00602 ;
2480 2805     00603         JR      Z,DOINF         ;Disk in - use header
2482 CD4E26   00604         CALL    NO_DISK         ;No - display 
2485 1803     00605         JR      NXTDRV          ;Get next drive
              00606 ;
              00607 ;       Create Header String & display if successful
              00608 ;
2487 CD0F25   00609 DOINF   CALL    GETINFO         ;Display Header string
              00610 ;
              00611 ;       Get next drive number
              00612 ;
248A C1       00613 NXTDRV  POP     BC              ;C = Drive #
248B 0C       00614         INC     C               ;Inc it
248C CB59     00615         BIT     3,C             ;Finished ?
248E 28DD     00616         JR      Z,FREE1         ;No - get next drive
2490 C9       00617         RET                     ;Finished - RETurn
              00618 ;
              00619 ;       MAP - Display Free Space Map
              00620 ;
              00621 ;       Log in diskette if possible
              00622 ;
2491 4F       00623 MAP     LD      C,A             ;Xfer drive # to C
2492          00624         @@GTDCT                 ;IY => DCT + 0
2492+3E51     00625         LD      A,81
2494+EF       00626         RST     40
2495 FD7E00   00627         LD      A,(IY)          ;P/u enable/disable
2498 FEC3     00628         CP      0C3H            ;Drive enabled ?
249A C25624   00629         JP      NZ,ILDRNUM      ;No - Illegal Drive #
249D          00630         @@CKDRV                 ;Disk in drive ?
249D+3E21     00631         LD      A,33
249F+EF       00632         RST     40
24A0 2806     00633         JR      Z,DISKIN        ;Good - Disk in Drive
              00634 ;
              00635 ;       No Disk in Drive - Display message & Abort
              00636 ;
24A2 CD4E26   00637         CALL    NO_DISK         ;Display 
24A5 C30D24   00638         JP      EXIT            ;Go to exit routine
              00639 ;
              00640 ;       Create header/footer strings & output header
              00641 ;
24A8 CD7D26   00642 DISKIN  CALL    CKBREAK         ;Check for 
24AB CD0F25   00643         CALL    GETINFO         ;Get GAT, create header
24AE CDD926   00644         CALL    DISPUND         ;Display underline
24B1 CD6F26   00645         CALL    CLRLN           ;Clear Line buffer
              00646 ;
              00647 ;       Transfer "  0-  7" string to line buffer
              00648 ;
24B4 215827   00649         LD      HL,MTRK         ;Initial track #s
24B7 11002B   00650         LD      DE,LINBUF
24BA 010700   00651         LD      BC,7            ;Len track # display
24BD EDB0     00652         LDIR
              00653 ;
              00654 ;       Pt HL => GAT+0, C = cylinder -1 (gets INCed)
              00655 ;
24BF 210029   00656         LD      HL,GAT          ;Pt to stored GAT
24C2 0D       00657         DEC     C               ;Init Cyl = -1
              00658 ;
              00659 ;       Loop to Display each line of Cylinders
              00660 ;
24C3 0608     00661 NEXTLIN LD      B,TPL           ;Max track per line count
24C5 DD21082B 00662         LD      IX,LINBUF+8     ;Pt to display buffer
              00663 ;
              00664 ;       Bump cylinder number & display Gran info
              00665 ;
24C9 0C       00666 DSPSC   INC     C               ;Current cylinder
24CA CD9726   00667         CALL    DFRE            ;Display Free grans
24CD 23       00668         INC     HL              ;Pt to next track
              00669 ;
              00670 ;       Finished Displaying all the cylinders ?
              00671 ;
24CE FD7E06   00672         LD      A,(IY+6)        ;P/u max cylinder
24D1 B9       00673         CP      C               ;Finished ?
24D2 281D     00674         JR      Z,ENDRET        ;Yes - display footer
              00675 ;
              00676 ;       Calculate offset (9-Grans/cyl) to next track
              00677 ;
24D4 3A9926   00678         LD      A,(GRANS+1)     ;P/u Grans/Cyl
24D7 ED44     00679         NEG
24D9 C609     00680         ADD     A,TPL+1         ;A = offset to next
              00681 ;
              00682 ;       Add offset to Line buffer pointer (IX)
              00683 ;
24DB 1600     00684         LD      D,0             ;Stuff in DE
24DD 5F       00685         LD      E,A
24DE DD19     00686         ADD     IX,DE           ;Where to dsp next track
24E0 10E7     00687         DJNZ    DSPSC           ;Loop current 6 trks
              00688 ;
              00689 ;       Finished 8 cylinders - display line
              00690 ;
24E2 E5       00691         PUSH    HL              ;Save buffer loc'n
24E3 C5       00692         PUSH    BC              ;Save current cyl
24E4 CD3C26   00693         CALL    DSPLINE         ;Display current line
              00694 ;
              00695 ;       Clear granule display line buffer
              00696 ;
24E7 CD6F26   00697         CALL    CLRLN           ;Clear Line buffer
24EA C1       00698         POP     BC              ;Recover cylinder # in C
              00699 ;
              00700 ;       Change cylinder numbers in line buffer
              00701 ;
24EB CDE126   00702         CALL    DSPTRK          ;Calc new track #'s
24EE E1       00703         POP     HL              ;Restore GAT pointer
24EF 18D2     00704         JR      NEXTLIN         ;Get next line
              00705 ;
              00706 ;       Finished with drive - Display current line
              00707 ;
24F1 CD3C26   00708 ENDRET  CALL    DSPLINE         ;Display tracks in buffer
24F4 CDD926   00709         CALL    DISPUND         ;Display underline
              00710 ;
              00711 ;       Display Footer Message
              00712 ;
24F7 21AF27   00713         LD      HL,FOOTER       ;HL => Footer Message
24FA CD3F26   00714         CALL    DSPMSG          ;Display footer string
              00715 ;
              00716 ;       If footer will cause a scroll - wait for key
              00717 ;
24FD 3A5B26   00718         LD      A,(CKPAGE+1)    ;P/u # of lines left
2500 FE02     00719         CP      2               ;At least 2 lines left?
2502 3003     00720         JR      NC,FRET         ;Lprint, free to return
2504 CD3327   00721         CALL    KEY             ;Wait for char
2507 360D     00722 FRET    LD      (HL),CR         ;Scroll
2509 CD3F26   00723         CALL    DSPMSG          ;Display line
250C C30D24   00724         JP      EXIT            ;Go to normal exit
              00725 ;
              00726 ;       Stuff Drive Number into String Header
              00727 ;
250F 79       00728 GETINFO LD      A,C             ;P/u drive #
2510 C630     00729         ADD     A,'0'           ;Convert to ASCII
2512 326627   00730         LD      (HDRIVE),A      ;Stuff into header string
              00731 ;
              00732 ;       Read in the diskette's GAT
              00733 ;
2515          00734         @@GTDCT                 ;IY => DCT+0
2515+3E51     00735         LD      A,81
2517+EF       00736         RST     40
2518 FD5609   00737         LD      D,(IY+9)        ;P/u Directory cylinder
251B 1E00     00738         LD      E,0             ;Sector Zero
251D 210029   00739         LD      HL,GAT          ;HL => GAT I/O buffer
2520          00740         @@RDSSC                 ;Read System Sector
2520+3E55     00741         LD      A,85
2522+EF       00742         RST     40
2523 3E14     00743         LD      A,14H           ;Init to "GAT Read Error"
2525 C21724   00744 DERR    JP      NZ,IOERR        ;Jump on GAT read error
2528 CD7D26   00745         CALL    CKBREAK         ;Check for 
              00746 ;
              00747 ;       Read in the diskette's HIT
              00748 ;
252B 1C       00749         INC     E               ;Sector 1
252C 24       00750         INC     H               ;HL => HIT I/O buffer
252D          00751         @@RDSSC                 ;Read System Sector
252D+3E55     00752         LD      A,85
252F+EF       00753         RST     40
2530 3E16     00754         LD      A,16H           ;Init to "HIT Read Error"
2532 20F1     00755         JR      NZ,DERR         ;Go to Error handler
2534 CD7D26   00756         CALL    CKBREAK         ;Check for 
              00757 ;
              00758 ;       Pick up quantity of Sectors/Granule
              00759 ;
2537 FD7E08   00760         LD      A,(IY+8)        ;Bits 4-0 contain #
253A E61F     00761         AND     1FH             ;  of Sectors/Granule.
253C 3C       00762         INC     A               ;Adjust for zero offset
              00763 ;
              00764 ;       Convert Sectors/Gran to K & stuff in string
              00765 ;
253D F5       00766         PUSH    AF              ;Save Sectors/Granule
253E 210000   00767         LD      HL,0            ;Set HLA = # Sec/Gran
2541 11F827   00768         LD      DE,FGRAN        ;DE => Destination
2544 018526   00769         LD      BC,CVT2D        ;Only 2 digits possible
2547 CD1027   00770         CALL    CALCK2          ;Convert to K
254A F1       00771         POP     AF              ;A = Sectors/Granule
254B 5F       00772         LD      E,A             ;Xfer to E
              00773 ;
              00774 ;       Pick up number of cylinders in HL
              00775 ;
254C FD6E06   00776         LD      L,(IY+6)        ;P/u # of cylinders
254F 2600     00777         LD      H,0             ;Msb = 0
2551 23       00778         INC     HL              ;Relative to zero
              00779 ;
              00780 ;       Calculate quantity of Granules/Cylinder
              00781 ;
2552 F5       00782         PUSH    AF              ;Save # of sectors/gran
2553 FD7E08   00783         LD      A,(IY+8)        ;Bits 7-5 contain
2556 E6E0     00784         AND     0E0H            ;  # of Granules/cylinder.
2558 07       00785         RLCA                    ;& shift to bits 0-2
2559 07       00786         RLCA
255A 07       00787         RLCA
255B 3C       00788         INC     A               ;Adjust for zero offset
255C FDCB046E 00789         BIT     5,(IY+4)        ;Double sided?
2560 2801     00790         JR      Z,FREE2         ;Bypass if one-sided
2562 87       00791         ADD     A,A             ;Else double the count
2563 329926   00792 FREE2   LD      (GRANS+1),A     ;Save # Grans/Cyl
2566 4F       00793         LD      C,A             ;Save in C for @MULT8
              00794 ;
              00795 ;       Calculate quantity of Sectors/Cylinder
              00796 ;
2567          00797         @@MUL8                  ;Mult E x C
2567+3E5A     00798         LD      A,90
2569+EF       00799         RST     40
              00800 ;
              00801 ;       A = quantity of Sectors per cylinder
              00802 ;
256A F5       00803         PUSH    AF              ;Save # Sectors/Cyl
256B E5       00804         PUSH    HL              ;Save # Cylinders
              00805 ;
              00806 ;       File slots avail = 256 if more than 32 secs
              00807 ;
256C 210001   00808         LD      HL,256          ;256 files maximum
256F D602     00809         SUB     2               ;Set A = # secs in dir
2571 FE20     00810         CP      20H             ;  Greater than 32 ?
2573 3006     00811         JR      NC,FREE3        ;Yes - use default of 256
              00812 ;
              00813 ;       Calculate number of directory entries avail
              00814 ;
2575 87       00815         ADD     A,A             ;Multiply # of Sectors
2576 87       00816         ADD     A,A             ;  in directory by 8
2577 87       00817         ADD     A,A             ;  to get # of slots.
2578 6F       00818         LD      L,A             ;Stuff in HL
2579 2600     00819         LD      H,0
257B 221726   00820 FREE3   LD      (FREE7+1),HL    ;File slots to test later
              00821 ;
              00822 ;       Stuff # of entries (HL) into header string
              00823 ;
257E 11AB27   00824         LD      DE,HPOSSF       ;DE => Destination
2581 CD8926   00825         CALL    CVT3D           ;Cvt HL to ASCII @ DE
2584 E1       00826         POP     HL              ;Recover # of cylinders
2585 F1       00827         POP     AF              ;Rcvr # of sectors/cyl
              00828 ;
              00829 ;       Calculate total # of sectors HL x A
              00830 ;
2586 4F       00831         LD      C,A             ;Set C = Sec/cyl
2587 B7       00832         OR      A
2588 2803     00833         JR      Z,SKIPMUL       ;Don't multiply if zero
258A          00834         @@MUL16                 ;Multiply HL x C
258A+3E5B     00835         LD      A,91
258C+EF       00836         RST     40
              00837 ;
              00838 ;       Convert # of sectors to K & stuff in string
              00839 ;
258D 119427   00840 SKIPMUL LD      DE,HPOSSK       ;DE => Destination
2590 CD0D27   00841         CALL    CALCK           ;Stuff into string
              00842 ;
              00843 ;       Transfer Diskette Name from GAT into string
              00844 ;
2593 21D029   00845         LD      HL,GAT+0D0H     ;HL => Pack Name
2596 116927   00846         LD      DE,HNAME        ;DE => String destination
2599 0E08     00847         LD      C,8             ;8 chars to xfer
259B EDB0     00848         LDIR                    ;Xfer into string
              00849 ;
              00850 ;       Transfer Diskette Date from GAT into string
              00851 ;
259D 117327   00852         LD      DE,HDATE        ;DE => Destination
25A0 0E08     00853         LD      C,8             ;8 chars to xfer
25A2 EDB0     00854         LDIR                    ;Xfer to string
              00855 ;
              00856 ;       Pt HL => GAT, DE = Free Gran cnt, B = cyls
              00857 ;
25A4 210029   00858         LD      HL,GAT          ;Pt to start of GAT
              00859         IF      @BLD631
25A7 50       00860         LD      D,B             ;<631>Init gran counter (B=0)
25A8 58       00861         LD      E,B             ;<631>(B=0)
              00862         ELSE
              00863         LD      DE,0            ;Init gran counter
              00864         ENDIF
25A9 3ACC29   00865         LD      A,(GAT+0CCH)    ;P/u cyl excess
25AC C623     00866         ADD     A,35            ;Add base
25AE 47       00867         LD      B,A             ;Set loop counter
              00868 ;
              00869 ;       Calculate quantity of Free granules left
              00870 ;
25AF 7E       00871 FREE4   LD      A,(HL)          ;P/u GAT byte & set
25B0 37       00872 FREE5   SCF                     ;  carry so bit 7 stays 1
              00873 ;
              00874 ;       Is the granule in use ?
              00875 ;
25B1 1F       00876         RRA                     ;Slide gran bit to carry
25B2 3801     00877         JR      C,FREE6         ;Ignore if in use
              00878 ;
              00879 ;       Free Granule - Bump Free Granule count
              00880 ;
25B4 13       00881         INC     DE              ;Free, bump gran counter
25B5 FEFF     00882 FREE6   CP      0FFH            ;End of byte?
25B7 20F7     00883         JR      NZ,FREE5        ;Loop if not
              00884 ;
              00885 ;       Finished with one cylinder, advance to next
              00886 ;
25B9 2C       00887         INC     L               ;Bump GAT byte pointer
25BA 10F3     00888         DJNZ    FREE4           ;Loop for # cyls
              00889 ;
              00890 ;       Multiply # Grans (DE) by Sectors/Gran
              00891 ;
25BC EB       00892         EX      DE,HL           ;Xfer # Grans to HL
25BD F1       00893         POP     AF              ;Rcvr # of sectors/gran
25BE 4F       00894         LD      C,A             ;Put in C for @MUL16
25BF          00895         @@MUL16                 ;Multiply HL x C
25BF+3E5B     00896         LD      A,91
25C1+EF       00897         RST     40
              00898 ;
              00899 ;       Cvt # of Free Grans to K & stuff in string
              00900 ;
25C2 118A27   00901         LD      DE,HFREEK       ;Cvrt to decimal
25C5 CD0D27   00902         CALL    CALCK           ;Cvrt to ASCII & stuff
              00903 ;
              00904 ;       Build Footer String in case of map
              00905 ;
25C8 3E35     00906         LD      A,'5'           ;Init 5"/8" media
25CA FDCB036E 00907         BIT     5,(IY+3)        ;Test DCT for size
25CE 2802     00908         JR      Z,FIVEIN        ;Go if 5"
25D0 3E38     00909         LD      A,'8'           ;Else reset to 8"
25D2 32B827   00910 FIVEIN  LD      (FSIZE),A       ;Stuff size into header
              00911 ;
              00912 ;       P/u # of heads from DCT & stuff into footer
              00913 ;
25D5 FD7E07   00914         LD      A,(IY+7)        ;Bits 7-5 = # heads
25D8 07       00915         RLCA                    ;Shift to 0-2
25D9 07       00916         RLCA
25DA 07       00917         RLCA
25DB E607     00918         AND     7               ;Mask off other junk
25DD 3C       00919         INC     A               ;Relative to zero
25DE F630     00920         OR      '0'             ;Make it ASCII
25E0 32CD27   00921         LD      (FHEADS),A      ;Stuff into header
              00922 ;
              00923 ;       If this is a hard drive - ignore sides check
              00924 ;
25E3 FDCB035E 00925         BIT     3,(IY+3)        ;Check if hard
25E7 2810     00926         JR      Z,DOSIDES       ;Not hard - check sides
              00927 ;
              00928 ;       Hard Drive - overwrite Floppy in footer
              00929 ;
25E9 215227   00930         LD      HL,HARD         ;HL => "Hard  "
25EC 11BB27   00931         LD      DE,FTYPE        ;DE => Dest in footer
25EF 010600   00932         LD      BC,6            ;BC = 6 chars to xfer
25F2 EDB0     00933         LDIR                    ;Transfer to footer
25F4 214C27   00934         LD      HL,RIGID        ;HL => "RIGID"
25F7 1815     00935         JR      D3              ;Xfer "RIGID" to footer
              00936 ;
              00937 ;       Floppy disk - Stuff # of sides into footer
              00938 ;
25F9 3E31     00939 DOSIDES LD      A,'1'           ;Init # of sides
25FB FDCB046E 00940         BIT     5,(IY+4)        ;Test DCT for sides
25FF 2801     00941         JR      Z,ONESIDE       ;Go if 1-sides
2601 3C       00942         INC     A               ;Else bump to 2
2602 32CD27   00943 ONESIDE LD      (FHEADS),A      ;Stuff into header
              00944 ;
              00945 ;       If floppy is double density pt HL to string
              00946 ;
2605 FDCB0376 00947         BIT     6,(IY+3)        ;Test SDEN/DDEN
2609 280B     00948         JR      Z,FREE7         ;Single - that's default
260B 214627   00949         LD      HL,MDDEN        ;Density MSG - Double
              00950 ;
              00951 ;       Xfer "Single, Double, or Rigid" to footer
              00952 ;
260E 11DB27   00953 D3      LD      DE,FDENS        ;Density MSG dsp pos
2611 010600   00954         LD      BC,6            ;6 chars to xfer
2614 EDB0     00955         LDIR                    ;Move Double to cover
              00956 ;
              00957 ;       Calculate # of Free HIT positions available
              00958 ;
2616 110000   00959 FREE7   LD      DE,$-$          ;P/u # of poss entries
2619 21002A   00960         LD      HL,HIT          ;HL => HIT + 0
261C 1B       00961 FREE8   DEC     DE              ;Dec count in case of SYS
              00962 ;
              00963 ;       Check SYS slots if this is a data disk
              00964 ;
261D 3ACD29   00965         LD      A,(GAT+0CDH)    ;Bit 7 set if Data disk
2620 07       00966         RLCA
2621 3805     00967         JR      C,DATDISK       ;Set - ignore SYS check
              00968 ;
              00969 ;       Is this a SYS slot - 00-07 or 20-27 ?
              00970 ;
2623 7D       00971         LD      A,L             ;P/u HIT offset
2624 E6D8     00972         AND     0D8H            ;Reserved slot ?
2626 2805     00973         JR      Z,FREE9         ;Yes - can't use it
              00974 ;
              00975 ;       Not reserved - is the HIT posn in use ?
              00976 ;
2628 7E       00977 DATDISK LD      A,(HL)          ;File in use?
2629 B7       00978         OR      A
262A 2001     00979         JR      NZ,FREE9        ;Yes - don't bump count
              00980 ;
              00981 ;       Slot not in use - bump free slot count
              00982 ;
262C 13       00983         INC     DE              ;Bump free count
262D 2C       00984 FREE9   INC     L               ;Bump HIT pointer
262E 20EC     00985         JR      NZ,FREE8        ;Loop if not through
              00986 ;
              00987 ;       Stuff available files into string
              00988 ;
2630 EB       00989         EX      DE,HL           ;Available files to HL
2631 11A727   00990         LD      DE,HFREEF       ;Cvrt to ASCII into msg
2634 CD8926   00991         CALL    CVT3D           ;Convert & RETurn
              00992 ;
              00993 ;       Display Header String & RETurn
              00994 ;
2637 215F27   00995         LD      HL,HEADER       ;HL => Header string
263A 1803     00996         JR      DSPMSG          ;Display header & RETurn
              00997 ;
263C 21002B   00998 DSPLINE LD      HL,LINBUF       ;Fall into Display & RET
              00999 ;
              01000 ;       DSPMSG - Display a message pointed to by HL 
              01001 ;
263F CD7D26   01002 DSPMSG  CALL    CKBREAK         ;Check for 
2642 CD3927   01003         CALL    DSPLY           ;Display message to video
2645 110000   01004 PPARM   LD      DE,$-$          ;P/u P parm
2648 1C       01005         INC     E               ;Was it entered ?
2649 200F     01006         JR      NZ,CKPAGE       ;No - Check page pause
264B C33C27   01007         JP      PRINT           ;Output line to *PR
              01008 ;
264E 79       01009 NO_DISK LD      A,C             ;P/u drive #
264F C630     01010         ADD     A,'0'           ;Cvt to ASCII
2651 320628   01011         LD      (NODISKN),A     ;Stuff in string
2654 21FF27   01012         LD      HL,NODISK       ;HL => Message
2657 C33F26   01013         JP      DSPMSG          ;Display Mess & RETurn
              01014 ;
              01015 ;       Decrement Lines printed count
              01016 ;
265A 3E16     01017 CKPAGE  LD      A,22            ;Ck for display pause
265C 3D       01018         DEC     A               ;Count down
265D 325B26   01019         LD      (CKPAGE+1),A    ;Update
2660 C0       01020         RET     NZ              ;Ret if not yet full
              01021 ;
              01022 ;       Printed a full page - Reset to count to max
              01023 ;
2661 3E17     01024         LD      A,23            ;Max lines to print
2663 325B26   01025         LD      (CKPAGE+1),A    ;Reset to max
              01026 ;
              01027 ;       Do not stop if a  is in effect
              01028 ;
2666 3A0000   01029 SFLAG1  LD      A,($-$)         ;P/u SFLAG$
2669 E620     01030         AND     20H             ;Do in effect ?
266B C0       01031         RET     NZ              ;Yes - RETurn
              01032 ;
              01033 ;       Wait for key - then clear screen
              01034 ;
266C CD3327   01035         CALL    KEY             ;Wait for key entry
              01036 DISPHDR:
              01037 ;
              01038 ;       Display Map header
              01039 ;
              01040 ;       LD      HL,HEADER       ;Point to the header
              01041 ;       CALL    DSPMSG          ;  & display it
              01042 ;       CALL    DISPUND         ;Display underline
              01043 ;
              01044 ;       CLRLN - Clear line buffer
              01045 ;
266F 3E20     01046 CLRLN   LD      A,' '           ;Clear buffer
2671 21002B   01047 BUFSTUF LD      HL,LINBUF       ;Point to buffer
2674 064F     01048         LD      B,79            ;Length of buffer
2676 77       01049 CLRLN1  LD      (HL),A          ;Stuff with char given
2677 23       01050         INC     HL
2678 10FC     01051         DJNZ    CLRLN1
267A 360D     01052         LD      (HL),CR         ;End line with C/R
267C C9       01053         RET
              01054 ;
              01055 ;       CKBREAK - Check if the  was pressed
              01056 ;
267D          01057 CKBREAK EQU     $
267D          01058         @@CKBRKC                ; hit ?
267D+3E6A     01059         LD      A,106
267F+EF       01060         RST     40
2680 C8       01061         RET     Z               ;No - RETurn
              01062         IF      @BLD631
2681 37       01063 ABORT   SCF                     ;<631> hit - abort
2682 C30E24   01064         JP      ABORT1          ;<631>Make HL = -1
              01065         ELSE
              01066 ABORT   LD      HL,-1           ; hit - abort
              01067         JP      SAVESP
              01068         ENDIF
              01069 ;
              01070 ;
              01071 ;       CVTDEC - Convert Hex Number to Decimal ASCII
              01072 ;       CVD2D - CVD4D  - Convert to 2,3, or 4 digits
              01073 ;
              01074 ;       HL => Hex Number to Convert
              01075 ;       DE => Buffer to receive characters
              01076 ;
              01077         IF      @BLD631
2685 0602     01078 CVT2D   LD      B,2             ;<631>
2687 180A     01079         JR      CVTDEC          ;<631>
2689 0603     01080 CVT3D   LD      B,3             ;<631>
268B 1806     01081         JR      CVTDEC          ;<631>
268D 0604     01082 CVT4D   LD      B,4             ;<631>
268F 1802     01083         JR      CVTDEC          ;<631>
2691 0605     01084 CVT5D   LD      B,5             ;<631>
2693 3E5F     01085 CVTDEC  LD      A,5FH           ;<631>HEXD
2695 EF       01086         RST     28H             ;<631>
2696 C9       01087         RET                     ;<631>
              01088         ELSE
              01089 CVT2D   LD      A,' '
              01090         JR      CVT10
              01091 CVT3D   LD      A,' '
              01092         JR      CVT100
              01093 CVD4D   LD      A,' '
              01094         JR      CVT1000
              01095 CVTDEC  LD      A,' '
              01096 ;
              01097         LD      BC,10000
              01098         CALL    CVD1
              01099 CVT1000 LD      BC,1000
              01100         CALL    CVD1
              01101 CVT100  LD      BC,100
              01102         CALL    CVD1
              01103 CVT10   LD      BC,10
              01104         CALL    CVD1
              01105         LD      A,L
              01106         ADD     A,'0'
              01107         LD      (DE),A
              01108         INC     DE
              01109         RET
              01110 ;
              01111 CVD1    PUSH    DE
              01112         LD      E,A
              01113         LD      D,0FFH
              01114         XOR     A
              01115 CVD2    INC     D
              01116         SBC     HL,BC
              01117         JR      NC,CVD2
              01118         ADD     HL,BC
              01119         LD      A,E
              01120         LD      B,D
              01121         POP     DE
              01122         LD      (DE),A
              01123         INC     B
              01124         DEC     B
              01125         JR      Z,CVD3
              01126         LD      A,B
              01127         ADD     A,'0'
              01128         LD      (DE),A
              01129         LD      A,'0'
              01130 CVD3    INC     DE
              01131         RET
              01132         ENDIF
              01133 ;
              01134 ;       DFRE - Stuff a cylinder's Gran symbols in buffer
              01135 ;
              01136 ;       IX => Buffer to receive characters
              01137 ;       HL => GAT cylinder byte to use
              01138 ;
2697 C5       01139 DFRE    PUSH    BC              ;Save C, cur cyl loc
2698 0600     01140 GRANS   LD      B,$-$           ;P/u Grans/Cylinder
              01141 ;
              01142 ;       Is this cylinder the directory ?
              01143 ;
269A FD7E09   01144         LD      A,(IY+9)        ;P/u dir cyl from DCT
269D B9       01145         CP      C               ;Directory ?
269E 282F     01146         JR      Z,DDIR          ;Yes - use "D"'s
              01147 ;
              01148 ;       Not the directory cyl - use "x", "." & "*"
              01149 ;
26A0 DDE5     01150         PUSH    IX              ;Save buffer pointer
26A2 C5       01151         PUSH    BC              ;Save Grans/Cyl
              01152 ;
              01153 ;       Is the Granule in use ?
              01154 ;
26A3 CB0E     01155 DF1     RRC     (HL)            ;P/u next Granule
26A5 3E78     01156         LD      A,'x'           ;Init "in use"
26A7 3802     01157         JR      C,DF2           ;Set - use "x"
              01158 ;
              01159 ;       Granule isn't in use - stuff a "." in buffer
              01160 ;
26A9 3E2E     01161         LD      A,'.'           ;Else free
26AB DD7700   01162 DF2     LD      (IX+0),A        ;Stuff char
              01163 ;
              01164 ;       Bump buffer pointer & decrement G/C count
              01165 ;
26AE DD23     01166         INC     IX              ;Next display loc
26B0 10F1     01167         DJNZ    DF1             ;Loop thru all grans
              01168 ;
              01169 ;       Recover Buff ptr, Grans/Cyl
              01170 ;
26B2 C1       01171         POP     BC              ;B = Grans per Cyl
26B3 DDE1     01172         POP     IX              ;IX to start of track
              01173 ;
              01174 ;       Position HL to Lockout table
              01175 ;
26B5 E5       01176         PUSH    HL              ;Save Cyl ptr
26B6 116000   01177         LD      DE,60H          ;Offset to lockout table
26B9 19       01178         ADD     HL,DE           ;Point to lockout
              01179 ;
              01180 ;       Go through lockout & overwrite if locked out
              01181 ;
26BA FDCB035E 01182 LO1     BIT     3,(IY+3)        ;If hard drive, there's
26BE 2008     01183         JR      NZ,LO2          ;  no lockout
              01184 ;
              01185 ;       Diskette is a floppy - Is gran locked out ?
              01186 ;
26C0 CB0E     01187         RRC     (HL)            ;Gran locked out ?
26C2 3004     01188         JR      NC,LO2          ;No - bump buff ptr
26C4 DD36002A 01189         LD      (IX+0),'*'      ;Asterisk = lockout
              01190 ;
              01191 ;       Bump buffer pointer & loop til done
              01192 ;
26C8 DD23     01193 LO2     INC     IX              ;Next gran dsp loc
26CA 10EE     01194         DJNZ    LO1             ;B grans/cyl
              01195 ;
              01196 ;       Recover ptrs & RETurn
              01197 ;
26CC E1       01198         POP     HL
26CD C1       01199         POP     BC
26CE C9       01200         RET
              01201 ;
              01202 ;       DDIR - Use "D"'s for Directory instead of "x"
              01203 ;
26CF DD360044 01204 DDIR    LD      (IX+0),'D'      ;Stuff "D" char
26D3 DD23     01205         INC     IX              ;Loop thru all DIR grans
26D5 10F8     01206         DJNZ    DDIR
26D7 C1       01207         POP     BC
26D8 C9       01208         RET
              01209 ;
              01210 ;       DISPUND - Display a line of "-"
              01211 ;
26D9 3E2D     01212 DISPUND LD      A,'-'           ;Character to underline
26DB CD7126   01213         CALL    BUFSTUF         ;Stuff line & display
26DE C33C26   01214         JP      DSPLINE         ;Display line
              01215 ;
              01216 ;       DSPTRK - Stuff cylinder numbers in line buffer
              01217 ;
26E1 D5       01218 DSPTRK  PUSH    DE              ;Save registers used
26E2 C5       01219         PUSH    BC
              01220 ;
              01221 ;       Stuff starting cylinder # in line buffer
              01222 ;
26E3 11002B   01223         LD      DE,LINBUF       ;Display buffer
26E6 0C       01224         INC     C               ;Bump to next cylinder
26E7 CD0427   01225         CALL    DSPTK4          ;Display cylinder number
              01226 ;
              01227 ;       Is this the only cylinder in the line ?
              01228 ;
26EA FD7E06   01229         LD      A,(IY+6)        ;P/u maximum # cyls
26ED B9       01230         CP      C               ;Are we at the top?
26EE 2811     01231         JR      Z,DSPTK3        ;Go if yes
              01232 ;
              01233 ;       More than 1 cyl - stuff "-" in line buffer
              01234 ;
26F0 F5       01235         PUSH    AF              ;Save max cylinder
26F1 3E2D     01236         LD      A,'-'           ;Stuff dash in buffer
26F3 12       01237         LD      (DE),A
26F4 F1       01238         POP     AF              ;Recover max cylinder
              01239 ;
              01240 ;       Get ending cylinder # for this line in C
              01241 ;
26F5 13       01242         INC     DE              ;Position to next avail
26F6 0607     01243         LD      B,TPL-1         ;Need 7 more on a line
              01244 ;
26F8 0C       01245 DSPTK1  INC     C               ;Bump until 7 or max
26F9 B9       01246         CP      C
26FA 2802     01247         JR      Z,DSPTK2
26FC 10FA     01248         DJNZ    DSPTK1
              01249 ;
              01250 ;       Stuff ending cylinder # into line buffer
              01251 ;
26FE CD0427   01252 DSPTK2  CALL    DSPTK4          ;Stuff ending cyl on line
2701 C1       01253 DSPTK3  POP     BC              ;Recover registers
2702 D1       01254         POP     DE
2703 C9       01255         RET                     ;RETurn
              01256 ;
              01257 ;       Convert cylinder # (C) to ASCII at DE
              01258 ;
2704 69       01259 DSPTK4  LD      L,C             ;Xfer cylinder # to HL
2705 2600     01260         LD      H,0
2707 C5       01261         PUSH    BC              ;Save cylinder #
2708 CD8926   01262         CALL    CVT3D           ;Convert cyl# to ASCII
270B C1       01263         POP     BC              ;C = cylinder #
270C C9       01264         RET                     ;RETurn
              01265 ;
              01266 ;       CALCK - Calculate Number of K & stuff in string
              01267 ;       HLA => Total # of Sectors
              01268 ;       DE => Destination of String
              01269 ;
              01270         IF      @BLD631
270D 019126   01271 CALCK   LD      BC,CVT5D        ;<631>Select 5 digit
              01272         ELSE
              01273 CALCK   LD      BC,CVTDEC       ;4 digit default
              01274         ENDIF
2710 ED432027 01275 CALCK2  LD      (CONVERT+1),BC
2714 65       01276 DIVHLA  LD      H,L             ;Per disk pack
2715 6F       01277         LD      L,A
2716 CB3C     01278         SRL     H               ;Divide total sectors
2718 CB1D     01279         RR      L               ;  by 4 to calculate
271A CB3C     01280         SRL     H               ;  space in K
271C CB1D     01281         RR      L
              01282 ;
              01283 ;       Convert K free (HL) to ASCII & put in string
              01284 ;
271E F5       01285         PUSH    AF              ;Save offset
271F CD0000   01286 CONVERT CALL    $-$             ;Cvt HL to ASCII @ DE
2722 F1       01287         POP     AF              ;Recover offset
              01288 ;
              01289 ;       Stuff hundredths value into string
              01290 ;
2723 13       01291         INC     DE              ;Go past decimal point
2724 E603     01292         AND     3               ;Modulo 4
2726 87       01293         ADD     A,A             ;Multiply by 2
2727 0600     01294         LD      B,0             ;  to position to
2729 4F       01295         LD      C,A             ;  hundredths string
272A 211428   01296         LD      HL,HUNDTAB      ;HL => Table base
272D 09       01297         ADD     HL,BC           ;HL => Hundredths string
272E 0E02     01298         LD      C,2             ;2 chars to xfer
2730 EDB0     01299         LDIR                    ;Stuff in string
2732 C9       01300         RET                     ;RETurn
              01301 ;
              01302 ;       KEY/DSP/DSPLY/PRT/PRINT - SVC routines
              01303 ;
2733 3E01     01304 KEY     LD      A,@KEY          ;Wait for key
2735 11       01305         DB      11H
              01306 ;
2736 3E02     01307 DSP     LD      A,@DSP          ;Display byte
2738 11       01308         DB      11H             ;LD DE,nnnn
              01309 ;
2739 3E0A     01310 DSPLY   LD      A,@DSPLY        ;Display line
273B 11       01311         DB      11H
              01312 ;
273C 3E0E     01313 PRINT   LD      A,@PRINT        ;Print line
273E 11       01314         DB      11H
              01315 ;
273F 3E06     01316 PRT     LD      A,@PRT          ;Print byte
              01317 ;
2741 EF       01318 DO_OUT  RST     40              ;Do SVC & check error
2742 C8       01319         RET     Z               ;RETurn if good
2743 C31724   01320         JP      IOERR           ;NZ - I/O Error
              01321 ;
2746 44       01322 MDDEN   DB      'DOUBLE'
     4F 55 42 4C 45 
274C 52       01323 RIGID   DB      'RIGID '
     49 47 49 44 20 
2752 48       01324 HARD    DB      'Hard  '
     61 72 64 20 20 
              01325 ;
2758 20       01326 MTRK    DB      '  0-  7'
     20 30 2D 20 20 37 
              01327 ;
275F 44       01328 HEADER  DB      'Drive :'
     72 69 76 65 20 3A 
2766 64       01329 HDRIVE  DB      'd  '
     20 20 
2769 64       01330 HNAME   DB      'diskname  '
     69 73 6B 6E 61 6D 65 20
     20 
2773 64       01331 HDATE   DB      'dd/mm/yy   Free Space ='
     64 2F 6D 6D 2F 79 79 20
     20 20 46 72 65 65 20 53
     70 61 63 65 20 3D 
278A 6E       01332 HFREEK  DB      'nnnnn.nnK/'
     6E 6E 6E 6E 2E 6E 6E 4B
     2F 
2794 6E       01333 HPOSSK  DB      'nnnnn.nnK  Files = '
     6E 6E 6E 6E 2E 6E 6E 4B
     20 20 46 69 6C 65 73 20
     3D 20 
27A7 64       01334 HFREEF  DB      'ddd/'
     64 64 2F 
27AB 64       01335 HPOSSF  DB      'ddd',CR
     64 64 0D 
              01336 ;
27AF 54       01337 FOOTER  DB      'Type =>  '
     79 70 65 20 3D 3E 20 20
27B8 73       01338 FSIZE   DB      's" '
     22 20 
27BB 46       01339 FTYPE   DB      'Floppy    Heads = '
     6C 6F 70 70 79 20 20 20
     20 48 65 61 64 73 20 3D
     20 
27CD 6E       01340 FHEADS  DB      'n   Density = '
     20 20 20 44 65 6E 73 69
     74 79 20 3D 20 
27DB 53       01341 FDENS   DB      'SINGLE   Note - 1 Position = '
     49 4E 47 4C 45 20 20 20
     4E 6F 74 65 20 2D 20 31
     20 50 6F 73 69 74 69 6F
     6E 20 3D 20 
27F8 6E       01342 FGRAN   DB      'nn.nnK'
     6E 2E 6E 6E 4B 
27FE 0D       01343 ENDFOOT DB      CR
              01344 ;
27FF 44       01345 NODISK  DB      'Drive :'
     72 69 76 65 20 3A 
2806 64       01346 NODISKN DB      'd  [No  Disk]',CR
     20 20 5B 4E 6F 20 20 44
     69 73 6B 5D 0D 
              01347 ;
2814 30       01348 HUNDTAB DB      '00255075'
     30 32 35 35 30 37 35 
              01349 ;
              01350 ;       Parameter Table
              01351 ;
281C 80       01352 PRMTBL$ DB      80H
281D 41       01353         DB      FLAG!1
281E 50       01354         DB      'P'
281F 00       01355         DB      0
2820 4626     01356         DW      PPARM+1
2822 00       01357         NOP
              01358 ;
2900          01359         ORG     $<-8+1<+8
2900          01360 GAT     DS      256
2A00          01361 HIT     DS      256
2B00          01362 LINBUF  EQU     $
              01363 ;
2400          01364         END     FREEMAP
2400 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]

Valid HTML 4.01!