.TITLE DVSIM ; ;DEVICE SIMULATOR TO EMULATE A HARDWARE DEVICE UNDER MSX. IT FILLS ;IN BUFFERS FROM MEMORY USING CLOCK TICKS TO SIMULATE A DEVICE ;("COMMUNICATIONS CONTROLLER" OR CC) WHICH GRABS LINKED BLOCKS ;OF MEMORY FOR INPUT MESSAGES AND STUFFS THEM WITH DATA AND WHICH ;HAS A GENERAL LIST OF COMMPLETED TRANSACTIONS WHICH IT PERIODICALLY ;EMITS GIVING DETAILS OF FINISHED INPUT AND OUTPUT DATA. THE REAL ;DEVICE THIS SIMULATED WAS SET UP TO HANDLE 18-BIT ADDRESSES, BUT ;A PRACTICAL DEVICE OF THIS TYPE MUST BE ABLE TO ACCESS THE FULL ;HARDWARE ADDRESS SPACE SINCE THE DMA IS ESSENTIALLY IMPOSSIBLE TO ;BOOK-KEEP IN SOFTWARE. THE DESIGN IS EFFICIENT THERE, BUT WHERE THE ;DEVICE WAS LIMITED TO 18 BITS, ITS USEFULNESS WAS LIMITED TO ;SMALL SYSTEMS OR NETWORKS. ; THIS VERSION OF THE SIMULATOR IS DESIGNED TO RUN UNDER RSX11M ;AND MSX AND WILL NORMALLY BE TASKBUILT WITH MSX AND STARTED BY A ;SUBROUTINE CALL FROM A USER'S INITIATING TASK. THE BUFFER INPUT CHAIN ;WILL BE PRESUMED TO BE POINTED TO BY GLOBAL INCHN AND THE OUTPUT BUFFER ;WILL BE ADDRESSED BY OUTTBL, WHERE OUTTBL WILL BE INDEXED BY LT ;NUMBER AND POINT TO A 32-WORD BLOCK FOR BUFFER START. THE BUFFERS ;WILL BE BUFSIZ LONG (64 BYTES AT FIRST) AND DATA WILL BE INSERTED ;IN A PRIMITIVE WAY FROM TMPBUF STARTING AFTER OFFSET (2 WORDS ;HERE...JUST A GUESS.) ; CC DMA STACK WILL BE POINTED TO BY CCSTAK, AND CC WORDCOUNT ;LEFT WILL BE CCWC, INCREMENTED AFTER EVERY WORD IS ADDED TO THE ;DMA STACK. ; TO START THE THING, CALL CCBGN WHICH WILL START MARKTIMES ;COMING IN AND CREATING STACK ITEMS (AND FAKING MSX INTERRUPTS) AND ;STASHING STUFF ON THE "DMA STACK". THE TASK'S APRS WILL BE SAVED/ ;RESTORED TO FREE THEM FOR USE HERE, SINCE THE PROGRAM HERE WILL ;HAVE TO USE APRS TO GET AT THE DATA IT HAS TO BASH. THE ADDRESSES ;STORED ARE ALL 64 BYTE BLOCK NUMBERS WHERE THERE IS 1 WORD AVAILABLE. ; ; TO START "OUTPUT" CALL CCOUT WITH R2 SET TO THE OUTPUT ADDRESS ;BLOCK NUMBER. THIS WILL SIMPLY INSERT A STACK ITEM AT THE CURRENT ;STACK ADDRESS, GLOBALLY AVAILABLE AS CCSP ; ; TO STOP THE THING CALL WHOA, WHICH WILL CANCEL MARKTIMES HERE. ; ; STACK FRAMES PUSHED WILL BE PREDEFINED (EXCEPT FOR LT # AND ;BUFFER ADDRESSES) IN SOME MORE OR LESS ARBITRARY WAY. SEQUENCES WILL ;BE: ; OUTPUT FRAMES (LT INFO ON TPE) ; END-OF FRAME, NEXT ; END OF BUFFER ADDRESS (FOR AN LTPA) ;LT NUMBER ENABLED BY ; ;NONZERO VALUE IN LTINEN ARRAY ; CC-PARITY-FRAME ; ; THESE WILL BECOME AVAILABLE VIA A MARKTIME EVERY SO OFTEN ;WHICH WILL SIMULATE A CC INTERRUPT (MXINT HAS THE ACTUAL AST ;ROUTINE AND HANDLING CODE WHICH WILL JUST BE POINTED TO HERE...) ; ; THIS ROUTINE WILL ONLY PUT DATA ONTO THE STACK OR ;MAKE MARKTIMES TO HANDLE THE PERIODIC INTERRUPTS-- NOTHING MORE. ; CCPAR: .WORD 4,4 ;CC PARITY COUNT (REALLY CONSTANT) CCTPE: .WORD 100,0 ;TPE (OUTPUT DONE) MASK FOR LT N CCINDN: .WORD 222,0 ;INPUT DONE END-FRAME ITEM .WORD 20000,0 ;END OF BUFFER ADDRESS ITEM ;NOTE THE ABOVE MASK ITEMS MUST BE MODIFIED TO CONFORM TO THE ACTUAL ;ITEMS TO BE USED. ; .GLOBL WHOA,CCOUT,CCSP,MX.CAS .GLOBL CCMTM ;CC MARKTIME AST ENTRY .MCALL MRKT$S,CMKT$S,MRKT$,CMKT$ MARK: MRKT$ ,3,2,CCMTM ;MARKTIME AST AT CCMTM .MCALL DIR$ ;STOP MARKTIMES... WHOA: CMKT$S ;CANCEL MARKTIMES PENDING IF ANY RTS PC ;THEN BACK TO USER .GLOBL CCBGN ;STARTUP ENTRY CCWRK: .WORD 0 ;SET NONZERO IF ANY WORK IS TO BE DONE CCSTAK:: .WORD 0 ;CC STACK ADDRESS BUFSIZ=64. OFFSET=4. ;INPUT BUFF SIZE, OFFSET INCHN: .WORD 0 ;BLOCK # OF INITIAL CHAIN ENTRY (OR CURRENT ONE) ;0 OR NEGATIVE ==> END OF CHAIN CCSP:: .WORD 0 ;CC STACK CURRENT ADDR VIRTUAL CCWC:: .WORD 0 ;CC REMAINING WORDCOUNT IOUTTBL:: .WORD 0 ;OUTPUT LTPA NO. ;NOTE NO ARRAY NEEDED... WE JUST FILL IN A STACK ITEM OURSELVES. OURPAR: .WORD 0 ;USED TO SAVE A LOCAL STACK PAR (PAR 6) ;WHICH WILL BE USED (AT PRI7) TO ADDRESS ;THE DMA STACK. NOTE THAT CCSP WILL BE ;RELATIVE TO PAR 6 (140000 BITS SET) UPAR0=177640 UPAR6=177654 UPDR0=177600 UPDR6=177614 ;PAR ADDRESSES TO MONKEY WITH MAXLT=4 ;MOST LT NUMBERS TO USE LTINEN:: .BLKB MAXLT .EVEN ;THE LTINEN ARRAY IS NONZERO BYTES WHEREINPUT IS ENABLED... ;OTHERWISE 0. ; CCBGN:: CLR CCWRK ;FLAG NO MORE WORK DIR$ #MARK ;PREPARE THE MARKTIME AST RTS PC ;THEN BUG OUT ; ; PUTSTAK -- ROUTINE TO FILL IN A STACK ENTRY ; ; CCSP = CC HANDLER STACK ADDR ; CCWC = CC HANDLER WC ; ; CCSTAK = CC STACK START BLOCK (64 BYTE) ; ; INPUTS: R0=ADDR OF STACK ENTRY TO FILL IN (LOCAL) ; OUTPUTS: STACK ENTRY ; PUTSTK: MOV @#UPAR5,-(SP) ;SAVE UAPR5 MOV R0,-(SP) MOV CCSTAK,R1 ;ADDR OF CC HANDLER STACK MOV #5,R0 ;PAR 5 SPEC JSR PC,MAPPER ;GO MAP IT (ASSUMES CCSTAK IS REAL MEM BLK) MOV (SP)+,R0 ;GET BACK R0 MOV CCSP,R1 ;GET CC STACK POINTER BIS #140000,R1 ;PLUS APR5 OFFSET MOV (R0)+,(R1)+ ;FILL IN THE STACK ADD #1,CCWC ;COUNT UP WORD COUNT BLT 1$ ;OK IF NOT +\ CMKT$S ;ELSE STOP MARKTIMES 1$: MOV (R0)+,(R1)+ ADD #1,CCWC BLT 2$ CMKT$S 2$: MOV (SP)+,R1 ;RESTORE PAR 5 MOV #5,R0 ;BASH R0 JSR PC,MAPPER ;FIX UP PAR 5 AGAIN RTS PC ;RETURN ; ; CCMTM -- MARKTIME AST ENTRY ; ; THIS ENTRY WILL FILL IN STACK ENTRIES FOR CC PARITY ; AND GO TO MX.CAS FOR NORMAL CC HANDLING. ; CCMTM: JSR R5,S.RSAV ;SAVE ALL REGS FOR IN HERE DIR$ #MARK ;SET UP THE NEXT TICK'S AST JSR PC,INPOLL ;GENERATE INPUT DATA IF ANY ENABLED MOV #CCPAR,R0 ;POINT TO CC PARITY STACK ENTRY JSR PC,PUTSTK ;FILL IT IN TO THE STACK JSR R5,S.RRES ;RESTORE SAVED REGISTERS JMP MX.CAS ;THEN GO DO NORMAL AST EXIT MSX NOTIFY... ; ; CCOUT -- GENERATE OUTPUT TPE ENTRY ON STACK FOR BUFFER ; USING LT NUMBERED. EXPECT ENTRY R2 TO BE THE LT NUMBER...BUFFER ; ADDRESS IS NEVER USED IN STACK ENTRIES. ; CCOUT:: JSR R5,S.RSAV ;SAVE REGS ASH #3,R2 ;SHIFT LT NUMBER OVER AS DESIRED MOV R2,CCTPE+2 ;SAVE IT MOV #CCTPE,R0 ;NOW STACK IT JSR PC,PUTSTK JSR R5,S.RRES ;GET USER'S REGS BACK RTS PC ; ; INPOLL -- LOOK ON LTINEN BUFFER AND FOR EACH INPUT ; ENABLED BUFFER GENERATE A BUFFER ADDRESS IF INCHN CAN HAVE ; A BUFFER OPOINTED TO IT. ; ; INPOLL: MOV #LTINEN,R5 ;ENABLE/DISABLE BYTES JSR PC,A$PRSV ;SAVE APR'S AT STARTUP MOV #MAXLT,R4 ;GET NO. OF LT'S 11$: ;REGS ASSUMED FREE ON STARTUP TSTB (R5)+ ;SEE IF INPUT ENABLED BEQ 101$ ;IF NOT SKIP SETUP 10$: JSR R5,S.RSAV MOV INCHN,R5 BLE 100$ ;IF NO BUFFERS JUST FORGET IT MOV R5,R1 ;POINT AT PAR5 CONTENTS MOV #5,R0 ;AND SPECIFY HIM JSR PC,MAPPER ;NOW LOAD APR5 WITH THAT ADDRESS MOV @#140000,R0 ;GET NEXT BUFFER ADDRESS MOV R0,INCHN ;AND SAVE FOR NEXT TIME MOV @#UAPR5,R2 ;POINT AT BLOCK ASH #-2,R2 ;LEAVE OUT BITS 6,7 MOV R2,CCINDN+6 ;SAVE H.O. ADDR BITS MOV @#UAPR5,R2 ;NOW GET BACK BITS 6,7 ASH #6,R2 BIC #177400,R2 ;BASH ALL BITS BUT... BIS #77,R2 ;AND SAY LAST ADDR IS 63 MORE MOVB R2,CCINDN+4 ;SET THEM IN... ;NOW FIND LT NUMBER MOV #LMAXLT,R2 SUB R4,R2 ;R2 = LT NO. INC R2 ;ADJUST RANGE TO 1,2,3,4,5... ASH #3,R2 ;POSITION IT MOV R2,CCINDN+2 ;AND FLAG WHICH LT IT IS ;NOW MODIFY THE DATA BLOCK TO FEED IN SOME "INPUT DATA" JSR PC,INFILL ;FILL UP INPUT BLOCK. REGS ALL FREE MOV #CCINDN,R0 ;NOW SET UP 1ST STACK ENTRY JSR PC,PUTSTK ;SAVE IT ON STACK MOV #CCINDN+4,R0 ;POINT AT 2ND ENTRY JSR PC,PUTSTK ;AND SAVE IT TOO 100$: JSR R5,S.RRES ;GET REGS BACK 101$: DEC R4 BGT 11$ ;DO ALL ENABLED ENTRIES JSR PC,A$PRRS ;GET BACK ORIGINAL APR'S RTS PC TEMPLT: .ASCII /THIS IS THE DAY WHICH THE LORD HATH MADE/ .ASCII <15><12>/WE WILL BE GLAD IN IT/<15><12> .EVEN .BLKW 16. ; INFILL -- FILL IN DATA AT PAR5 WITH TEXT AFTER "OFFSET" BYTES ; INFILL: MOV #140000+OFFSET,R0 ;ALL REGS AVAILABLE MOV #,R1 MOV #TEMPLT,R2 ;DATA IS IN "TEMPLT" ORIGINALLY 1$: MOVB (R2)+,(R0)+ ;FILL IN THE BUFFER DEC R1 BGT 1$ RTS PC .END ;THAT'S IT, PEOPLE!