"Loading DMS support" $PRINT CRLF ;mod 6/13/11 - modified swapper in ALTSAVE to clear A/B ; removed spaces in ?DMS to recover memory ;mod 9/8/04 - added ALTSAVE ;mod 12/30/03 - added ?DMS ;mod 3/15/03 - GOUSER, GOSYSTEM ;mod 11/28/02 - MSUSER ;--------------------------------------------------- ; ; EXPERIMENTAL 21MX HP-PIL/OS DMS KEYWORDS ; FOR HP-1000 M/E/F SERIES CPU'S ONLY! ; ; THIS INCLUDES : ; !DMS -DMS SDMA UDMA SJUMP UJUMP SPAGE C>ACOPY ; A>CCOPY USPACE DMSTATUS ; ; Converted to CREATE format, 9/19/02 ; Editorial corrections 10/17/02 ; "Loading !DMS" $PRINT CRLF ; ; !DMS, INITIALIZES DMS AND ENABLES SYSTEM MAP ; CREATE !DMS JMP CSTART * * DMS SUBROUTINES * * SETUP DCPC FOR USER MAP ACCESS * SUDMA NOP * SET DCPC PORT A MAP TO CURRENT USER MAP SUDM1 CLA,INA * A REG = 000001 RAR * A REG = 100000 XMA * XFER MAPS INTERNAL PER A * SET DCPC PORT B MAP TO CURRENT USER MAP INA * A REG = 100001 XMA * XFER MAPS INTERNAL PER A JMP SUDMA,I * END OF SUDMA * * SETUP DCPC FOR SYSTEM MAP ACCESS * SSDMA NOP * SET DCPC PORT A MAP TO SYSTEM MAP SSDM1 CLA * CLEAR A REG XMA * XMA * SET DCPC PORT B MAP TO SYSTEM MAP CLA,INA * A REG = 000001 XMA * XFER MAPS INTERNAL PER A JMP SSDMA,I * END OF SSDMA * * TEST FOR USER MODE - IF SYSTEM MODE EXIT WITH A=0 * IF USER MODE PRINT "USER TRAP " AND EXIT WITH A=1 * TUSRM NOP RSA * READ STATUS REGISTER INTO A RAR,ALF * PUT BIT 12 INTO BIT 15 SSA,RSS * SKIP IF USER MODE (B15=1) JMP TUSRS * JUMP IF SYSTEM MODE LDA TUSR8 * GET WORD COUNT LDB TUSR9 * GET MESSAGE ADDRESS JSB ZPBFL,I * PRINT "USER TRAP " CLA,INA * A = 1 JMP TUSRM,I * RETURN TUSR8 OCT 5 TUSR9 DEF *+1 ASC 5,USER TRAP TUSRS CLA * A = 0 JMP TUSRM,I * RETURN * DMREG OCT 000100 * SYSTEM AND USER MAP REGISTERS MASK1 OCT 001777 * VM ABSOLUTE ADDRESS MASK (SPAGE) DMSK2 OCT 000037 * DMS PAGE ADDRESS MASK (SPAGE) MASK3 OCT 077777 * WORD COUNT AND ADDRESS MASK (C>A..A>CCOPY) DCON1 OCT 000040 * START OF USER MAP DMS REGISTERS (USPACE) * * end of subs and var, code entry... * CSTART JSB TUSRM * TEST FOR USER MODE SZA * SKIP IF A=0 JMP ZNXT,I * EXIT IF USER MODE * SET FENCE FOR NO UNMAPPED BASE PAGE MEMORY CLA * CLEAR A REG LFA * LOAD FENCE FROM A * LOAD SYSTEM AND USER MAP REGISTERS LDA DMREG * SET A REG TO 77 OCTAL CAX * COPY A TO X CLA * CLEAR A REG CLB * CLEAR B REG XMS * TRANSFER MAPS SEQUENTIALLY * SYSTEM MAP = PAGES 00 - 37, USER MAP = PAGES 40 - 77 JSB SSDMA * SETUP DMA HARDWARE FOR SYSTEM MAP * DISABLE MEMORY PROTECT - NO PROTECTED MODE OPERATION! CLC 05B * CLEAR CONTROL 05 DISABLED M.P. * ENABLE SYSTEM MAP AND CONTINUE SJP * SJP - ENABLE SYSTEM MAP AND JUMP DEF *+1 * TARGET ADDRESS FOR SJP * DMS ENABLED, SYSTEM MAP SELECTED! END "Loading -DMS" $PRINT CRLF ; ; -DMS, DISABLES DMS ; CREATE -DMS /KEEP * USER MODE TRAP JSB TUSRM * TEST FOR USER MODE SZA * SKIP IF A=0 JMP ZNXT,I * EXIT IF USER MODE * DJP * DISABLE DMS AND JUMP DEF *+1 * DJP TARGET ADDRESS * DMS MAPPING IS NOW DISABLED! END "Loading SDMA" $PRINT CRLF ; ; SDMA, SETS DCPC PORTS A,B TO SYSTEM MAP ; CREATE SDMA /KEEP * USER MODE TRAP JSB TUSRM * TEST FOR USER MODE SZA * SKIP IF A=0 JMP ZNXT,I * EXIT IF USER MODE JSB SSDMA * SETUP DCPC HARDWARE END "Loading UDMA" $PRINT CRLF ; ; UDMA, SETS DCPC PORTS A,B TO CURRENT USER MAP ; CREATE UDMA /KEEP * USER MODE TRAP JSB TUSRM * TEST FOR USER MODE SZA * SKIP IF A=0 JMP ZNXT,I * EXIT IF USER MODE JSB SUDMA * SETUP DCPC HARDWARE END "Loading UJUMP" $PRINT CRLF ; ; UJUMP, JUMPS TO ADDRESS IN CURRENT USER MAP ; CREATE UJUMP /KEEP JSB ZSPOP,I * POP TARGET ADDRESS FROM STACK UJP * ENABLE UDER MAP AND JUMP OCT 100000 * UJP TARGET ADDRESS = A REG INDIRECT! * NOTE! HP-IPL/OS HAS LOST CONTROL OF THE CPU, USER CODE RUNS. END "Loading SJUMP" $PRINT CRLF ; ; SJUMP, JUMPS TO ADDRESS IN SYSTEM MAP ; CREATE SJUMP /KEEP JSB ZSPOP,I * POP TARGET ADDRESS FROM STACK SJP * ENABLE SYSTEM MAP AND JUMP OCT 100000 * SJP TARGET ADDRESS = A REG INDIRECT! * NOTE! USER CODE HAS LOST CONTROL OF THE CPU, SYSTEM CODE RUNS. END "Loading SPAGE" $PRINT CRLF ; ; SPAGE, ALTERS SYSTEM DMS MAPPING! ; THIS POPS THE SELECTED VM PAGE NUMBER, AND THEN THE ; DESIRED 1K PAGE ADDRESS FROM THE SYSTEM STACK. THE ; SELECTED MEMORY PAGE IS REPLACED BY THE ADDRESED VM ; MEMORY BLOCK. ; CREATE SPAGE /KEEP * USER MODE TRAP JSB TUSRM * TEST FOR USER MODE SZA,RSS * SKIP IF A<>0 JMP DMS6A * JUMP IF SYSTEM MOME JSB ZSPOP,I * CLEAN UP STACK JSB ZSPOP,I JMP ZNXT,I * EXIT * DMS6A CLA,INA * A REG = 000001 CAX * COPY A TO X JSB ZSPOP,I * POP VM PAGE ADDRESS AND MASK1 * VM PAGES = 0 TO 1777 STA TMP1 * SAVE IT IN TEMP1 JSB ZSPOP,I * POP MEMORY PAGE ADDRESS AND DMSK2 * DMS PAGES = 0 TO 37 LDB TMP1 * B REG = VM ABSOLUTE PAGE ADDRESS * DMS ADDRESS IN A REG, VM PAGE ADDRESS IN B REG, X = 000001 XMS * TRANSFER MAPS SEQUENTIALLY * A 1K WORD PAGE JUST GOT REMAPPED, BE CAREFUL WITH THIS ONE! END "Loading C>ACOPY" $PRINT CRLF ; ; C>ACOPY, COPIES WORDS FROM CURRENT MAP TO ALTERNATE MAP ; POPS WORD COUNT, TARGET ADDRESS, SOURCE ADDRESS FROM STACK ; CREATE C>ACOPY /KEEP JSB ZSPOP,I * POP WORD COUNT AND MASK3 * LIMIT TO POSITIVE VAUES STA TMP1 * SAVE WORD COUNT JSB ZSPOP,I * POP TARGET ADDRESS AND MASK3 * 32K WORD ADDRESS LIMIT STA TMP2 * SAVE TARGET ADDRESS JSB ZSPOP,I * POP SOURCE ADDRESS AND MASK3 * 32K ADDRESS LIMIT STA TMP3 * SAVE SOURCE ADDRESS LDA TMP1 * GET WORD COUNT CAX * COPY A TO X * WORD COUNT NOW IN X REGISTER LDA TMP3 * PUT SOURCE ADDRESS IN A REG LDB TMP2 * PUT DESTINATION ADDRESS IN B REG MWI * MWI - MOVE WORDS INTO ALTERNATE MAP * WORD BLOCK COPY INTO ALTERNATE MAP TAKES PLACE END "Loading A>CCOPY" $PRINT CRLF ; ; A>CCOPY, COPIES WORDS FROM ALTERNATE MAP TO CURRENT MAP ; CREATE A>CCOPY /KEEP JSB ZSPOP,I * POP WORD COUNT AND MASK3 * LIMIT TO POSITIVE VAUES STA TMP1 * SAVE WORD COUNT JSB ZSPOP,I * POP TARGET ADDRESS AND MASK3 * 32K WORD ADDRESS LIMIT STA TMP2 * SAVE TARGET ADDRESS JSB ZSPOP,I * POP SOURCE ADDRESS AND MASK3 * 32K ADDRESS LIMIT STA TMP3 * SAVE SOURCE ADDRESS LDA TMP1 * GET WORD COUNT CAX * CAX - COPY A TO X * WORD COUNT NOW IN X REGISTER LDA TMP3 * PUT SOURCE ADDRESS IN A REG LDB TMP2 * PUT DESTINATION ADDRESS IN B REG MWF * MOVE WORDS FROM ALTERNATE MAP * WORD BLOCK COPY FROM ALTERNATE MAP TAKES PLACE END "Loading USPACE" $PRINT CRLF ; ; USPACE, SETS USER MAP TO ANY LINEAR 32K WORD BLOCK IN VM ; CREATE USPACE /KEEP JSB ZSPOP,I * GET VALUE FROM STACK * USER MODE TRAP STA TMP4 JSB TUSRM * TEST FOR USER MODE SZA * SKIP IF A=0 JMP ZNXT,I * EXIT IF USER MODE LDA TMP4 * * CALCULATE STARTING DMS REGISTER VALUE AND DMSK2 * KEEP LOW 5 BITS ONLY RAL,RAL * SHIFT SHIFT RAL,RAL * SHIFT SHIFT RAL * SHIFT LEFT 5 BITS ADA DCON1 * ADD USER MAP DMS REG OFFSET STA TMP1 * SAVE DMS REGISTER BASE VALUE * LOAD REGISTERS FOR XMS INSTRUCTION LDA DMSK2 CAX * COPY A TO X * X REG = NUMBER OF DMS REGISTERS TO LOAD LDA DCON1 * USER MAP STARTING ADDRESS * A REG = DMS STARTING REGISTER ADDRESS LDB TMP1 * B REG = DMS STARTING REGISTER VALUE XMS * TRANSFER MAPS SEQUENTIALLY * USER ADDRESS SPACE IS NOW REMAPPED! END "Loading DMSTATUS" $PRINT CRLF ; ; DMSTATUS, GETS DMS STATUS REGISTER VALUE ; CREATE DMSTATUS /KEEP RSA * READ STATUS REGISTER INTO A JSB ZSPSH,I * PUSH REGISTER VALUE TO STACK END ; ; END CORE DMS DEFINITIONS ; ;--------------------------------------------------- "Loading UPTR and MSUSER" $PRINT CRLF ; ; MSUSER pops location, stores in UPTR variable and redirects ; MS input and output to that location in the alternate map. ; Usage: address MSUSER ; CREATE UPTR LDA PTLOC JSB ZSPSH,I JMP ZNXT,I PTLOC DEF UPTR UPTR OCT 0 END ; CREATE MSUSER /KEEP JSB ZSPOP,I pop starting location STA UPTR and save CLA STA EOFLG clear even/odd flag LDA MSISA get MS input sub address STA ZMINP save in input vector LDA MSOSA get MS output sub address STA ZMOUT save in output vector JMP ZNXT,I back to hpiplos MSISA DEF MSIS MSOSA DEF MSOS MSIS NOP *** MS input byte sub LDB EOFLG SZB JMP INODD CLA,INA CAX put a 1 in X (length) LDB TBUFA destination - address of buffer LDA UPTR source - mem pointer MWF move word from alt map ISZ EOFLG set even/odd flag LDA TBUFF get buffer contents ALF,ALF put high byte in low byte AND LBMSK return high byte first JMP MSIS,I exit subroutine INODD CLA STA EOFLG clear even odd flag ISZ UPTR increment user-mem pointer LDA TBUFF AND LBMSK return low byte from word JMP MSIS,I MSOS NOP *** MS output byte sub AND LBMSK make sure 8 bit data LDB EOFLG get even/odd flag SZB JMP OTODD if odd jump to odd ALF,ALF put data in high byte STA TBUFF save in buffer ISZ EOFLG set even odd flag JMP MSOS,I return from subroutine OTODD IOR TBUFF OR data with high-byte data STA TBUFF save back to buffer CLA,INA CAX put a 1 in X (length) LDA TBUFA source - address of buffer LDB UPTR destination - mem pointer MWI move word into alt map CLA STA EOFLG clear even/odd flag ISZ UPTR increment pointer NOP JMP MSOS,I LBMSK OCT 377 low-byte mask TBUFA DEF TBUFF address of buffer TBUFF OCT 0 temp buffer EOFLG OCT 0 even/odd flag M1 OCT -1 END ;--------------------------------------------------- "Loading ABSLOAD" $PRINT CRLF ; loads ABS file from MS into alternate page ; just loads, use UJUMP (or SJUMP if in user page) ; to execute. DMS must be enabled (!DMS) 7/29/02 DEFINE ABSLOAD #0 ;a dot counter DO ;find 1st record... MSBIN DUP IFNZ #1 ENDIF ;terminate when non-zero UNTIL ;leave recordlen on stack "LOADING" $PRINT DO ;main loop SWAP INC ;inc dot counter and print . every 10 records DUP 10 SUB IFZ "." $PRINT DROP #0 ENDIF SWAP ;note doesn't indicate size, only activity MSBIN DROP ;discard unused byte MSWIN DUP ROT ;stack chk,recordlen,address (chk=address) SWAP DEC OVER ADD ; now chk,startadr,endadr +DO ;process each word, stack now just chk MSWIN ; get word from MS, stack now chk,data SWAP OVER ADD SWAP ;add to checksum SP>S DEC ; push address of data on stack INDEX #1 C>ACOPY ;copy one word to adr in user map DROP ;don't need word anymore +LOOP MSWIN ;get checksum SUB IFNZ ;if checksum error... CRLF "CHECKSUM ERROR" $PRINT #1 ;print error and terminate ELSE MSBIN ;get next record length DUP IFZ DROP MSBIN ENDIF ;unrolled loop to DUP IFZ DROP MSBIN ENDIF ;allow up to 4 consecutive DUP IFZ DROP MSBIN ENDIF ;0 bytes between records DUP IFZ DROP MSBIN ENDIF ;otherwise basic won't load! ;this implies that abs files should always end with a lot of zero's ;the first 0 does NOT terminate! don't recall this in the docs... ;but matches observation that without 20 or so 0's the load fails. DUP IFZ DROP #1 ;if zero, drop and terminate ELSE #0 ENDIF ;keep looping if another record ENDIF ;checksum error UNTIL ;loop until all records have been loaded DROP ;dot counter END ;---------------------------------------------------- "Loading GOUSER and GOSYSTEM" $PRINT CRLF ; ; These make jumping to/from user map easier... ; GOUSER - disable irq/auto, copy everything to user and restart ; GOSYSTEM - enable auto, copy everything and restart in sysmap ; Modified 3/15/02 (a) (removed SYSEXIT 9/8/04) ; In user mode, NO dma/mt/ints or else, paper only!!! ; To return to sys mode without copying: 2 SJUMP OCTAL DEFINE GOUSER DMSTATUS 170000 AND 120000 SUB IFZ -IRQ #0 #0 77777 C>ACOPY ;copy sys mem to alt mem 21440 SP>S DEC 460 #1 C>ACOPY DROP ;# prompt in user copy #0 SP>S DEC 465 #1 C>ACOPY DROP ;disable auto-start in user copy 2 UJUMP ;jump to user copy ELSE "Not in system mode" $PRINT ENDIF END ; DEFINE GOSYSTEM DMSTATUS 170000 AND 130000 SUB IFZ #0 #0 77777 C>ACOPY ;copy to alt mem 37440 SP>S DEC 460 #1 C>ACOPY DROP ;? prompt in system mode #1 SP>S DEC 465 #1 C>ACOPY DROP ;enable auto-start in sys copy 2 SJUMP ;jump to copy in sys mem ELSE "Not in user mode" $PRINT ENDIF END ;---------------------------------------------------- "Loading ALTSAVE" $PRINT CRLF DEFINE ALTSAVE ; saves the current system to alternate memory and add a ; restore program beginning at 77000 that swaps alt and sys mem ; and jumps to 2 in system memory. Usage: ; ALTSAVE ; [do something that you want to restore from] ; 77000 RUN if in hpiplos or otherwise jump to 77000 ; HP-IPL/OS restored. ; 77000 RUN again to swap back but be very careful not to ; MTSHOW/MTLOAD/TSHOW/TLOAD or anything else that disturbs ; alternate memory or else.. primary use is to allow loading ; of a utility or program such as HPBASIC and be able to ; exit back to hpiplos as it existed before the load. ;save current system to alt map 2 2 76000 C>ACOPY ;put exit code at 77000 that enables dms and copies ;the saved system back to the system map and runs from 2 ; original code, just restores ; 76000 2 127010 105706 67010 63010 77011 105745 77002 105734 ; 77000 77011 +DO INDEX SWAP PUT +LOOP ; new code 8/31/04 swaps alt/sys to allow saving or swapping back ;400 76400 76002 2 27004 73035 127031 53032 43034 63035 105707 ;67035 63033 77034 105745 105706 67035 63035 77034 105745 105705 ;67033 63035 77034 105745 73035 63031 77002 105734 ;77000 77034 +DO INDEX SWAP PUT +LOOP ; new code 6/13/11 also clear A/B reg to avoid issues (esp w/ BCS) 400 76400 76002 2 127034 6400 2400 27004 73040 27031 53035 43037 63040 105707 67040 63036 77037 105745 105706 67040 63040 77037 105745 105705 67036 63040 77037 105745 73040 63034 77002 105734 77000 77037 +DO INDEX SWAP PUT +LOOP ; note... it might be better if the swapper was in its own word.. ; but it's been in ALTSAVE since 2004 and changing now would trigger ; a cascade of IPL/doc changes. Probably not a good idea as far as the ; core system - but if you really need a separate swapper word, just ; copy the above code (400 to +LOOP) into a DEFINE word. END ;---------------------------------------------------- "Loading ?DMS" $PRINT CRLF ; DEFINE ?DMS CRLF "Dynamic Mapping System status:" $PRINT CRLF DMSTATUS 034000 AND CASE = 020000 " DMS is ENABLED, current mapping is SYSTEM. " $PRINT CRLF " PROTECTED MODE is DISABLED. " $PRINT CRLF = 030000 " DMS is ENABLED, current mapping is USER. " $PRINT CRLF " PROTECTED MODE is DISABLED. " $PRINT CRLF = 024000 " DMS is ENABLED, current mapping is SYSTEM. " $PRINT CRLF " PROTECTED MODE is ENABLED. " $PRINT CRLF = 034000 " DMS is ENABLED, current mapping is USER. " $PRINT CRLF " Warning - PROTECTED MODE is ENABLED! " $PRINT 000007 PCHR CRLF = 000000 " DMS is DISABLED. " $PRINT CRLF DEFAULT ENDCASE DMSTATUS 140000 AND CASE = 100000 " MEM was ENABLED in the SYSTEM mapping at last interrupt." $PRINT CRLF = 140000 " MEM was ENABLED in the USER mapping at last interrupt." $PRINT CRLF DEFAULT ENDCASE " Base page fence value = " $PRINT DMSTATUS 003777 AND PNUM CRLF END ;---------------------------------------------------- "Done" $PRINT CONSOLE