;- - - - - - - - - - - - - - KIM.ASM - - - - - - - - - - - ; COPYRIGHT MOS TECHNOLOGY, INC ; DATE: OCT 18, 1975 REV-D ;************************ 6530-003 I.C. ****************** ; 6530-003 I.C. IS AN AUDIO CASSETTE TAPE RECORDER ; EXTENSION OF THE BASIC KIM MONITOR. IT FEATURES ; TWO ROUTINES: ; LOADT - LOAD MEMORY FROM AUDIO TAPE ; ID=00 IGNORE ID ; ID=FF IGNORE ID, USE SA FOR START ADDR ; ID=01-FE USE ADDRESS ON TAPE ; ; DUMPT - STORE MEMORY ONTO AUDIO TAPE ; ID=00 SHOULD NOT BE USED ; ID=FF SHOULD NOT BE USED ; ID=01-FE NORMAL ID RANGE ; SAL LSB STARTING ADDRESS OF PROGRAM ; SAH MSB ; EAL ENDING ADDRESS OF PROGRAM ; EAH MSB ; *= $1800 SAD = $1740 6530 A DATA PADD = $1741 6530 A DATA DIRECTION SBD = $1742 6530 B DATA PBDD = $1743 6530 B DATA DIRECTION CLK1T = $1744 DIV BY 1 TIME CLK8T = $1745 DIV BY 8 TIME CLK64T = $1746 DIV BY 64 TIME CLKKT = $1747 DIV BY 1024 TIME CLKRDI = $1747 READ TIME OUT BIT CLKRDT = $1746 READ TIME ; ** MPU REG. SAVX AREA IN PAGE 0 ** PCL = $EF PROGRAM CNT LOW PCH = $F0 PROGRAM CNT HI PREG = $F1 CURRENT STATUS REG SPUSER = $F2 CURRENT STACK POINTER ACC = $F3 ACCUMULATOR YREG = $F4 Y INDEX XREG = $F5 X INDEX ; ** KIM FIXED AREA IN PAGE 0 ** CHKHI = $F6 CHKSUM = $F7 INL = $F8 INPUT BUFFER INH = $F9 INPUT BUFFER POINTL = $FA LSB OF OPEN CELL POINTH = $FB MSB OF OPEN CELL TEMP = $FC TMPX = $FD CHAR = $FE MODE = $FF ; ** KIM FIXED AREA IN PAGE 23 ** CHKL = $17E7 CHKH = $17E8 CHKSUM SAVX = $17E9 (3-BYTES) VEB = $17EC VOLATILE EXEC BLOCK (6-B) CNTL30 = $17F2 TTY DELAY CNTH30 = $17F3 TTY DELAY TIMH = $17F4 SAL = $17F5 LOW STARTING ADDRESS SAH = $17F6 HI STARTING ADDRESS EAL = $17F7 LOW ENDING ADDRESS EAH = $17F8 HI ENDING ADDRESS ID = $17F9 TAPE PROGRAM ID NUMBER ; ** INTERRUPT VECTORS ** NMIV = $17FA STOP VECTOR (STOP=1C00) RSTV = $17FC RST VECTOR IRQV = $17FE IRQ VECTOR (BRK=1C00) ; ; ** DUMP MEMORY TO TAPE ** DUMPT LDA #$AD LOAD ABSOLUTE INST 1800 STA VEB JSR INTVEB LDA #$27 TURN OFF DATAIN PB5 STA SBD LDA #$BF CONVERT PB7 TO OUTPUT STA PBDD LDX #$64 100 CHARS DUMPT1 LDA #$16 SYNC CHARS JSR OUTCHT DEX BNE DUMPT1 LDA #$2A START CHAR JSR OUTCHT LDA ID OUTPUT ID JSR OUTBT LDA SAL OUTPUT STARTING JSR OUTBTC ADDRESS LDA SAH JSR OUTBTC DUMPT2 LDA VEB+1 CHECK FOR LAST CMP EAL DATA BYTE LDA VEB+2 SBC EAH BCC DUMPT4 LDA #'/ OUTPUT END-OF-DATA CHAR JSR OUTCHT LDA CHKL LAST BYTE HAS BEEN JSR OUTBT OUTPUT NOW OUTPUT LDA CHKH CHKSUM JSR OUTBT LDX #$02 2 CHARS DUMPT3 LDA #$04 EOT CHAR JSR OUTCHT DEX BNE DUMPT3 LDA #$00 DISPLAY 0000 STA POINTL FOR NORMAL EXIT STA POINTH JMP START DUMPT4 JSR VEB DATA BYTE OUTPUT JSR OUTBTC JSR INCVEB JMP DUMPT2 ; ; ** LOAD MEMORY FROM TAPE ** ; TAB .WORD LOAD12 'LOAD12' ADDRESS 1871 ; LOADT LDA #$8D INIT VOLATILE EXECUTION 1873 STA VEB BLOCK WITH STA ABS. JSR INTVEB LDA #$4C JUMP TYPE RTRN STA VEB+3 LDA TAB STA VEB+4 LDA TAB+1 STA VEB+5 LDA #$07 RESET PB5=0 (DATA-IN) STA SBD SYNC LDA #$FF CLEAR SAVX FOR SYNC CHAR 1891 STA SAVX SYNC1 JSR RDBIT GET A BIT LSR SAVX SHIFT BIT INTO CHAR ORA SAVX STA SAVX LDA SAVX GET NEW CHAR CMP #$16 SYNC CHAR BNE SYNC1 LDX #$0A TEST FOR 10 SYNC CHARS SYNC2 JSR RDCHT CMP #$16 BNE SYNC IF NOT 10 CHAR, RE-SYNC DEX BNE SYNC2 LOADT4 JSR RDCHT LOOK FOR START OF CMP #$2A DATA CHAR BEQ LOAD11 CMP #$16 IF NOT , SHOULD BE SYNC BNE SYNC BEQ LOADT4 LOAD11 JSR RDBYT READ ID FROM TAPE CMP ID COMPARE WITH REQUESTED ID BEQ LOADT5 LDA ID DEFAULT 00, READ RECORD CMP #$00 ANYWAY BEQ LOADT5 CMP #$FF DEFAULT FF, IGNORE SA ON BEQ LOADT6 TAPE BNE LOADT LOADT5 JSR RDBYT GET SA FROM TAPE JSR CHKT STA VEB+1 SAVX IN VEB+1,2 JSR RDBYT JSR CHKT STA VEB+2 JMP LOADT7 ; LOADT6 JSR RDBYT GET SA BUT IGNORE 18EC JSR CHKT JSR RDBYT JSR CHKT LOADT7 LDX #$02 GET 2 CHARS LOAD13 JSR RDCHT GET CHAR (X) CMP #$2F LOOK FOR LAST CHAR BEQ LOADT8 JSR PACKT CONVERT TO HEX BNE LOADT9 Y=1 NON-HEX CHAR DEX BNE LOAD13 JSR CHKT COMPARE CHECKSUM JMP VEB SAVX DATA IN MEMORY LOAD12 JSR INCVEB INCR DATA POINTER JMP LOADT7 ; LOADT8 JSR RDBYT END OF DATA, COMPARE CHKSUM 1915 CMP CHKL BNE LOADT9 JSR RDBYT CMP CHKH BNE LOADT9 LDA #$00 NORMAL EXIT BEQ LOAD10 LOADT9 LDA #$FF ERROR EXIT LOAD10 STA POINTL STA POINTH JMP START ; ; ** SUBROUTINES BELOW ** INTVEB LDA SAL MOVE SA TO VEB+1,2 1932 STA VEB+1 LDA SAH STA VEB+2 LDA #$60 RTS INST STA VEB+3 LDA #$00 CLEAR CHKSUM AREA STA CHKL STA CHKH RTS ; ** COMPUTE CHKSUM FOR TAPE LOAD ** CHKT TAY 194C CLC ADC CHKL STA CHKL LDA CHKH ADC #$00 STA CHKH TYA RTS ; ** OUTPUT ONE BYTE ** OUTBTC JSR CHKT COMPARE CHKSUM 195E OUTBT TAY SAVX DATA BYTE LSR A SHIFT OFF LSD LSR A LSR A LSR A JSR HEXOUT OUTPUT MSD TYA JSR HEXOUT OUTPUT LSD TYA RTS ; ** CONVERT LSD OF A TO ASCII, OUTPUT TO TAPE ** HEXOUT AND #$0F 196F CMP #$0A CLC BMI HEX1 ADC #$07 HEX1 ADC #$30 ; ** OUTPUT TO TAPE ONE ASCII CHAR ** OUTCHT STX SAVX 197A STY SAVX+1 LDY #$08 START BIT CHT1 JSR ONE LSR A GET DATA BIT BCS CHT2 JSR ONE DATA BIT=1 JMP CHT3 CHT2 JSR ZRO DATA BIT=0 CHT3 JSR ZRO DEY BNE CHT1 LDX SAVX LDY SAVX+1 RTS ; ** OUTPUT 1 TO TAPE, 9 PULSES, 138 US EACH ** ONE LDX #$09 199E PHA SAVX A ONE1 BIT CLKRDI WAIT FOR TIME OUT 19A1 BPL ONE1 LDA #126 STA CLK1T LDA #$A7 STA SBD SET PB7 = 1 ONE2 BIT CLKRDI 19B0 BPL ONE2 LDA #126 STA CLK1T LDA #$27 STA SBD RESET PB7=0 DEX BNE ONE1 PLA RTS ; ** OUTPUT 0 TO TAPE, 6 PULSES, 207 US EACH ** ZRO LDX #$06 19C4 PHA SAVX A ZRO1 BIT CLKRDI 19C7 BPL ZRO1 LDA #$C3 STA CLK1T LDA #$A7 STA SBD SET PB7=1 ZRO2 BIT CLKRDI BPL ZRO2 LDA #195 STA CLK1T LDA #$27 STA SBD RESET PB7=0 DEX BNE ZRO1 PLA RESTORE A RTS ; ** SUB TO INC VEB+1,2 ** INCVEB INC VEB+1 19EA BNE INCVE1 INC VEB+2 INCVE1 RTS ; ** SUB TO READ BYTE FROM TAPE ** RDBYT JSR RDCHT 19F3 JSR PACKT JSR RDCHT JSR PACKT RTS ; ** PACK A=ASCII INTO SAVX AS HEX DATA ** PACKT CMP #$30 1A00 BMI PACKT3 CMP #$47 BPL PACKT3 CMP #$40 BMI PACKT1 CLC ADC #$09 PACKT1 ROL A ROL A ROL A ROL A LDY #$04 PACKT2 ROL A ROL SAVX DEY BNE PACKT2 LDA SAVX LDY #$00 Y=0 VALID HEX CHAR RTS PACKT3 INY Y=1 NOT HEX RTS ; ** GET 1 CHAR FROM TAPE AND RETURN WITH ; CHAR IN A. USE SAVX+1 TO ASM CHAR ** RDCHT STX SAVX+2 1A24 LDX #$08 READ 8 BITS RDCHT1 JSR RDBIT GET NEXT DATA BIT LSR SAVX+1 RIGHT SHIFT CHAR ORA SAVX+1 OR IN SIGN BIT STA SAVX+1 REPLACE CHAR DEX BNE RDCHT1 LDA SAVX+1 MOVE CHAR INTO A ROL A SHIFT OFF PARITY LSR A LDX SAVX+2 RTS ; ** THIS SUB GETS ONE BIT FROM TAPE AND ; RETURNS IT IN SIGN OF A ** RDBIT BIT SBD WAIT FOR END OF START BIT 1A41 BPL RDBIT LDA CLKRDT GET START BIT TIME LDY #$FF A=256-T1 STY CLK64T SET UP TIMER LDY #$14 RDBIT3 DEY DELAY 100 MICRO SEC BNE RDBIT3 RDBIT2 BIT SBD BMI RDBIT2 WAIT FOR NEXT START BIT SEC SBC CLKRDT (256-T1)-(256-T2)=T2-T1 LDY #$FF STY CLK64T SET UP TIMER FOR NEXT BIT LDY #$07 RDBIT4 DEY DELAY 50 MICROSEC BNE RDBIT4 EOR #$FF COMPLEMENT SIGN OF A AND #$80 MASK ALL EXCEPT SIGN RTS ; ** PLLCAL OUTPUT 166 MICROSEC (6024 HZ) ; PULSE STRING PLLCAL LDA #$27 1A6B STA SBD TURN OFF DATIN PB5=1 LDA #$BF CONVERT PB7 TO OUTPUT STA PBDD PLL1 BIT CLKRDI BPL PLL1 LDA #154 WAIT 166 MICROSEC STA CLK1T LDA #$A7 OUTPUT PB7=1 STA SBD PLL2 BIT CLKRDI BPL PLL2 LDA #154 STA CLK1T LDA #$27 PB7=0 STA SBD JMP PLL1 ; ; ** INTERRUPTS ** *= $1BFA NMIP27 .WORD PLLCAL RSTP27 .WORD PLLCAL IRQP27 .WORD PLLCAL ; ;******************* 6530-002 I.C. ***************** ; ** COPYRIGHT MOS TECHNOLOGY INC. ; DATE OCT 13, 1975 REV E ; ; ** KIM ** ; TTY INTERFACE 6530-002 ; KEYBOARD INTERFACE, ; 7-SEGMENT 6-DIGIT DISPLAY ; ; TTY COMANDS: ; G GOEXEC ; CR OPEN NEXT CELL ; LF OPEN PREVIOUS CELL ; . MODIFY OPEN CELL ; SP OPEN NEW CELL ; L LOAD (OBJECT FORMAT) ; Q DUMP FROM OPEN CELL ADDR TO HI LIMIT ; RO RUB OUT - RETURN TO START KIM ; (ALL ILLEGAL CHARS ARE IGNORED) ; ; KEYBOARD COMMANDS: ; ADDR SETS MODE TO MODIFY CELL ADDRESS ; DATA SETS MODE TO MODIFY DATA IN OPEN CELL ; STEP INCREMENTS TO NEXT CELL ; RST SYSTEM RESET ; RUN GOEXEC ; STOP $1C00 CAN BE LOADED INTO NMIV TO USE ; PC DISPLAY PC (PROGRAM COUNTER) ; *= $1C00 SAVE STA ACC KIM ENTRY VIA STOP (NMI) 1C00 PLA OR BRK (IRQ) STA PREG PLA KIM ENTRY VIA JSR (A LOST) 1C05 STA PCL STA POINTL PLA STA PCH STA POINTH STY YREG STX XREG TSX STX SPUSER JSR INITS JMP START ; NMIT JMP (NMIV) NON-MASKABLE INTERRUPT TRAP 1C1C IRQT JMP (IRQV) INTERRUPT TRAP 1C1F RST LDX #$FF KIM ENTRY VIA RST 1C22 TXS STX SPUSER JSR INITS LDA #$FF COUNT START BIT STA CNTH30 ZERO CNTH30 LDA #$01 MASK HI ORDER BITS DET1 BIT SAD TEST 1C31 BNE START KEYBD SSW TEST BMI DET1 START BIT TEST LDA #$FC DET3 CLC THIS LOOP COUNTS 1C3A ADC #$01 THE START BIT TIME BCC DET2 INC CNTH30 DET2 LDY SAD CHECK FOR END OF START BIT 1C42 BPL DET3 STA CNTL30 LDX #$08 JSR GET5 GET REST OF THE CHAR, TEST CHAR ; ** MAKE TTY/KB SELECTION ** START JSR INIT1 1C4F LDA #$01 BIT SAD BNE TTYKB JSR CRLF PRT CR LF LDX #$0A TYPE OUT KIM JSR PRTST JMP SHOW1 ; CLEAR LDA #$00 STA INL CLEAR INPUT BUFFER STA INH READ JSR GETCH GET CHAR CMP #$01 BEQ TTYKB JSR PACK JMP SCAN ; ** MAIN ROUTINE FOR KEYBOARD AND DISPLAY ** TTYKB JSR SCAND IF A=0 NO KEY 1C77 BNE START TTYKB1 LDA #$01 BIT SAD BEQ START JSR SCAND BEQ TTYKB1 JSR SCAND BEQ TTYKB1 JSR GETKEY CMP #$15 BPL START CMP #$14 BEQ PCCMD DISPLAY PC CMP #$10 ADDR MODE=1 BEQ ADDRM CMP #$11 DATA MODE=1 BEQ DATAM CMP #$12 STEP BEQ STEP CMP #$13 RUN BEQ GOV ASL A SHIFT CHAR INTO HIGH ASL A ORDER NIBBLE ASL A ASL A STA TEMP STORE IN TEMP LDX #$04 DATA1 LDY MODE TEST MODE 1=ADDR BNE ADDR MODE=0 DATA LDA (POINTL),Y GET DATA ASL TEMP SHIFT CHAR ROL A SHIFT DATA STA (POINTL),Y STORE OUT DATA JMP DATA2 ; ADDR ASL A SHIFT CHAR ROL POINTL SHIFT ADDR ROL POINTH SHIFT ADDR HI DATA2 DEX BNE DATA1 DO 4 TIMES BEQ DATAM2 EXIT HERE ADDRM LDA #$01 BNE DATAM1 DATAM LDA #$00 DATAM1 STA MODE DATAM2 JMP START ; STEP JSR INCPT 1CD3 JMP START ; GOV JMP GOEXEC 1CD9 ; ** DISPLAY PC BY MOVING PC TO POINT ** PCCMD LDA PCL 1CDC STA POINTL LDA PCH STA POINTH JMP START ; ** LOAD PAPER TAPE FROM TTY ** LOAD JSR GETCH LOOK FOR FIRST CHAR 1CE7 CMP #$3B SEMICOLON BNE LOAD LDA #$00 STA CHKSUM STA CHKHI JSR GETBYT GET BYTE COUNT TAX SAVE IN X INDEX JSR CHK COMPUTE CHECKSUM JSR GETBYT GET ADDRESS HI STA POINTH JSR CHK JSR GETBYT GET ADDRESS LO STA POINTL JSR CHK TXA IF CNT=0 DONT BEQ LOAD3 GET ANY DATA LOAD2 JSR GETBYT GET DATA STA (POINTL),Y STORE DATA JSR CHK JSR INCPT NEXT ADDRESS DEX BNE LOAD2 INX X=1 DATA RCD X=0 LAST RCD LOAD3 JSR GETBYT COMPARE CHKSUM CMP CHKHI BNE LOADE1 JSR GETBYT CMP CHKSUM BNE LOADER TXA X=0 LAST RECORD BNE LOAD LDX #$0C X-OFF KIM LOAD8 LDA #$27 STA SBD DISABLE DATA IN JSR PRTST JMP START ; LOADE1 JSR GETBYT DUMMY LOADER LDX #$11 X-OFF ERR KIM BNE LOAD8 ; ** DUMP TO TTY FROM OPEN CELL ADDRESS TO ; LIMHL, LIMHH ** DUMP LDA #$00 1D42 STA INL STA INH CLEAR RECORD COUNT DUMP0 LDA #$00 STA CHKHI CLEAR CHKSUM STA CHKSUM JSR CRLF PRINT CR LF LDA #$3B PRINT SEMICOLON JSR OUTCH LDA POINTL TEST POINT GT OR ET CMP EAL HI LIMIT GOTO EXIT LDA POINTH SBC EAH BCC DUMP4 LDA #$00 PRINT LAST RECORD JSR PRTBYT 0 BYTES JSR OPEN JSR PRTPNT LDA CHKHI PRINT CHKSUM JSR PRTBYT FOR LAST RECORD LDA CHKSUM JSR PRTBYT JMP CLEAR ; DUMP4 LDA #$18 PRINT 24 BYTE COUNT 1D7A TAX SAVE AS INDEX JSR PRTBYT JSR CHK JSR PRTPNT DUMP2 LDY #$00 PRINT 24 BYTES LDA (POINTL),Y GET DATA JSR PRTBYT PRINT DATA JSR CHK COMPUTE CHKSUM JSR INCPT INCREMENT POINT DEX BNE DUMP2 LDA CHKHI PRINT CHKSUM JSR PRTBYT LDA CHKSUM JSR PRTBYT INC INL INCR RECORD COUNT BNE DUMP3 INC INH DUMP3 JMP DUMP0 ; SPACE JSR OPEN OPEN NEW CELL 1DA9 SHOW JSR CRLF PRINT CR LF SHOW1 JSR PRTPNT JSR OUTSP PRINT SPACE LDY #$00 PRINT DATA SPECIFIED LDA (POINTL),Y BY POINT AD=LDA EXT JSR PRTBYT JSR OUTSP PRINT SPACE JMP CLEAR ; RTRN JSR INCPT OPEN NEXT CELL 1DC2 JMP SHOW ; GOEXEC LDX SPUSER 1DC8 TXS LDA POINTH PROGRAM RUNS FROM PHA OPEN CELL ADDRESS LDA POINTL PHA LDA PREG PHA LDX XREG RESTORE REGS LDY YREG LDA ACC RTI ; SCAN CMP #$20 OPEN CELL BEQ SPACE CMP #$7F RUB OUT (KIM) BEQ STV CMP #$0D NEXT CELL BEQ RTRN CMP #$0A PREV CELL BEQ FEED CMP #'. MODIFY CELL BEQ MODIFY CMP #'G GO EXEC BEQ GOEXEC CMP #'Q DUMP FROM OPEN CELL TO HI LIMIT BEQ DUMPV CMP #'L LOAD TAPE BEQ LOADV JMP READ IGNORE ILLEGAL CHAR ; STV JMP START DUMPV JMP DUMP LOADV JMP LOAD ; FEED SEC 1E07 LDA POINTL DEC DOUBLE BYTE SBC #$01 AT POINTL AND POINTH STA POINTL BCS FEED1 DEC POINTH FEED1 JMP SHOW ; MODIFY LDY #$00 GET CONTENTS OF INPUT BUFF LDA INL INL AND STORE IN LOC STA (POINTL),Y SPECIFIED BY POINT JMP RTRN ; ; ** SUBROUTINES FOLLOW ** PRTPNT LDA POINTH PRINT POINTL, POINTH 1E1E JSR PRTBYT JSR CHK LDA POINTL JSR PRTBYT JSR CHK RTS ; **PRINT STRING OF ASCII CHARS FROM TOP+X TO TOP CRLF LDX #$07 PRTST LDA TOP,X JSR OUTCH DEX BPL PRTST STOP ON INDEX ZERO RTS ; ** PRINT 1 HEX BYTE AS 2 ASCII CHARS ** PRTBYT STA TEMP 1E3B LSR A SHIFT CHAR RIGHT 4 BITS LSR A LSR A LSR A JSR HEXTA CONVERT TO HEX AND PRINT LDA TEMP GET OTHER HALF JSR HEXTA CONVERT TO HEX AND PRINT LDA TEMP RESTORE BYTE IN A AND RETURN RTS HEXTA AND #$0F MASK HI 4 BITS CMP #$0A CLC BMI HEXTA1 ADC #$07 ALPHA HEX HEXTA1 ADC #$30 DEC HEX JMP OUTCH PRINT CHAR ; ** GET 1 CHAR FROM TTY, CHAR IN A GETCH STX TMPX SAVE X REG 1E5A LDX #$08 SET UP 8-BIT COUNT LDA #$01 GET1 BIT SAD BNE GET6 BMI GET1 WAIT FOR START BIT JSR DELAY DELAY 1 BIT GET5 JSR DEHALF DELAY 1/2 BIT TIME GET2 LDA SAD GET 8 BITS AND #$80 MASK OFF LOW ORDER BITS LSR CHAR SHIFT RIGHT CHAR ORA CHAR STA CHAR JSR DELAY DELAY 1 BIT TIME DEX BNE GET2 GET NEXT CHAR JSR DEHALF EXIT THIS ROUTINE LDX TMPX LDA CHAR ROL A SHIFT OFF PARITY LSR A GET6 RTS ; ** INITIALIZATION FOR SIGMA ** INITS LDX #$01 SET KB MODE TO ADDR 1E88 STX MODE INIT1 LDX #$00 STX PADD FOR SIGMA USE SADD LDX #$3F STX PBDD FOR SIGMA USE SBDD LDX #$07 ENABLE DATA IN STX SBD OUTPUT CLD SEI RTS ; ** PRINT ONE CHAR IN A ** OUTSP LDA #$20 PRINT SPACE 1E9E OUTCH STA CHAR STX TMPX JSR DELAY DELAY 10/11 BIT CODE SYNC LDA SBD START BIT AND #$FE STA SBD JSR DELAY LDX #$08 OUT1 LDA SBD DATA BIT AND #$FE LSR CHAR ADC #$00 STA SBD JSR DELAY DEX BNE OUT1 LDA SBD STOP BIT ORA #$01 STA SBD JSR DELAY STOP BIT LDX TMPX RESTORE INDEX RTS ; ** DELAY 1 BIT TIME ** DELAY LDA CNTH30 1ED4 STA TIMH LDA CNTL30 DE2 SEC DE4 SBC #$01 BCS DE3 DEC TIMH DE3 LDY TIMH BPL DE2 RTS ; ** DELAY 1/2 BIT TIME ** DEHALF LDA CNTH30 1EEB STA TIMH LDA CNTL30 LSR A LSR TIMH BCC DE2 ORA #$80 BCS DE4 ; ** SUB TO DETERMINE IF KEY IS DEPRESSED OR ; CONDITION OF SSW KEY NOT DEPRESSED OR ; TTY MODE A=0 ; KEY DEPRESSED OR KB MODE A NOT ZERO AK LDY #$03 3 ROWS LDX #$01 DIGIT 0 ONEKEY LDA #$FF AK1 STX SBD OUTPUT DIGIT INX GET NEXT DIGIT INX AND SAD INPUT SEGMENTS DEY BNE AK1 LDY #$07 STY SBD ORA #$80 EOR #$FF RTS ; ** OUTPUT TO 7-SEGMENT DISPLAY ** SCAND LDY #$00 GET DATA 1F19 LDA (POINTL),Y SPECIFIED BY POINT STA INH SET UP DISPLAY BUFFER LDA #$7F CHANGE SEG STA PADD TO OUTPUT LDX #$09 INIT DIGIT NUMBER LDY #$03 OUTPUT 3 BYTES SCAND1 LDA INL,Y GET BYTE LSR A GET MSD LSR A LSR A LSR A JSR CONVD OUTPUT CHAR LDA INL,Y GET BYTE AGAIN AND #$0F GET LSD JSR CONVD OUTPUT CHAR DEY SET UP FOR NEXT BYTE BNE SCAND1 STX SBD ALL DIGITS OFF LDA #$00 CHANGE SEGMENT STA PADD TO INPUTS JMP AK GET ANY KEY ; ** CONVERT AND DISPLAY HEX (USED BY SCAND ONLY)** CONVD STY TEMP TAY SAVE Y LDA TABLE,Y USE CHAR AS INDEX LDY #$00 LOOKUP CONVERSION STY SAD TURN OFF SEGMENTS STX SBD OUTPUT DIGIT ENABLE STA SAD OUTPUT SEGMENTS LDY #$7F DELAY 500 CYCLES CONVD1 DEY BNE CONVD1 INX GET NEXT DIGIT NUMBER INX ADD 2 LDY TEMP RESTORE Y RTS ; ** INCREMENT POINT ** INCPT INC POINTL BNE INCPT2 INC POINTH INCPT2 RTS ; ** GET KEY FROM KEYPAD A=KEYVALUE ** GETKEY LDX #$21 START AT DIGIT 0 1F6A GETKE5 LDY #$01 GET 1 ROW JSR ONEKEY BNE KEYIN A=0 NO KEY CPX #$27 TEST FOR DIGIT 2 BNE GETKE5 LDA #$15 15=NOKEY RTS KEYIN LDY #$FF KEYIN1 ASL A SHIFT LEFT BCS KEYIN2 UNTIL Y=KEY NO INY BPL KEYIN1 KEYIN2 TXA AND #$0F MASK MSD LSR A DIVIDE BY 2 TAX TYA BPL KEYIN4 KEYIN3 CLC ADC #$07 MULT (X-1 TIMES A KEYIN4 DEX BNE KEYIN3 RTS ; ** COMPUTE CHECKSUM ** CHK CLC ADC CHKSUM STA CHKSUM LDA CHKHI ADC #$00 STA CHKHI RTS ; ** GET 2 HEX CHARS AND PACK INTO INL AND INH ** GETBYT JSR GETCH JSR PACK JSR GETCH JSR PACK LDA INL RTS ; ** SHIFT CHAR IN A INTO INL AND INH ** PACK CMP #$30 CHECK FOR HEX 1FAC BMI UPDAT2 CMP #$47 NOT HEX EXIT BPL UPDAT2 CMP #$40 CONVERT TO HEX BMI UPDATE CLC ADC #$09 UPDATE ROL A ROL A ROL A ROL A LDY #$04 SHIFT INTO I/O BUFFER UPDAT1 ROL A ROL INL ROL INH DEY BNE UPDAT1 LDA #$00 A=0 IF HEX NUM UPDAT2 RTS ; OPEN LDA INL MOVE I/O BUFFER TO POINT STA POINTL LDA INH TRANSFER INH- POINTH STA POINTH RTS ; ; ** TABLES ** TOP .DBYTE $0000,$0000,$0000,$0A0D 1FD5 .BYTE 'M,'I,'K,$20,$13 KIM .BYTE 'R,'R,'E,$20,$13 ERR TABLE .DBYTE $BF86,$DBCF,$E6ED,$FD87 ;0-7 1FE7 .DBYTE $FFEF,$F7FC,$B9DE,$F9F1 ;8-F HEX TO 7-SEG ; ; ** INTERRUPT VECTORS ** *= $1FFA NMIENT .WORD NMIT RSTENT .WORD RST IRQENT .WORD IRQT .END