;BYE.ASM AS OF 02-OCT-80 ; ; CR == 0DH LF == 0AH EOF == 1AH ;CP/M EOF CHAR TAB == 9 ;TAB CHAR BANK == 0FDH ;PAGE BANK PORT ; ; --------> NOTE THE FOLLOWING <--------- ; ;THE FOLLOWING ADDRESS IS O-U-T-S-I-D-E ;OF THIS PROGRAM . THESE ADDRESSES POINT TO THE ;FIRSTNAME/LASTNAME STORED IN BIOS ; FNAME == 0F803H ;FIRSTNAME BUUFER LNAME == 0F817H ;LASTNAME BUUFER (IN BIOS) DKUPSW == 0F830H ;TEMP<<<<=======**** NOTE ** ; ; ; ROM CLOCK ROUTINES EQUATES ; ROM == 0F000H ; CLK0 == ROM+24 ;PRINT TIME/DATE CLK01 == ROM+27 ;PRINT TIME/DATE (CBBS) CLK1 == ROM+30 ;MOVE DATE -> (HL) CLK2 == ROM+33 ;MOVE TIME -> (HL) CLK3 == ROM+36 ;MOVE LOGIN TIME -> (HL) CLK4 == ROM+39 ;MOVE CONNECT TIME -> (HL) CLK5 == ROM+42 ;CALCULATE CONNECT TIME CLK6 == ROM+45 ;PRINT CONNECT TIME CLK7 == ROM+48 ;SET NOT LOGGED IN CLK8 == ROM+51 ;READ CLOCK CLK9 == ROM+54 ;PRINT ELAPSED TIME HANGUP == ROM+57 ;HANGUP (DISCONNECT MODEM) RDELAY == ROM+60 ;DELAY SUBROUTINE (=SECS.) ; .XLINK .PABS .PHEX .LOC 100H BYE: MVI A,1 STA DKUPSW ;SET DISK WRITE ACTIVE LXI SP,STACK MVI C,20H MVI E,0 ;SET USER 0 CALL BDOS MVI C,14 MVI E,0 CALL BDOS ;SELECT DRIVE A CALL CRLF CALL CLK01 ;PRINT DATE/TIME CALL CLK6 ;PRINT CONNECT TIME LXI H,LOGFL CALL EXTEND CALL WRCRLF LXI H,ET ;CONNECT TIME CALL CLK4 ;GET CONNECT TIME LXI H,ETMSG CALL WRVAR ;WRITE CPM CONNECT TIME ; CALL WRCRLF CALL WREOF ;WRITE EOF, CLOSE FILE ; BYEBYE: CALL ILPRT BYEMS: .ASCII [CR][LF] .ASCIZ |Thanks for calling | LXI H,FNAME MVI B,CR ;PRINT FIRST NAME CALL TYPEM CALL ILPRT .ASCII [CR][LF][LF] .ASCII |Please call again| .ASCII [CR][LF][LF] .ASCIZ |++DISCONNECTED++|[CR][LF] ; ;HANGUP THEN REBOOT BY ENTERING ROMON ; DISC: XRA A STA DKUPSW ;SET NO WRITE ACTIVE CALL HANGUP ;DISCONNECT MODEM JMP ROM ;JUMP TO ROM AND REBOOT ; ; TELLUS: CALL ILPRT .BYTE 7,7,7,7,CR,LF .ASCII |++AN ERROR OCCURRED++|[CR][LF][LF] .ASCII |Please call | .ASCII |David at (604) 873-3148|[CR][LF] .ASCII |and tell him of this error.| .BYTE 7,7,7,7,7 ;MORE BELLS .BYTE CR,LF,0 JMP BYEBYE ;ALL DONE ; ;-----> WRITE EOF BY PADDING SECTOR WITH CONTROL-Z, ; THEN WRITING SECTOR, AND CLOSING FILE ; WREOF: MVI A,EOF ;WRITE.. CALL WRBYTE ;..EOF LDA BUFPTR ;DONE WITH SECTOR? CPI 80H ;AT START ? JRNZ WREOF ;..NO, LOOP ;WRBYTE WROTE SECTOR, SO CLOSE THE FILE LXI D,FCB MVI C,CLOSE CALL BDOS INR A ;OK? RNZ ;ERROR: COULDN'T CLOSE FILE CALL ILPRT .ASCIZ |++Sorry, couldn't close the file.|[CR][LF] JMP TELLUS ; ;-----> WRITE BYTE TO CURRENTLY OPENED FILE ; WRBYTE: PUSH H LHLD BUFPTR MOV M,A ;STORE CHAR INX H MOV A,H ;TIME TO WRITE? (ADDR=100H) DCR A JRNZ WRBNOW ;NO WRITE ;WRITE SECTOR PUSH B PUSH D LXI D,FCB MVI C,WRITE CALL BDOS POP D POP B ORA A JRZ WRBOK ;WRITE OK CALL ILPRT .ASCIZ [CR][LF]|++Error in writing logout++|[CR][LF] JMP TELLUS ; ;WRITE WAS OK ; WRBOK: LXI H,80H ;BACK TO START OF BUFFER WRBNOW: SHLD BUFPTR ;SAVE POINTER POP H RET ; ; ;-----> WRITE A VARIABLE TO DISK ; WRVAR: MOV A,M ;GET CHAR CPI CR ;END? RZ ;YES, RET ;DON'T WRITE A COMMA, AS THAT IS THE DELIMITER ;USED WHEN READING BACK CPI ',' JRNZ ..L1 MVI A,'/' ;SUBSTITUTE '/' ..L1: CALL WRBYTE INX H JMPR WRVAR ;LOOP UNTIL C/R ; ;-----> WRITE CR/LF INTO FILE ; WRCRLF: MVI A,CR CALL WRBYTE MVI A,LF JMPR WRBYTE ; ;-----> ROUTINE TO SET UP FILE FOR READ ;HL POINTS TO FCB. ; SETRD: XRA A ;GET 'NOT EOF' VALUE STA EOFLG ;SET EOF FLAG STA FCBEXT ;ZERO EXTENT STA FCBRNO ;ZERO RECORD NUMBER STA S2 ;ZERO S2 BYTE ;MOVE FILENAME TO FCB LXI D,FCB LXI B,12 ;FILENAME LENGTH LDIR ;MOVE FILENAME TO FCB LXI H,100H ;EMPTY BUFF VALUE SHLD BUFPTR LXI D,FCB MVI C,OPEN CALL BDOS ;OPEN THE FILE RET ;A= -1 IF ERROR ELSE >= 0 ; ;-----> ROUTINE TO READ BYTE FROM FILE. ;5CH FCB USED, BUFFER AT 80, BUFPTR POINTING ;INTO BUFFER. MUST CALL 'SETRD' FIRST, ;WITH HL POINTING TO FCB ; RDBYTE: LDA EOFLG ;ALREADY HAVE EOF? ORA A ;SET TO 1AH IF EOF. STC ;CARRY & RET IF EOF, RNZ ;A=1AH FROM EOFLG PUSH H LHLD BUFPTR ;GET POINTER MOV A,H ;TIME.. DCR A ;..TO READ? JRNZ NORD ;READ A SECTOR FROM THE FILE LXI D,FCB MVI C,READ PUSH B PUSH D CALL BDOS POP D POP B ORA A ;READ OK? JRZ RDOK POP H MVI A,EOF ;FAKE EOF STA EOFLG ;SET FLAG STC ;SHOW EOF RET ; RDOK: LXI H,80H ;GET START OF BUFF POINTER ; NORD: MOV A,M ;GET CHAR INX H ;POINT TO NEXT CHAR SHLD BUFPTR POP H CPI EOF JRNZ RDBNEO STA EOFLG ;SET EOF FLAG STC ;SHOW EOF RET ; RDBNEO: ORA A ;CLEAR CARRY: NOT EOF RET ; ; ;-----> EXTEND A FILE. ;NAME (NOT FCB) POINTED TO BY HL. ;MAKE THE FILE IF IT DOESN'T EXIST. ; EXTEND: PUSH H ;SAVE NAME POINTER CALL SETRD ;TRY OPENING IT POP H ;GET SAVED NAME PTR ORA A ;SET FLAGS JM BYEBYE ;DISCONNECT IF NO LOG FILE LDA FCB+15 ;GET HI SECTOR DCR A ;IF START OF EXT, JM EXTEOF ;..JUST SCAN STA FCBRNO ;SET REC # EXTEOF: CALL RDBYTE ;SCAN FOR CPI EOF ;..EOF JRNZ EXTEOF ;GOT EOF - BACK UP BUFPTR BY 1 FOR SUBSEQUENT WRITES, ;ALSO BACK UP THE SECTOR NUMBER, IN PREP FOR WRITE LHLD BUFPTR DCX H SHLD BUFPTR LDA FCBRNO ;GET REC # DCR A STA FCBRNO RET ; ILPRT: POP H ;GET MSG ADDR CALL TYPEM0 ;TYPE THE MESSAGE PCHL ;RET FOLLOWING MESSAGE ; ;-----> TYPE MESSAGE (HL=POINTER, (B) = END OF MSG) ; TYPEM0: MVI B,0 ;DEFAULT END DELIMITER TYPEM: MOV A,M ;GET CHR INX H CMP B ;END? RZ ;..YES CALL TYPE ORA A JRNZ TYPEM ; CRLF: MVI A,CR CALL TYPE MVI A,LF ; TYPE: PUSH B PUSH D PUSH H PUSH PSW TYPEC: MOV E,A ;FOR OUTPUT ROUTINE MVI C,PRNT ;BDOS CALL FOR CON OUT CALL BDOS POP PSW POP H POP D POP B RET ; ;SYSTEM EQUATES ; ; ANSWER: .ASCII |DD-MMM-YY XX:XX:XX|[CR] ETMSG: .ASCII |CP/M ET | ET: .ASCII |XX:XX:XX|[CR] ; LOGFL: .ASCII [0]|LOG | ; 12345678123 ; EOFLG: .BYTE 0 ;END OF FILE (1AH=EOF) ; BUFPTR: .BLKB 2 ;FILE READ CHAR POINTER .BLKB 60 ;STACK SPACE ; STACK == . ;FOR 'LXI SP,STACK' PRNT == 2 ;PRINT CHAR ON CONSOLE OPEN == 15 ;0FFH=NOT FOUND CLOSE == 16 SRCHF == 17 SRCHN == 18 ERASE == 19 READ == 20 ;0=OK, 1=EOF WRITE == 21 ;0=OK, 1=ERR MAKE == 22 ;0FFH=BAD REN == 23 ;0FFH=BAD STDMA == 26 BDOS == 5 FCB == 5CH FCBEXT == FCB+12 ;EXTENT NUMBER FCBNSEC == FCB+15 ;# SECTORS IN FILE FCBRNO == FCB+32 ;RECORD (SECTOR) NUMBER S2 == FCB+14 ;MUST BE SET TO ZERO BY USER ; .END BYE