; 0BF0H = TRAP HANDLER ; 2BH = INHIBITS ALL TRAPS when written into the MASK REGISTER ; X0000 EQU 00000H X0003 EQU 00003H X0004 EQU 00004H TASKMSK EQU 00006H X0007 EQU 00007H T1CTASK EQU 00008H SPSAVE EQU 0000AH PCSAVE EQU 0000CH X000D EQU 0000DH X0010 EQU 00010H X0014 EQU 00014H X0016 EQU 00016H X0017 EQU 00017H X0018 EQU 00018H X001B EQU 0001BH X001F EQU 0001FH X0030 EQU 00030H X0032 EQU 00032H X0100 EQU 00100H X01B0 EQU 001B0H IMAGEMAP EQU 00200H X0202 EQU 00202H X03FF EQU 003FFH ; BIAS EQU 400H ; Bias for memory adjustment X0400 EQU 00400H FRONTPNL EQU 00401H ; SENSESWS EQU 00402H STATUS EQU 00403H ; TASKREG EQU 00402H MASKREG EQU 00403H ; ACTULMAP EQU 00600H X0602 EQU 00602H X0603 EQU 00603H X061E EQU 0061EH X061F EQU 0061FH X07FE EQU 007FEH X0800 EQU 00800H X0C09 EQU 00C09H-BIAS X080E EQU 0080EH X0C12 EQU 00C12H-BIAS X0821 EQU 00821H X0C21 EQU 00C21H-BIAS X0C38 EQU 00C38H-BIAS X083A EQU 0083AH X084E EQU 0084EH X0857 EQU 00857H X0C72 EQU 00C72H-BIAS X0873 EQU 00873H X0C85 EQU 00C85H-BIAS X0C88 EQU 00C88H-BIAS X0C93 EQU 00C93H-BIAS X0C9E EQU 00C9EH-BIAS X08A0 EQU 008A0H X0CBF EQU 00CBFH-BIAS X08D5 EQU 008D5H X0CDA EQU 00CDAH-BIAS X08E1 EQU 008E1H X0CE7 EQU 00CE7H-BIAS X0CF5 EQU 00CF5H-BIAS X0CFA EQU 00CFAH-BIAS X0916 EQU 00916H X091A EQU 0091AH X0D23 EQU 00D23H-BIAS X0D4A EQU 00D4AH-BIAS X096A EQU 0096AH X0986 EQU 00986H X0DCD EQU 00DCDH-BIAS X09F7 EQU 009F7H X0E01 EQU 00E01H-BIAS X0E06 EQU 00E06H-BIAS X0E25 EQU 00E25H-BIAS X0E34 EQU 00E34H-BIAS X0E37 EQU 00E37H-BIAS X0E39 EQU 00E39H-BIAS X0A3E EQU 00A3EH X0E46 EQU 00E46H-BIAS X0E54 EQU 00E54H-BIAS X0E5F EQU 00E5FH-BIAS X0E68 EQU 00E68H-BIAS X0E72 EQU 00E72H-BIAS X0A79 EQU 00A79H X0E7D EQU 00E7DH-BIAS X0E7F EQU 00E7FH-BIAS X0E85 EQU 00E85H-BIAS X0A87 EQU 00A87H X0AA3 EQU 00AA3H X0EA4 EQU 00EA4H-BIAS X0EAA EQU 00EAAH-BIAS X0EB4 EQU 00EB4H-BIAS X0EC8 EQU 00EC8H-BIAS X0ECD EQU 00ECDH-BIAS X0ED6 EQU 00ED6H-BIAS X0EDC EQU 00EDCH-BIAS X0EDD EQU 00EDDH-BIAS X0EF7 EQU 00EF7H-BIAS X0EFD EQU 00EFDH-BIAS X0F09 EQU 00F09H-BIAS X0B26 EQU 00B26H X0B2B EQU 00B2BH X0F40 EQU 00F40H-BIAS X0B9E EQU 00B9EH X0BAD EQU 00BADH X0BB3 EQU 00BB3H X0BC3 EQU 00BC3H X0FC9 EQU 00FC9H-BIAS X0C00 EQU 00C00H X1000 EQU 01000H X1048 EQU 01048H X104A EQU 0104AH X1050 EQU 01050H X1080 EQU 01080H X1081 EQU 01081H X108B EQU 0108BH X108C EQU 0108CH ; X1555 EQU 01555H XFAAA EQU 0FAAAH XFFF1 EQU 0FFF1H XFFFF EQU 0FFFFH ; PORT48 EQU 48H PORT49 EQU 49H PORT4A EQU 4AH PORT4B EQU 4BH PORT4C EQU 4CH PORT4D EQU 4DH PORT4E EQU 4EH PORT4F EQU 4FH PORT50 EQU 50H PORT51 EQU 51H PORT52 EQU 52H PORT53 EQU 53H PORT54 EQU 54H PORT55 EQU 55H PORT56 EQU 56H ; PORTFF EQU 0FFH HEXFF EQU 0FFH ; DEFINE SYMBOL FOR X'FF' ; JMPOPCOD EQU 0C3H ; DEFINE SYMBOL FOR JP (JUMP) OP-CODE ; ; ORG 0800H ; JR0800: OUT (PORTFF),A ; LD HL,X0400 ; Tickle.. LD A,(HL) ; ..all.. INC HL LD A,(HL) ; ..the.. INC HL LD A,(HL) ; ..read-only.. INC HL LD A,(HL) ; ..registers JR JR0857 ; Test sense switches for start-up mode ; JR080E: XOR A ; Clear A-reg to zero JR080F: OUT (PORTFF),A ; Write to ?? LD (MASKREG),A ; Clear task/segment mask LD (FRONTPNL),A ; Clear protection attributes LD (X0400),A CPL ; Toggle the data byte CP HEXFF ; If it was zero, JR Z,JR080F ; then re-write all ones JR JR0857 ; Test sense switches for start-up mode ; JR0821: XOR A LD HL,ACTULMAP ; Set pointer to Actual Memory Map OUT (PORTFF),A LD (HL),A ; Clear task 0 task/segment mask INC HL LD (HL),A ; Clear task 0 protection attributes CPL LD (HL),A ; Complement task 0 protection attributes DEC HL LD (HL),A ; Complement task 0 task/segment mask LD HL,X07FE ; Repeat the process for LAST entry in.. LD (HL),A ; ..Actual Memory Map INC HL LD (HL),A CPL LD (HL),A DEC HL LD (HL),A JR JR0857 ; Test sense switches for start-up mode ; JR083A: LD HL,X0000 OUT (PORTFF),A JR083F: XOR A LD (HL),A ; Write to byte at 0 CP (HL) ; This looks.. CPL ; ..like a.. LD (HL),A ; ..memory.. CP (HL) ; ..test, except.. BIT 0,H ; ..it only tests TWO bytes JR NZ,JR0857 ; Test sense switches for start-up mode LD HL,X03FF ; Then repeat the process.. JR JR083F ; ..for byte at 3FFH ; JR084E: XOR A OUT (PORTFF),A JR0851: LD (X0C00),A LD A,(X0C00) JR0857: ; Test sense switches for start-up mode LD A,(FRONTPNL) ; Get front-panel switch BIT 1,A ; Is front-panel switch set? JP Z,X08D5 ; Yes - go to initialize monitor LD A,(SENSESWS) ; No - Get Sense Switches (16C) BIT 2,A ; Is Power-Up-In-Monitor switch set? JP Z,X08D5 ; Yes - go to initialize monitor AND 70H ; No - Throw away irrelevant bits RRC A ; Multiply sense switch.. RRC A ; ..bits 2-4 by 2 LD HL,DIAGTABL ; Set pointer to Diagnostic Jump Table ADD A,L ; Use sense switch.. LD L,A ; ..as a vector into Jump Table L0872: JP (HL) ; Jump to computed address in Jump Table ; L0873: LD HL,SENSESWS LD A,0F0H LD (HL),A LD A,HEXFF LD (X061E),A LD A,03 LD (X061F),A LD (X0603),A XOR A LD (X0602),A OUT (PORTFF),A LD (XFFFF),A LD (HL),A LD (X1000),A OR 0F0H LD (HL),A LD A,(XFFFF) XOR A LD (HL),A LD A,(X1000) JR JR0857 ; JR08A0: LD HL,SENSESWS LD A,0A0H LD (HL),A LD A,0AAH LD (X061E),A LD A,03 LD (X061F),A LD (X0603),A LD A,055H LD (X0602),A OUT (PORTFF),A CPL LD (XFAAA),A LD A,050H LD (HL),A OR 05H LD (X1555),A LD A,0A0H LD (HL),A LD A,(XFAAA) LD A,050H LD (HL),A LD A,(X1555) JP X0857 ; JR08D5: CALL X08E1 ; Build default Memory Maps CALL X0B2B CALL X091A JP X01B0 ; JR08E1: LD HL,X0000 JR08E4: DEC HL ; Loop.. LD A,L ; ..until.. OR H ; ..HL-reg.. JR NZ,JR08E4 ; .is zero LD (HL),JMPOPCOD ; Build jump.. INC HL ; ..to.. LD (HL),00 ; ..location.. INC HL ; ..1000H at.. LD (HL),010H ; ..location 0000H LD HL,IMAGEMAP ; Set pointer to Image Memory Map LD (T1CTASK),HL ; Save pointer value JR08F7: XOR A ; Set task # and segment # to zero LD C,03 ; Set Protection Attribute to Full Access JR08FA: LD B,A ; Bank & Segment Mask is task & segment # CALL SETMAP ; Go to set Memory Maps INC A ; Bump Segment # AND 0FH ; Limit mask to bank 0 JR NZ,JR08FA ; Loop until all segments in task 0 are set LD A,10H ; Set task/segment pointer to task 1/seg. 0 LD B,00H ; Set bank/segment mask to bank & segment 0 JR0907: CALL SETMAP ; Go to set Memory Maps INC B ; Bump segment # in bank/segment mask.. INC A ; ..and task/segment pointer CP 20H ; Loop until all.. JR NZ,JR0907 ; ..segments in task 1 set JR0910: LD B,A ; Bank/segment mask becomes task/segment # CALL SETMAP ; Go to set Memory Maps INC A ; Bump task/segment #s CP 00 ; Loop thru remaining.. JR NZ,JR0910 ; ..tasks (2-15) RET ; JR091A: XOR A LD (X0602),A LD (X0202),A LD (X0016),A LD A,01AH LD (MASKREG),A LD (X0007),A LD HL,XFFFF ; Start at top of memory space.. JR092F: ; ..and tickle each byte until you LD A,0F0H ; ..find one that giggles! AND H ; Limit search to addresses JR Z,JR0946 ; ..above 0FFF (i.e., above the monitor ROM) LD (HL),A CP (HL) JR Z,JR093B ; Here he (she?) is! DEC HL JR JR092F ; JR093B: CPL ; Tickle him again, just to be sure LD (HL),A CP (HL) LD (X0017),HL ; Save his address JR Z,JR0954 ; Yep, he's really alive! DEC HL ; No, just rigor mortis.. JR JR092F ; ..go back and keep looking ; JR0946: LD HL,X0BAD ; No living memory found! LD (X0017),HL LD A,04DH LD (X0016),A JP X0A6B ; JR0954: LD A,(SENSESWS) AND 0F8H ; 11111000B LD D,A LD E,00 CP 00H JP Z,X0AA3 CP 08H JP Z,X09F7 CP 10H JR Z,JR09C9 JR096A: LD A,(SENSESWS) BIT 2,A LD A,01 LD (PCSAVE),DE LD (TASKMSK),A JR Z,JR0982 LD (X0602),A LD (X0202),A JR JR0986 ; JR0982: XOR A LD DE,X0916 JR0986: LD HL,X01B0 LD (HL),03EH INC HL LD (HL),A INC HL LD (HL),032H INC HL LD (HL),02 INC HL LD (HL),04 INC HL LD (HL),00 INC HL LD (HL),00 INC HL LD (HL),00 INC HL LD (HL),00 INC HL LD (HL),00 INC HL LD (HL),00 INC HL LD (HL),JMPOPCOD ; 0C3H INC HL LD (HL),E INC HL LD (HL),D XOR A OUT (PORT4F),A LD A,01FH OUT (PORT4C),A LD A,000H OUT (PORT4D),A LD A,00CH OUT (PORT4D),A LD A,HEXFF OUT (PORT4D),A LD A,020H OUT (PORT4C),A OUT (PORT4C),A RET ; JR09C9: LD H,010H JR09CB: LD BC,X0000 JR09CE: LD A,(X104A) CP 40H LD DE,(X1048) JR Z,JR096A CP HEXFF JR Z,JR09F1 DEC BC LD A,B OR C JR NZ,JR09CE DEC H JR NZ,JR09CB LD C,046H LD A,(X104A) LD B,A LD A,(X1048) LD D,A JR JR0A62 ; JR09F1: XOR A LD (X104A),A JR JR09CE ; JR09F7: LD BC,X0010 LD HL,X0BB3 LD DE,X1080 LDIR LD HL,X1050 LD (HL),080H XOR A INC HL LD (HL),A INC HL LD (HL),A OUT (PORT54),A LD DE,X0010 JR0A11: DEC D JR NZ,JR0A11 CALL X0A3E LD HL,XFFFF LD (X1081),HL LD A,006H LD (X108B),A LD A,001H LD (X108C),A CALL X0A3E LD DE,X1080 LD BC,X000D LD HL,X0BC3 LDIR CALL X0A3E LD DE,X0100 JP X096A ; JR0A3E: LD C,020H JR0A40: OUT (PORT55),A LD DE,X0000 JR0A45: LD A,(X108C) CP HEXFF RET Z DEC DE LD A,E OR D JR NZ,JR0A45 LD A,(X108C) CP 01 JR NZ,JR0A5A DEC C JR NZ,JR0A40 JR0A5A: POP DE LD C,048H LD B,A LD A,(X108B) LD D,A JR0A62: LD A,C LD HL,X0016 LD (HL),A INC HL LD (HL),B INC HL JR0A6A: LD (HL),D X0A6B EQU 00A6BH XOR A LD (TASKMSK),A LD DE,X0916 LD (PCSAVE),DE JP X0986 ; JR0A79: LD DE,X0000 JR0A7C: IN A,(PORT50) AND B RET NZ DEC DE LD A,D OR E JR NZ,JR0A7C JR JR0A99 ; JR0A87: LD H,010H JR0A89: LD DE,X0000 JR0A8C: IN A,(PORT50) AND B RET Z DEC DE LD A,D OR E JR NZ,JR0A8C DEC H JR NZ,JR0A89 POP HL JR0A99: LD C,044H IN A,(PORT50) LD B,A IN A,(PORT51) LD D,A JR JR0A62 ; JR0AA3: LD A,0FCH OUT (PORT52),A LD A,005H OUT (PORT50),A LD B,020H CALL X0A87 LD A,007H OUT (PORT50),A JR0AB4: IN A,(PORT50) RRA JR NC,JR0AC8 LD A,0F8H OUT (PORT52),A LD A,0FCH OUT (PORT52),A LD B,004H CALL X0A79 JR JR0AB4 ; JR0AC8: IN A,(PORT50) LD C,A JR0ACB: IN A,(PORT50) SUB C JR Z,JR0ACB JR0AD0: IN A,(PORT50) SUB C JR NZ,JR0AD0 JR0AD5: IN A,(PORT50) SUB C JR Z,JR0AD5 LD A,008H OUT (PORT51),A XOR A OUT (PORT53),A OUT (PORT53),A INC A OUT (PORT53),A LD A,080H OUT (PORT53),A LD A,001H OUT (PORT51),A LD B,002H CALL X0A79 IN A,(PORT53) LD L,A LD E,A IN A,(PORT53) LD H,A LD D,A AND 0F0H JR Z,JR0B10 XOR A LD (X0602),A JR0B03: IN A,(PORT53) LD (DE),A INC E JR NZ,JR0B03 LD D,H LD E,L LD A,001H JP X096A ; JR0B10: LD A,D AND 0FH OR 010H LD D,A JR JR0B03 SETMAP: ; Update memory maps: ; ; On entering: ; ; A = Task ID in high order nibble, ; ; Real Segment # in low nibble ; ; B = Bank # in High nibble, ; ; Virtual Segment # in low nibble ; ; C = Protection attributes: ; ; 00 = No access ; ; 01 = Read only ; ; 02 = Execute only ; ; 03 = Full access ; ; 04 = No access - R10 set ; ; 05 = Read only - R10 set ; ; 06 = Execute only - R10 set ; ; 07 = Full access - R10 set ; ; ; On exiting: ; ; Image Memory Map at 0200H AND ; ; Actual Memory Map at 0600H updated ; ; ; Scratch Registers: ; ; HL ; ; DE ; LD L,A ; Multiply.. LD H,00 ; ..task and segment.. ADD HL,HL ; ..by 2 to get displacement.. EX DE,HL ; ..into Memory Maps LD HL,ACTULMAP ; Set pointer to Actual Memory Map CALL RX0B26 ; Update indicated Memory Map LD HL,IMAGEMAP ; Set pointer to Image Memory Map RX0B26: ; Update indicated Memory Map ADD HL,DE ; Compute effective address LD (HL),B ; Store segment mask into map INC HL ; Bump to Protection Attribute LD (HL),C ; Set Protection Attribute RET ; JR0B2B: LD D,03 JR0B2D: LD A,D OUT (PORT4F),A XOR A OUT (PORT4D),A OUT (PORT49),A DEC D JR NZ,JR0B2D OUT (PORT4F),A IN A,(PORT49) RLCA RLCA RLCA AND 07 CP 07 LD D,00 JR Z,JR0B52 LD HL,X0BA5 ADD A,A LD E,A ADD HL,DE LD C,(HL) INC HL LD B,(HL) JR JR0B55 ; JR0B52: LD BC,PCSAVE JR0B55: INC D LD A,D OUT (PORT4F),A LD A,087H OUT (PORT4B),A LD A,B OUT (PORT49),A LD A,C OUT (PORT48),A LD A,007H OUT (PORT4B),A LD A,010H OUT (PORT4C),A IN A,(PORT48) XOR A OUT (PORT48),A CALL X0B9E IN A,(PORT48) XOR A OUT (PORT48),A CALL X0B9E JR0B7B: IN A,(PORT4D) AND 01 JR Z,JR0B7B IN A,(PORT48) CP 00 JR Z,JR0B96 PUSH AF LD A,055H LD (X0016),A LD A,D LD (X0018),A POP AF LD (X0017),A XOR A JR0B96: OUT (PORT4C),A LD A,D CP 03 RET Z JR JR0B55 ; JR0B9E: IN A,(PORT4D) AND 20H JR Z,JR0B9E RET ; X0BA5 EQU 00BA5H DB 017H,004H,080H ;0BA5 DB 001H,060H,000H,030H,000H,018H,000H,00CH ;0BA8 DB 000H,006H,000H,010H,000H,000H,03CH,000H ;0BB0 DB 001H,000H,000H,01EH,0C8H,003H,004H,000H DB 080H,000H,000H,000H,000H,000H,07CH,000H ;0BC0 DB 001H,000H,000H,000H,000H,000H,000H,000H ; DIAGTABL: ; Diagnostic JUMP TABLE with I x 4 Vector ; ; Based upon sense switches S2-S4=======VVV JP X0800 ; Read Switches 000 NOP ; Full system reset???? JR0BD4: JP X080E ; R/W S-100 Bus 001 NOP ; Diagnostic system reset???? JR0BD8: JP X0821 ; R/W S-100 Bus 010 NOP JR0BDC: JP X083A ; R/W Floating-Point Processor 011 NOP JR0BE0: JP X084E ; Write R/W RAMs 100 NOP JR0BE4: JP X0873 ; Write Map RAMs 101 NOP JR0BE8: JP X08A0 ; Write Registers 110 NOP JR0BEC: JR JR0BF9 ; Read Registers 111 NOP NOP JR0BF0: LD HL,X104A LD A,0 ; Set bank/segment mask of task 0 to 0/0 LD (X0602),A ; (This maps 1000H-1FFFH over 0000H-0FFFH INC A JR0BF9: LD SP,IMAGEMAP ; Use area below Image Map for Stack JP X0857 NOP ; ; JR0C00: JP X0C21 ;0C00 ; Task dispatcher entry point JP X0C12 ;0C03 ; Get Task Save Area Address JP X0CE7 ;0C06 ; Set Memory Map attributes JP X0C9E ;0C09 ; Restore prior task JP X0CDA ;0C0C ; Get Memory Map attributes JP X0C12 ;0C0F ; Get Task Save Area Address JP X0CFA ;0C12 ; Get Task Save Area Address JP X0C93 ;0C15 ; Reset Memory Map & Restore prior task JP X0C09 ;0C18 ; Restore prior task JP X0C85 ;0C1B ; Dispatch task (task # LOADED) JP X0C88 ;0C1E ; Dispatch task (task # NOT loaded) ; RX0C21: LD DE,XFFF1 ; Load -15 into DE reg POP HL ; Pop the top of stack (return addr?) ADD HL,DE ; Add in the -15 LD (PCSAVE),HL ; Save at 000CH (return address) LD A,(TASKMSK) ; Get current task # CP 00 ; Is it task 0?? JP Z,X0C72 ; Yes - go to Initialize for task 0 POP DE ; No - Initialize for NON-Task 0 POP HL POP AF LD SP,(T1CTASK) ; Load new Stack Pointer value EX AF,AF' ; Swap.. EXX ; ..regs PUSH HL ; Save ALL the regs PUSH DE PUSH BC PUSH AF PUSH IY PUSH IX LD A,I ; Load interrupt vector PUSH AF ; Save interrupt vector EX AF,AF' ; Swap regs.. EXX ; ..again!! PUSH HL ; Save these also PUSH DE PUSH BC PUSH AF LD HL,(TASKMSK) ; Load.. LD DE,(SPSAVE) ; ..current task.. LD BC,(PCSAVE) ; ..status words PUSH DE ; Save them.. PUSH BC ; ..on the.. PUSH HL ; ..Stack LD (X0014),SP ; Save the stack pointer LD A,L ; Is Task # = 0 CP 00 JR Z,JR0C69 ; Yes - bypass front-panel-stop check LD A,(STATUS) ; Read status reg. BIT 4,A ; Is it front-panel stop? JR NZ,JR0C7C ; No - JR0C69: ; Front panel stop XOR A ; Set current.. LD (TASKMSK),A ; ..task = 0 CALL X0C12 ; Go to get Task 0 save area address JR JR0C9E ; Dispatch Task 0 ; JR0C72: ; Initialize for task 0 POP DE POP HL POP AF LD SP,(SPSAVE) ; Load stack pointer JP X0C38 ; Return to main line ; JR0C7C: XOR A ; Set current.. LD (TASKMSK),A ; ..task = 0 CALL X0000 JR JR0C9E ; Dispatch indicated task ; JR0C85: ; Dispatch an active task LD A,(TASKMSK) ; Get current task # R0C88: LD (TASKREG),A ; Load into Task Register NOP ; Spin.. NOP NOP ; ..off.. NOP NOP ; ..seven.. NOP NOP ; ..instructions RET ; Return to dispatched task ; JR0C93: LD HL,IMAGEMAP ; Set pointer to Image Memory Map LD DE,ACTULMAP ; Set pointer to Actual Memory Map LD BC,X001F ; Set length to one task LDIR ; Copy task's map from Image Map to Actual Map JR0C9E: ; Restore prior task's status and return to it LD HL,X0000 ; Get Stack Pointer.. ADD HL,SP ; ..into HL regs LD SP,HL POP HL LD (TASKMSK),HL ; Restore.. POP HL LD (PCSAVE),HL ; ..previous task's.. POP HL LD (SPSAVE),HL ; ..status words.. POP AF POP BC POP DE POP HL ; ..and registers EX AF,AF' EXX POP AF ; Restore.. LD I,A ; ..interrupt vector POP IX ; ..and.. POP IY ; .index regs LD HL,(PCSAVE) ; Recover previous task's return address LD (X0004),HL ; Build a jump.. LD A,JMPOPCOD ; ..to the.. LD (X0003),A ; ..return address POP AF POP BC POP DE LD HL,(TASKMSK) LD (TASKREG),HL POP HL EX AF,AF' EXX LD SP,(SPSAVE) JP X0003 ; Go to the return jump ; JR0CDA: LD L,A ; Multiply.. LD H,00 ; ..task and segment.. ADD HL,HL ; ..by 2 to get displacement.. EX DE,HL ; ..into Memory Maps LD HL,IMAGEMAP ; Set pointer to Image Memory Map ADD HL,DE ; Bump to indicated task and segment LD B,(HL) ; Get map mask INC HL ; Bump pointer to Protection Attribute LD C,(HL) ; Get Protection Attribute RET ; JR0CE7: LD L,A ; Multiply.. LD H,00 ; ..task and segment.. ADD HL,HL ; ..by 2 to get displacement.. EX DE,HL ; ..into Memory Maps LD HL,ACTULMAP ; Set pointer to Actual Memory Map CALL X0CF5 LD HL,IMAGEMAP ; Set pointer to Image Memory Map ADD HL,DE ; Compute effective address LD (HL),B ; Store segment mask into map INC HL ; Bump to Protection Attribute LD (HL),C ; Set Protection Attribute RET ; JR0CFA: ; Error condition entry point LD (X0030),SP ; Save stack pointer LD IY,(X0030) ; Load it into IY-reg also LD SP,X0032 ; Load new stack pointer value LD HL,(X0014) ; Load new HL.. LD DE,X001B ; ..and DE values PUSH HL ; Place.. ADD HL,DE ; ..the sum of.. EX DE,HL ; ..HL and DE in DE POP HL LD BC,X0D23 ; Set Top-of-Stack.. PUSH BC ; ..to default return address JP X0D4A ; Go to display Condition Code and.. ; ; ..enter Monitor main loop ; JR0D16: LD A,(X0016) ; JR0D19: LD C,A ; Write.. CALL X0E39 ; ..data byte LD HL,(X0017) ; Load ? into HL.. CALL X0EC8 ; ..and display it in Hex LD SP,X0032 ; Initialize Stack Pointer LD DE,X0D23 ; Load Default Return Address.. PUSH DE ; ..to point to Stack Pointer reset CALL X0E06 ; Force new line, test for any input LD C,':' ; Load command prompt CALL X0E39 ; Write prompt JR0D32: CALL X0F09 ; Call routine to read command character OR A ; Loop until some input JR Z,JR0D32 CP 'z'+1 ; Is input invalid? JP NC,X0E25 ; Yes - Go to display a "?" LD C,02H ; No - it's OK, so set default.. ; ; ..parameter count and decode the command: CP 'D' ; (D)isplay.. JR Z,JR0D47 CP 'd' ; ..request? JR NZ,JR0D60 ; No - go check for (F)ill request JR0D47: ; (D)isplay command: CALL X0E01 ; Go to get two Hex parameters JR0D4A: CALL X0E06 ; Force new line, test for any input CALL X0EC8 ; Display data address in HL LD B,010H ; Load byte count per line (16) JR0D52: CALL X0E37 ; Go to write a space LD A,(HL) ; Get indicated data byte CALL X0ECD ; Display byte in hex CALL X0EA4 ; Bump HL pointer DJNZ JR0D52 ; Loop on byte counter for 16 bytes JR JR0D4A ; Repeat line display until end address reached ; JR0D60: CP 'F' ; (F)ill.. JR Z,JR0D68 CP 'f' ; ..request? JR NZ,JR0D75 ; No - go check for (G)o request JR0D68: ; (F)ill command: CALL X0E72 ; Go to get three hex operands JR0D6B: LD (HL),C ; Insert data byte into indicated memory byte CALL X0EAA ; Go to bump memory pointer and test for end JR NC,JR0D6B ; Loop until end of data POP DE ; Throw away default return address JP X0D23 ; Loop back to get next command ; JR0D75: CP 'G' ; (G)o.. JR Z,JR0D7D CP 'g' ; ..request? JR NZ,JR0D85 ; No - go check for (T)est memory request JR0D7D: ; (G)o command: CALL X0E7D ; Go to get ONE Hex operand (in HL) CALL X0E06 ; Force new line, test for any input POP HL ; Pop operand into HL JP (HL) ; GO to that address ; JR0D85: CP 'T' ; (T)est memory.. JR Z,JR0D8D CP 't' ; ..request JR NZ,JR0DA9 ; No - go check for (M)ove command JR0D8D: ; (T)est memory command: CALL X0E01 ; Go to get hex operands.. ; ; ..(Start and End addresses) JR0D90: ; Memory test loop: LD A,(HL) ; Get indicated byte LD B,A ; Save it CPL ; Complement data byte LD (HL),A ; Store back into memory location XOR (HL) ; Complement memory location JR Z,JR0DA3 ; If successful, go to restore data byte PUSH DE ; Error - save DE regs LD E,A ; Move data byte into E-reg for binary display CALL X0E34 ; Write a space CALL X0F40 ; Go to write data byte in binary CALL X0E06 ; Force new line, test for any input POP DE ; Restore DE regs JR0DA3: LD (HL),B ; Restore original data byte CALL X0EA4 ; Bump HL pointer JR JR0D90 ; Loop until end address reached ; JR0DA9: CP 'M' ; (M)ove.. JR Z,JR0DB1 CP 'm' ; ..command? JR NZ,JR0DC3 ; No - go check for (S)et memory value JR0DB1: ; (M)ove command: CALL X0E72 ; Get source, end, and target addresses JR0DB4: LD A,(HL) ; Get source byte LD (BC),A ; Store at target location INC BC ; Bump target address CALL X0EA4 ; Bump source address (HL), test for end JR JR0DB4 ; Loop until end reached ; JR0DBC: ; UNREFERENCED ROUTINE!!!!!!!!!!!!!!!!!! LD (IX+0),A INC IX DEC E RET ; JR0DC3: CP 'S' ; (S)et memory.. JP Z,X0DCD CP 's' ; ..value JP NZ,X0EB4 ; No - go check for (H)ex arithmetic CALL X0E7D ; Yes - Go to get one hex operand CALL X0EFD ; Go test for JP C,X0E25 ; If one entered, then abort with "?" POP HL ; Load the Start address into HL JR0DD7: LD A,(HL) ; Load the indicated byte CALL X0ECD ; Display the byte in Hex LD C,'-' ; Set up to display "-" character.. CALL X0EF7 ; Go to write data byte and read keyboard RET C ; Return to caller if "^C" entered ; ; If "N", ",", or " " entered then.. JR Z,JR0DF3 ; ..go to bump Memory Pointer to next byte PUSH HL ; Save current memory address LD HL,X0000 ; Clear hex conversion reg LD C,01H ; Set operand count CALL X0E85 ; Go to get a hex operand POP DE ; recover returned operand into DE reg POP HL ; Restore Memory Pointer LD (HL),E ; Insert input byte into memory location LD A,B ; Was a entered? CP 0DH RET Z ; Yes - return to caller JR0DF3: INC HL ; No - bump memory pointer CALL X0E06 ; Force new line, test for any input PUSH HL ; Save memory pointer CALL X0EC8 ; Go to display current memory address CALL X0E37 ; Go to write a space POP HL ; Recover memory pointer JR JR0DD7 ; Loop until user signals end ; JR0E01: ; Get indicated number of operands.. ; ; ..and force new line, test for any keyboard input CALL X0E7F ; Go to get hex operands from user POP DE ; Recover the operands into.. POP HL ; ..DE and HL regs JR0E06: ; Force new line, interrogate keyboard for any input PUSH HL PUSH BC LD C,0DH ; Load CALL X0E39 ; Go to write it LD C,0AH ; Load CALL X0E39 ; Go to write it POP BC POP HL CALL X0E54 ; Call keyboard status routine OR A ; Is there character ready? RET Z ; No - Return to caller JR0E19: CALL X0E46 ; Yes - Go to read the character AND 7FH ; Strip "parity" bit CP 13H ; Is data byte "^S" (pause display toggle)? JR Z,JR0E19 ; Yes - loop until there's something else CP 03 ; Is data byte "^C"? RET NZ ; No - return to caller CALL X0EDC ; Yes - Call a RET (for some reason!!!) LD DE,X0E25 ; Reset default return.. PUSH DE ; ..address to return HERE!! LD C,'?' ; Load "?" CALL X0E39 ; Display it JP X0D23 ; Loop back to start of Monitor main line ; JR0E34: ; Write a byte in hex, followed by a space CALL X0EC8 ; Go to display A-reg byte in hex R0E37: ; Write a space to the terminal port LD C,' ' ; Load a space into output register (C-reg) R0E39: ; Write whatever is in the C-reg to the terminal CALL X0E5F ; Go to wake up the Terminal port JR0E3C: ; Write Byte in C-reg to terminal IN A,(PORT4D) ; Get Output Port status AND 20H ; Is a the port ready? JR Z,JR0E3C ; No - loop until it is LD A,C ; Yes - load data byte into A-reg OUT (PORT48),A ; Write it to the port RET ; JR0E46: ; Read a data byte from the Terminal Input Port CALL X0E5F ; Go to wake up the Terminal port JR0E49: IN A,(PORT4D) ; Get Input Port status AND 01H ; Is a the port ready? JR Z,JR0E49 ; No - loop until it is IN A,(PORT48) ; Yes - Read the data byte AND 7FH ; Strip the "parity" bit RET ; JR0E54: CALL X0E5F ; Go to wake up the Terminal port IN A,(PORT4D) ; Get Input Port status AND 01H ; Is a the port ready? RET Z ; No - return to caller LD A,HEXFF ; Yes - Signal so by setting A-reg = HEXFF RET ; JR0E5F: ; Wake up the Terminal port LD A,09H OUT (PORT4F),A LD A,07H OUT (PORT4B),A RET ; JR0E68: ; Convert low order nibble of A-reg to Hex AND 0FH ; Strip out high nibble ADD A,090H DAA ADC A,040H DAA LD C,A ; Place result in C-reg RET ; JR0E72: ; Get three hex operands from user INC C ; Bump Operand count to three CALL X0E7F ; Go to get the operands CALL X0E06 ; Go to force new line, test for any input POP BC ; Recover the.. POP DE ; ..three operands.. POP HL ; ..into the double-word registers RET ; JR0E7D: ; Get one hex operand from user LD C,01 ; Reset operand count to ONE JR0E7F: ; Get a hex operand from the keyboard LD HL,X0000 ; Zero the operand work register JR0E82: CALL X0F09 ; Read an operand byte from keyboard LD B,A ; Save the data byte CALL X0EDD ; Convert from Hex to binary R0E86: JR C,JR0E93 ; Exit on error or end of operand ADD HL,HL ; Shift the.. ADD HL,HL ; ..work-register.. ADD HL,HL ; ..left.. ADD HL,HL ; ..one nibble OR L ; Combine high order nibble in L-reg.. JR0E90: LD L,A ; ..with low-order nibble in A-reg JR JR0E82 ; Loop until a delimiter found at R0E86 ; JR0E93: EX (SP),HL ; Swap result (in HL) onto Stack.. PUSH HL ; ..BELOW the return address LD A,B ; Restore the data byte CALL X0EFD ; Go test for a JR NC,JR0E9D ; If there was none, then continue DEC C ; If there was a then decrement RET Z ; ..operand count and return if zero JR0E9D: JP NZ,X0E25 ; If not zero, go to restart main loop DEC C ; If there was no then decrement.. JR NZ,JR0E7F ; ..operand count and get next operand.. RET ; ..until operand count goes to zero ; JR0EA4: ; Bump Memory Pointer reg and test for end CALL X0EAA ; Go to bump Memory Pointer RET NC ; If no errors then return to caller POP DE ; If any errors then throw away.. RET ; ..caller's return address and.. ; ; ..return to last previous caller ; JR0EAA: ; Bump HL reg, test for memory wrap or = to DE regs INC HL ; Bump reg LD A,H ; Did.. OR L ; ..HL-reg.. SCF ; ..go to zero? RET Z ; Yes - return with carry flag set LD A,E ; No - Did HL-reg.. SUB L ; ..bump.. LD A,D ; ..past.. SBC A,H ; ..DE-reg RET ; Yes - return with carry set; ; ; No - return with carry cleared ; JR0EB4: CP 'H' ; (H)ex.. JR Z,JR0EBC CP 'h' ; ..arithmetic? JR NZ,JR0F23 ; No - go check for (O)ut or (I)n command JR0EBC: ; (H)ex arithmetic command: CALL X0E01 ; Go to get two Hex parameters PUSH HL ; Save first operand ADD HL,DE ; Compute the operands' sum CALL X0E34 ; Go to display the Hex value of the result POP HL ; Restore the first operand OR A ; Clear the carry flag SBC HL,DE ; Compute the operands' difference LD A,H ; Display high-order.. CALL X0ECD ; ..byte in Hex LD A,L ; Display low-order byte in Hex JR0ECD: ; Display the data byte in Hex PUSH AF ; Save low nibble RRCA ; Move.. RRCA ; ..High nibble.. RRCA ; ..into.. RRCA ; ..Low nibble CALL X0ED6 ; Go to display it POP AF ; Restore low nibble JR0ED6: ; Display Low nibble in A-reg in Hex CALL X0E68 ; Go convert low nibble to hex JP X0E39 ; Go display it and return to caller ; JR0EDC: ; Special RET instruction?!?!?! RET ; JR0EDD: ; Convert HEX input byte into BINARY CP 'a' ; Is data byte lower-case? JR C,JR0EE7 ; No - go to compute binary CP 'z'+1 ; Maybe - Is it a letter at all? CCF ; No - return to caller.. RET C ; ..with carry flag set SUB 'a'-'A' ; Yes - convert from lower to upper case JR0EE7: SUB '0' ; Make relative to BINARY zero RET C ; If < '0' then return with carry set CP ('F'+1)-'0' ; If > 'F'.. CCF ; ..then.. RET C ; ..return with carry set CP 10 ; If < 10.. CCF ; ..then.. RET NC ; ..return with carry RE-set.. SUB 7 ; ..else.. CP 10 ; ..adjust for bias between "0" and "A" RET ; Return with carry set if > 10 ; JR0EF7: ; Write (S)et prompt to terminal, get user response CALL X0E39 ; Go to display prompt byte CALL X0F09 ; Go to get input from user F0EFD: CP ' ' ; User enter a space? RET Z ; Yes - return to caller CP ',' ; No - a comma? RET Z ; Yes - return to caller CP 0DH ; No - user enter ? SCF RET Z ; Yes - return to caller with carry set CCF ; No - return to caller with carry clear RET ; JR0F09: ; Read command or operand byte CALL X0E46 ; Go to read from terminal INC A RET Z DEC A AND 7FH ; Strip "parity" byte RET Z ; Exit if "null" input CP 00 ; Test it again, I guess??? RET Z CP 'N' ; Still not zero, is it a "N".. RET Z CP 'n' ; ..or a "n"? RET Z ; Yes - return to caller PUSH BC ; No - Save BC-regs LD C,A ; Display the.. CALL X0E39 ; ..input byte LD A,C ; Restore input byte to A-reg POP BC ; Restore BC-regs RET ; JR0F23: CP 'O' ; (O)ut.. JR Z,JR0F51 CP 'o' ; ..command? JR Z,JR0F51 ; OR CP 'I' ; (I)n.. JR Z,JR0F35 CP 'i' ; ..command? JR Z,JR0F35 JR JR0F59 ; No - go check for (V)erify command ; JR0F35: ; (I)n port command: CALL X0E7D ; Go to get ONE hex operand LD C,0AH ; Load a Line-Feed character to output reg CALL X0E39 ; Go to force line-feed POP BC ; Recover the operand value into C-reg IN E,(C) ; Read from designated port LD B,08H ; Load Bit count CALL X0E37 ; Go to write a space JR0F45: SLA E ; Shift first bit into carry LD A,018H ; Load (ORD ("0") / 2) into A-reg ADC A,A ; A-reg := ((ORD ("0") / 2) * 2) + Data Bit LD C,A ; Load result byte into Output-reg (C-reg) CALL X0E39 ; Go to write it DJNZ JR0F45 ; Loop for bit count (8) RET ; JR0F51: ; (O)ut port command: CALL X0E7F ; Go to get two operands POP DE ; Load second operand (data byte) into E-reg POP BC ; Load first operand (port address) into C-reg OUT (C),E ; Write data byte to port RET ; JR0F59: CP 'V' ; (V)erify.. JR Z,JR0F61 CP 'v' ; ..command? JR NZ,JR0F73 ; No - go check for (C)ontinue command JR0F61: ; (V)erify command: CALL X0E72 ; Go to get THREE operands JR0F64: LD A,(BC) ; Load indicated Source byte into work-reg CP (HL) ; Compare to indicated Target byte JR Z,JR0F6D ; If equal, go to bump both pointers PUSH BC ; Save source pointer CALL X0FC9 ; Go to display HL address and data byte POP BC ; Restore source pointer JR0F6D: INC BC ; Bump source pointer CALL X0EA4 ; Go to bump target pointer JR JR0F64 ; Loop until Target pointer exceeds End Address ; JR0F73: CP 'C' ; (C)ontinue.. JR Z,JR0F7B CP 'c' ; ..command? JR NZ,JR0F86 ; No - go check for (U) single step command JR0F7B: ; (C)ontinue command: LD SP,IY ; Recover stack pointer POP DE POP HL LD A,H OR 08H LD H,A PUSH HL PUSH DE RET ; JR0F86: CP 'U' ; (U) Single step.. JR Z,JR0F8E CP 'u' ; ..command? JR NZ,JR0F99 ; No - go check for (B)oot command JR0F8E: ; (U) Single-step command: LD SP,IY POP DE POP HL LD A,H AND 0F6H LD H,A PUSH HL PUSH DE RET ; JR0F99: ; Test for "BOOT" command CP 'B' ; (B)oot.. JR Z,JR0FA2 CP 'b' ; ..command? JP NZ,X0E25 ; No - go to restart Monitor main loop JR0FA2: ; (B)oot command: EX AF,AF' EXX XOR A INC A LD (X0602),A LD (X0202),A LD A,(SENSESWS) AND 0F8H CP 00 ; F800H JR Z,JR0FC3 CP 08H ; F000H JR Z,JR0FC3 CP 10H ; E800H JR Z,JR0FC3 LD H,A ; LD L,00 JP X0CBF ; JR0FC3: LD HL,(PCSAVE) JP X0CBF ; R0FC9: LD B,A ; Save data byte CALL X0E34 ; Go to display HL reg value in Hex LD A,(HL) ; Load indicated byte into A-reg CALL X0ECD ; Go to display indicated byte in Hex CALL X0E37 ; Go to write a space LD A,B ; Recover data byte CALL X0ECD ; Go to display data byte in Hex JP X0E06 ; Go to force new line and check for input ; JR0FDB: DB 000H,000H,000H,000H,000H ;0FDB DB 000H,000H,000H,000H,000H,000H,000H,000H ;0FE0 DB 000H,000H,000H,000H,000H,0FFH,0FFH,0FFH ;0FE8 DB 000H ;0FF0 ; JR0FF1: ; UNREFERENCED ROUTINE!!!!!!!!!!!!!!!!!! LD (SPSAVE),SP LD SP,X0014 PUSH AF PUSH HL PUSH DE NOP CALL X0C21 HALT ; END