; ; SECURITY4.ASM (revised 08/06/82) ; by Keith Petersen and Bob Mathias ; ;THIS PROGRAM RUNS UP IN HIGH RAM. IT GETS THERE ;BY BEING MOVED THERE WHEN 'MINICBBS' IS TYPED. ; ;THE PROGRAM IN HI RAM DOES THE FOLLOWING: ; ;LOADS AND EXECUTES FILE 'RIBBS.EXE' FROM USER 15 ;ON DRIVE B: ; ;------------------------------------------------ ;CHANGE THE FOLLOWING EQUATE TO AN AREA IN YOUR ;HI MEMORY WHERE THIS PROGRAM MAY PATCH ITSELF IN. ; DEST EQU 0C500H ;RUNNING LOCATION OF CODE ; ;------------------------------------------------ ; BASE SET 0 ALTCPM EQU 0 ;PUT 1 HERE FOR ALTERNATE CPM IF ALTCPM BASE SET 4200H ENDIF PRINT EQU 9 OPEN EQU 15 STDMA EQU 26 SGUSR EQU 32 ;SET/GET USER FUNCTION BDOS EQU BASE+5 FCB EQU BASE+5CH FCBEXT EQU FCB+12 FCBRNO EQU FCB+32 ; CR EQU 0DH LF EQU 0AH ; ORG BASE+100H ; ;MOVE THE PROGRAM UP TO HI RAM AND JUMP TO IT. ; MOVEUP LXI B,PEND-START+1 ;NUMBER OF BYTES TO MOVE LXI H,DEST+PEND-START+1 ;END OF MOVED CODE LXI D,SOURCE+PEND-START ;END OF SOURCE CODE MVLP LDAX D ;GET BYTE DCX H ;BUMP POINTERS MOV M,A ;NEW HOME DCX D DCX B ;BUMP BYTE COUNT MOV A,B ;CHECK IF ZERO ORA C JNZ MVLP ;IF NOT, DO SOME MORE PCHL ;JUMP TO "START" ; SOURCE EQU $ ;BOUNDARY MEMORY MARKER ; OFFSET EQU DEST-SOURCE ;RELOC AMOUNT ;-----------------------------------------------; ; THE FOLLOWING CODE GETS MOVED ; ; TO HI RAM LOCATED AT "DEST", ; ; WHERE IT IS EXECUTED. ; ;-----------------------------------------------; ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XX C A U T I O N : IF MODIFYING ANYTHING XX ;XX IN THIS PROGRAM FROM HERE ON: XX ;XX A-L-L LABELS MUST BE OF THE FORM: XX ;XX label EQU $+OFFSET XX ;XX IN ORDER THAT THE RELOCATION TO HI RAM XX ;XX WORK SUCCESSFULLY. FORGETTING TO XX ;XX SPECIFY '$+OFFSET' WILL CAUSE THE PRO- XX ;XX GRAM TO JMP INTO WHATEVER IS CURRENTLY XX ;XX IN LOW MEMORY, WITH UNPREDICTABLE XX ;XX RESULTS. BE CAREFUL.... XX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; START EQU $+OFFSET LXI SP,STACK ;SET UP LOCAL STACK POINTER ; ;SET USER NUMBER TO 15 ; MVI E,15 ;E = USER 15 MVI C,SGUSR CALL BDOS ; ;SAVE PAGE 0 TO RESTORE BEFORE JUMPING TO LOADED PROGRAM ; LXI H,BASE+5CH LXI D,PAGSAV MVI B,100H-5CH CALL MOVE ; ;LOAD AND EXECUTE FILE ; LXI H,FILENAM ;SOURCE LXI D,FCB ;DESTINATION MVI B,13 ;LENGTH CALL MOVE ;MOVE THE NAME ; ;SET DMA ADDR TO 80H LXI D,BASE+80H MVI C,STDMA CALL BDOS ; ;OPEN THE FILE ; LXI D,FCB MVI C,OPEN CALL BDOS ; ;DID IT EXIST? ; INR A ;A=> 0 MEANS "NO" JZ BYERR ;NO FILE, EXIT ERROR MSG ; OPENOK: EQU $+OFFSET LXI D,BASE+100H ;POINT TO TPA ; READLP: EQU $+OFFSET PUSH D ;SAVE BUFFER ADDRESS PUSH B PUSH H MVI C,STDMA CALL BDOS ; ;READ A SECTOR ; LXI D,FCB MVI C,20 ;READ CALL BDOS POP H POP B ORA A ;OK? JNZ EOF ;NOT OK, MUST BE EOF POP D ;GET DMA ADDR LXI H,80H ;LENGTH OF 1 SECT. DAD D ;CALC NEXT BUFF ADDR XCHG ;PUT IT BACK IN DE JMP READLP ;LOOP ; ;GOT RETURN CODE ON READ, SEE IF ERROR OR EOF ; EOF: EQU $+OFFSET POP D ;DELETE STACKED BUFFER ADDR ; ;A HAS RETURN CODE FROM READ DCR A ;EOF? JZ RSDMA ;YES, EXIT ; ;READ ERROR - EXIT WITH MSG ; BYERR: EQU $+OFFSET CALL ERXIT ;PRINT: DB CR,LF,'++DISK READ ERROR++',CR,LF,'$' ; ;EXIT WITH ERROR MESSAGE ; ERXIT: EQU $+OFFSET POP D MVI C,9 CALL BDOS XRA A STA BASE+4 ;SET DRIVE A:, USER 0 JMP BASE ; ;RESET DMA ADDRESS TO NORMAL ; RSDMA: EQU $+OFFSET LXI D,BASE+80H MVI C,STDMA CALL BDOS ; ; RESTORE PAGE 0 ; LXI H,PAGSAV LXI D,BASE+5CH MVI B,100H-5CH CALL MOVE ; ;LEAVE WARM BOOT ADDRESS ON STACK, THEN EXECUTE RIBBS ; LXI H,0 PUSH H JMP BASE+100H ;EXECUTE MINICBBS ; ;MOVE (HL) TO (DE), LENGTH IN (B) ; MOVE: EQU $+OFFSET MOV A,M ;GET A BYTE STAX D ;PUT AT NEW HOME INX D ;BUMP POINTERS INX H DCR B ;DEC BYTE COUNT JNZ MOVE ;IF MORE, DO IT RET ;IF NOT,RETURN ; FILENAM EQU $+OFFSET DB 3,'RIBBS EXE',0 ;FILENAME GOES HERE^^^^^^^^^^^ ;DRIVE NAME HERE^ ^EXTENT NR. ; PEND EQU $+OFFSET ;END OF RELOCATED CODE ; DS 40 STACK EQU $+OFFSET ;LOCAL STACK ; PAGSAV EQU STACK+1 ;ADDRESS OF PAGE 0 SAVE AREA END