.TITLE SCMPKB, 'P005235 7/14/76' ;************************************************************************ ;* Typed from scanned listing Paul Bigwood G3WYW September 2015 * ;* BOARD * ;* PROM # ADDRESS COORDINATE BOARD # * ;* * ;* 460305235-001 0000 5A 9804879 * ;* * ;************************************************************************ ; RAM = 0F00 DISP = 0D00 ; SEGMENT ASSIGNMENTS SA = 1 SB = 2 SC = 4 SD = 8 SE = 16 SF = 32 DG = 64 ; 7 SEGMENT CONVERSION N0 = SA+SB+SC+SD+SE+SF N1 = SB+SC N2 = SA+SB+SD+SE+SG N3 = SA+SB+SC+SD+SG N4 = SB+SC+SF+SG N5 = SA+SC+SD+SF+SG N6 = SA+SC+SD+SE+SF+SG N7 = SA+SB+SC N8 = SA+SB+SC+SD+SE+SF+SG N9 = SA+SB+SC+SF+SG NA = SA+SB+SC+SE+SF+SG NB = SC+SD+SE+SF+SG NC = SA+SD+SE+SG ND = SB+SC+SD+SE+SG NE = SA+SD+SE+SF+SG NF = SA+SE+SF+SG DASH = SG KE = NE KR = SE+SG K0 = SC+SD+SE+SG .PAGE ' HARDWARE FOR KEYBOARD' ; FUNCTION DATA KYB FUNCTION ; 0 080 0 ; 1 081 1 ; 2 082 2 ; 3 083 3 ; 4 084 4 ; 5 085 5 ; 6 086 6 ; 7 087 7 ; 8 040 8 ; 9 041 9 ; A 010 + ; B 011 - ; C 012 MUL ; D 013 DIV ; E 016 SQUARE ; F 017 SQRT ; GO 022 % ; MEM 023 = ; ABORT 024 CE/C ; TERM 027 . ; RAM POINTER USED BY KITBUG, P3 IS SAVED ELSEWHERE P1H = 0FF9 P1L = 0FFA P2H = 0FFB P2L = 0FFC A = 0FFD E = 0FFE S = 0FFF ; COMMANDS ;ABORT ; THIS ABORTS THE PRESENT OPERATION DISPLAYS -. ;MEM: ; ALLOWS USER TO READ/MODIFY MEMORY. ; ADDRESS IS ENTERED UNTIL TERM THEN DATA IS ENTERED. ; TO WRITE DATE INTO MEMORY TERM IS PUSHED. ; DATA IS READ TO CHECK IF IT GOT WRITTEN INTO RAM. ;GO: ; ADDRESS IS ENTERED UNTIL TERM. ; THE REGISTERS ARE LOADED FROM RAM AND PROGRAM ; IS TRANSFERRED USING XPPC P3. ; TO GET BACK DO A XPPC P3. .PAGE ' INITIALISE ' NOP INIT: JMP START ; DEBUG EXIT ; RESTORE ENVIRONMENT GOOUT: LD ADH(2) ;GET GO ADDRESS XPAH P3 LD ADL(2) XPAL P3 LD @-1(3) ;FIX GO ADDRESS LD E XAE LD P1L XPAL 1 LD P1H XPAH 1 LD P2H XPAH 2 LD S CAS LD A XPPC P3 ;TO GET BACK ; ENTRY POINT FOR DEBUG START: ST A ;SAVE STATUS LDE ST E CSA ST S XPAH 1 ST P1H XPAL 1 ST P1L LDI H(RAM) ;SET P2 TO POINT TO RAM XPAH 2 ST P2H LDI L(RAM) XPAL 2 ST P2L LD @1(3) ;BUMP P3 FOR RETURN. XPAL 3 ;SAVE P3 ST ADL(2) XPAH 3 ST ADH(2) .PAGE ; ABORT SEQUENCE ABORT: LDI 0 ST D3(2) ST D4(2) ST D9(2) LDI DASH ;SET SEGMENTS TO '-' ST DL(2) ST DH(2) ST ADLL(2) ST ADLH(2) ST ADHL(2) ST ADHH(2) WAIT: JS 3,KYBD ;DISPLAY AND READ KEYBOARD JMP WCK ;COMMAND RETURN JMP ABORT ;RETURN FOR NUMBER. WCK: XRI 07 ;CHECK IF MEM. JZ MEM XRI 07 ;CHECK IF GO. JNZ ABORT .PAGE ; GO WAS PUSHED ; GOT TO USER PROGRAM GO: LDI -1 ;SET FIRST FLAG. ST DDTA(2) LDI DASH ;SET DATA TO DASH. ST DL(2) ST DH(2) GOL: LDI L(DISPA-1) ;FIX ADDRESS SEG. XPAL 3 XPPC 3 ;DO DISPLAY AND KEYBRD. JMP GOCK ;COMMAND RETURN LDI L(ADR)-1 ;SET ADDRESS. XPAL 3 XPPC 3 JMP GOL ;NOT DONE GOCK: XRI 03 ;CHECK FOR TERM. JZ GOOUT ;ERROR IS NO TERM. ; INCORRECT SEQUENCE ; DISPLAY ERRROR WAIT FOR NEW INPUT ERROR: LDI KE ;FILL WITH ERROR ST ADHH(2) LDI KR ST ADHL(2) ST ADLH(2) ST D4(4) LDI KO ST ADLL(2) LDI 0 ST D3(2) ST DH(2) ST DL(2) JMP WAIT .PAGE ' MEMORY TRANSACTIONS ' DTACK: LD NEXT(2) ;CHECK IF DATA FIELD. JNZ DATA ;ADDRESS DONE. MEMDN: LD ADH(2) ;PUT WORD IN MEM XPAH 1 LD ADL(2) XPAH 1 LD WORD(2) ST (1) JMP MEM MEMCK: XRI 06 ;CHECK FOR GO. JZ ERROR ;CAN NOT GO NOW. XRI 05 ;CHECK FOR TERM. JZ TACK ;CHECK FOR DONE. ILD ADL(2) ;UPDATE ADDRESS LOW. JNZ MEM ;CHECK IF UPDATE HI. ILD ADH(2) ; MEM KEY PUSHED MEM: LDI -1 ;SET FIRST FLAG ST NEXT(2) ;SET FLAS FOR ADDRESS NOW. ST DDTA(2) MEML: LD ADH(2) XPAL 1 ;SET P1 FOR MEM ADDRESS LD ADL(2) XPAL 1 LD (1) ST WORD(2) ;SAVE MEM DATA. LDI L(DISPD)-1 ;FIX DATA SEG. XPAL 3 XPPC 3 ;GO TO DISPD SET SEG FOR DATA. JMP MEMCK ;COMMAND RETURN LDI L(ADR)-1 ;MAKE ADDRESS XPAL 3 XPPC 3 JMP MEML ;GET NEXT CHAR. DATA: LDI -1 ;SET FIRST FLAG ST DDTA(2) LD ADR(2) ;SET P1 TO MEMORY ADDRESS. XPAL 1 LD ADL(2) XPAL 1 LD (1) ;READ DATA WORD. ST WORD(2) ;SAVE FOR DISPLAY. .PAGE DATAL: LDI L(DISPD)-1 ;FIX DATA SEG. XPAL 3 XPPC 3 ; FIX DATA SEG-GO TO DISPD. JMP MEMCK ;CHAR RETURN. LDI 4 ;SET COUNTER FOR NUMBER OF SHIFTS. ST CNT(2) ILD DDTA(2) ;CHECK IF FIRST. JNZ DNFST LDI 0 ;ZERO WORD FOR FIRST. ST WORD(2) ST NEXT(2) ;SET FLAG FOR ADDRESS DONE. DNFST: CCL LD WORD(2) ;SHIFT LEFT ADD WORD(2) ST WORD(2) DLD CNT(2) ;CHECK FOR 4 SHIFTS. JNZ DNFST LD WORD(2) ;ADD NEW DATA. ORE ST WORD(2) JMP DATAL .PAGE 'HEX NUMBER TO SEGMENT TABLE ; HEX NUMER TO SEVEN SEGMENT TABLE CROM: .BYTE N0 .BYTE N1 .BYTE N3 .BYTE N4 .BYTE N5 .BYTE N6 .BYTE N7 .BYTE N8 .BYTE N9 .BYTE NA .BYTE NB .BYTE NC .BYTE ND .BYTE NE .BYTE NF .PAGE ' MAKE A 4 DIGIT ADDRESS ' ADR: ; SHIFT ADDRESS LEFT ONE DIGIT THEN ; ADD NEW LOW HEX DIGIT ; HEX DIGIT IN E REGISTER ; P2 POINTS TO RAM. LDI 4 ;SET NUMBER OF SHIFTS ST CNT(2) ILD DDTA(2) ;CHECK IF FIRST JNZ NOTFST ;JMP IF NO. LDI 0 ;ZERO ADDRESS. ST ADH(2) ST ADL(2) NOTFST: CCL ;CLEAR LINK LD ADL(2) ;SHIFT ADDRESS LEFT4 TIMES ADD ADL(2) ST ADL(2) LD ADH(2) ADD ADH(2) ST ADH(2) DLD CNT(2) ;CHECK IF SHIFTED 4 TIMES JNZ NOTFST ;JMP IF NOT DONE LD ADL(2) ;NOW ADD THE NEW NUMBER ORE ST ADL(2) ;NUMBER IS NOW UPDATED. XPPC 3 ;BACK TO CALLING PROG .PAGE ' DATA TO SEGMENTS' ; CONVERT HEX DATA TO SEGMENTS. ; P2 POINTS TO RAM ; DROPS THRU TO HEX ADDRESS CONVERSION. DISPD: LDI H(CROM) ;SET ADDRESS IN TABLE. XPAH 1 LDI L(CROM) LD WORD(2) ; GET MEMORY WORD ANI 0F ;MASK OFF TOP NIBBLE XAE LD -128(1) ;GET SEGMENT DISPLACEMENT ST DL(2) ;SAVE AT DATA LOW LD WORD(2) ;FIX HI SR ;SHIFT HI TO LOW SR SR SR XAE LD -128(1) ;GET SEGMENT ST DH(2) ;SAVE IN DATA HIGH .PAGE 'ADDRESS TO SEGMENTS' ; CONVERT HEX ADDRESS TO SEGMENTS ; P2 POINTS TO RAM ; DROPS THROUGH TO KEYBOARD AND DISPLAY DISPA: SCL LDI H(CROM) ;SET ADDRESS OF TABLE XPAH P1 LDI L(CROM) XPAL P1 LOOPD: LD ADL(2) ;GET ADDRESS ANI 0F XAE LD -128(1) ;GET SEGMENTS ST ADLL(2) ;SAVE SEG OF ADR LL. LD ADL(2) SR ;SHIFT HI TO LOW SR SR SR XAE LD -128(1) ;GET SEGMENTS ST ADLH(2) CSA ;CHECK IF DONE ANI 080 JZ DONE CCL ;CLEAR FLAG. LDI 0 ST D4(2) ;ZERO DIGIT 4. LD @2(2) ;FIX P2 FOR NEXT LOOP. JMP LOOPD DONE: LD @-2(2) ;KIX P2. .PAGE ' DISPLAY AND KEYBOARD INPUT' ; CALL XPPC 3 ; JMP COMMAND IN A GO=6,MEM=7,TERM=3 ; IN E GO=22,MEM=23,TERM=27. ; NUMBER RETURN HEX NUMBER IN E REG. ; ABORT KEY GOES TO ABORT ; ALL REGISTERS ARE USED. ; P2 MUST POINT TO RAM. ADDRESS MUST BE XXX0. ; TO RE-EXECUTE ROUTINE DO XPPC P3. KYBD: LDI 0 ;ZERO CHAR. ST CHAR(2) LDI H(DISP) ;SET DISPLAY ADDRESS. XPAH 1 OFF: LDI -1 ;SET ROW/DIGIT ADDRESS. ST ROW(2) ;SAVE ROW COUNTER. LDI 10 ;SET ROW COUNT. ST CNT(2) LDI 0 ST PUSHED(2) ;ZERO KEYBOARD INPUT. XPAL 1 ;SET DISP ADDRESS LOW. LOOP: ILD RPW(2) ;UPDATE ROW ADDRESS. XAE LD -128(2) ;GET SEGMENT. ST -128(1) ;SEND IT. DLY 0 ;DELAY FOR DISPLAY. LD -128(1) ;GET KEYBOARD INPUT. XRI 0FF ;CHECK IF KEY PUSHED. JNZ KEY JUMP IF PUSHED. BACK: DLD CNT(2) ;CHECK IF DONE. JNZ LOOP ;NO IF JUMP. LD PUSHED(2) ;CHECK IF KEY. JZ CKMORE LD CHAR(2) ;WAS THERE A CHAR?. JNZ OFF ;YES WAIT FOR RELEASE. LD PUSHED(2) ;NO SET CHAR. ST CHAR(2) JMP OFF CKMORE: LD CHAR(2) ;CHECK IF THERE WAS A CHAR. JZ OFF ;NO KEEP LOOKING. .PAGE ; COMMAND KEY PROCESSING COMMAND: XZE ;SAVE CHAR. LDE ;GET CHAR. ANI 020 ;CHECK FOR COMMAND. JNZ CMND ;JUMP IF COMMAND. LDI 080 ;FIND NUMBER. ANE JNZ LT7 ;0 TO 7. LDI 040 ANE JNZ N89 ;8 OR 9. LDI 0F ANE ADI 7 ;MAKE OFFSET TO TABLE. XAE ;PUT OFFSET AWAY. LD -128(0) ;GET NUMBER. KEYRTN: XAE ;SAVE IN E LD @2(3) ;FIX RETURN. XPPC P3 ;RETURN. JMP KYBD ;ALLOWS XPPC P3 TO RETURN .BYTE 0A,0B,0C,0D,0E,0F LT7: XRE ;KEEP LOW DIGIT JMP KEYRTN N89: XRE ;GET LOW ADI 08 ;MKAE DIGIT AN 8 OR 9. JMP KEYRTN .PAGE CNMD: XRE XRI 04 ;CHECK IF ABORT. JZ ABORT ;ABORT. XPPC 3 ;IN E 23=MEM,22=GO,27=TERM. ;IN A 7=MEM,6=GO,3=TERM. JMP KYBD ;ALLOWS JUMPS A XPPC P3 TO RETURN. KRY: ORE ;MAKE CHAR. ST PUSHED(2) ;SAVE CHAR. JMP BACK ABRT: LDI H(ABORT) XPAH 3 LDI L(ABORT)-1 XPAL 3 XPPC 3 ;GO TO ABORT. .PAGE ' RAM OFF-SET' DL = 0 ;SEGMENT FOR DIGIT 1 DH = 1 ;SETMENT FOR DIGIT 2 D3 = 2 ;SEGMENT FOR DIGIT 3 D4 = 3 ;SEGMENT FOR DIGIT 4 ADLL = 4 ;SEGMENT FOR DIGIT 5 ADLH = 5 ;SEGMENT FOR DIGIT 6 ADHL = 6 ;SEGMENT FOR DIGIT 7 ADHH = 7 ;SEGMENT FOR DIGIT 8 D9 = 8 ;SEGMENT FOR DIGIT 9 CNT = 9 ;COUNTER PUSHED = 10 ;KEY PUSHED. CHAR = 11 ;CHAR READ. ADL = 12 ;MEMORY ADDRESS LOW WORD = 13 ;MEMORY WORD. ADH = 14 ;MEMORY ADDRESS HI. DDTA = 15 ;FIRST FLAG. ROW = 16 ;ROW COUNTER. NEXT = 17 ;FLAG FOR NOW DATA. .END