home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CBM Funet Archive
/
cbm-funet-archive-2003.iso
/
cbm
/
schematics
/
kim-1
/
kim.asm
< prev
next >
Wrap
Assembly Source File
|
1997-10-19
|
34KB
|
1,136 lines
;
; lAST UPDATE: 19 oCTOBER 1997
;
;
; tHE SOURCECODE IS COPIED FROM 'kim-1 manual' RELEASED BY mos tECHNOLOGIES
; AND THIS MEANS THAT SOMEONE PROBABLY HAS THE COPYRIGHTS OF IT. uNTIL
; SOMEONE CLEARS THE MESS AROUND 'WHO OWNS WHAT FROM cOMMODORE', LEAVE THIS
; REMARK IN THE SOURCECODE AS A SIGN OF ACKNOWLEDGEMENT AND RESPECT IN CASE
; YOU INTEND TO USE IT FOR YOUR OWN PURPOSES.
;
;
; i HAVE CHECKED THE src LINE BY LINE AND ADDED SOME COMMENT OF MY OWN. aT
; THIS MOMENT IT DOES NOT MEAN THAT IT IS WITHOUT FAULTS. i ONLY WILL BE
; SURE ABOUT THAT UNTIL i HAVE COMPILED THE src AND FOUND NO DIFFERENCES
; WITH THE ORIGINAL bin.
;
;
; tHE src CAN BE ASSEMBLED WITH MY OWN PROGRAMMED ASSEMBLER. tHIS ASSEMBLER
; FOR THE pc IS AVAILABLE AS FREEWARE, INCLUDING SOURCECODE FOR tURBO pASCAL.
;
;
; sOURCODE OF THE kim-1
;
.EQ pcl = $ef ; PROGRAMCOUNTER LOW
.EQ pch = $f0 ; PROGRAMCOUNTER HIGH
.EQ preg = $f1 ; STATUSREGISTER
.EQ spuser = $f2 ; STACKPOINTER
.EQ acc = $f3
.EQ yreg = $f4
.EQ xreg = $f5
.EQ chkhi = $f6
.EQ chksum = $f7
.EQ inl = $f8 ; INPUTBUFFER LOW
.EQ inh = $f9 ; INPUTBUFFER HIGH
.EQ pointl = $fa ; ADDRESSl ON DISPLAY
.EQ pointh = $fb ; ADDRESSh ON DISPLAY
.EQ temp = $fc
.EQ tmpx = $fd
.EQ char = $fe
.EQ mode = $ff
.EQ inl_a = $00f8 ; inl AS ABSOLUTE ADDRESS
;
.EQ chkl = $17e7
.EQ chkh = chkl+1
.EQ savx = chkl+2
.EQ veb = chkl+5
.EQ cntl30 = chkl+11
.EQ cnth30 = chkl+12
.EQ timh = chkl+13
.EQ sal = chkl+14
.EQ sah = chkl+15
.EQ eal = chkl+16
.EQ eah = chkl+17
.EQ id = chkl+18
.EQ nmiv = chkl+19 ; nmi-VECTOR
.EQ rstv = chkl+21 ; reset-VECTOR
.EQ irqv = chkl+23 ; irq-VECTOR
;
.EQ sad = $1740
.EQ padd = sad+1
.EQ sbd = sad+2
.EQ pbdd = sad+3
.EQ clk1t = sad+4
.EQ clk8t = sad+5
.EQ clk64t = sad+6
.EQ clkrdt = sad+7 ; rEAD TIME
.EQ clkkt = sad+7
.EQ clkrdi = sad+7
.EQ clkrdi = sad+7 ; rEAD TIME OUT BIT
;
;
.BA $1800
;
; dUMP MEMORY ON TAPE
dumpt LDA #$ad ; LOAD ABSOLUTE INST
STA veb
JSR intveb
;
LDA #$27 ; TURN OFF DATAINPUT pb5
STA sbd
LDA #$bf ; pb7 := OUTPUT
STA pbdd
;
LDX #100 ; 100 CHARACTERS
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 START ADDRESS
JSR outbtc
LDA sah
JSR outbtc
;
dumpt2 LDA veb+1 ; COMPARE FOR LAST DATA BYTE
CMP eal
LDA veb+2
SBC eah
BCC dumpt4
;
LDA #$2f ; OUTPUT eNDoFdATA-CHAR
JSR outcht
LDA chkl ; OUTPUT CHECKSUM
JSR outbt
LDA chkh
JSR outbt
;
LDX #2 ; 2 CHARS
dumpt3 LDA #4 ; eot-CHAR
JSR outcht
DEX
BNE dumpt3
;
LDA #0 ; DISPLAY 0000
STA pointl
STA pointh
JMP start
;
dumpt4 JSR veb ; OUTPUT DATA BYTE
JSR outbtc
JSR incveb
JMP dumpt2
;
; lOAD FROM TAPE INTO MEMORY
tab .WO load12
loadt LDA #$8d ; INITIALISE VOLATILE EXECUTION
STA veb ; BLOCK WITH STA ABS
JSR intveb
;
LDA #$4c ; CODE FOR jmp
STA veb+3
LDA tab
STA veb+4
LDA tab+1
STA veb+5
;
; RESULT: JMP load12 (= $190f)
;
LDA #7 ; RESET pb5
STA sbd
;
sync LDA #$ff ; CLEAR savx FOR sync-AREA
STA savx
;
sync1 JSR rdbit ; GET A BIT
LSR savx
ORA savx
STA savx
LDA savx ; GET NEW CHAR
CMP #$16 ; sync-CHAR?
BNE sync1
;
LDX #10 ; TEST FOR 10 sync-CHAR
sync2 JSR rdcht
CMP #$16 ; sync-CHAR?
BNE sync
DEX
BNE sync2
loadt4 JSR rdcht ; LOOK FOR START OF
CMP #$2a ; START CHAR
BEQ load11 ; YES ->
CMP #$16 ; sync-CHAR?
BNE sync ; NO ->
BEQ loadt4 ; ALWAYS ->
;
load11 JSR rdbyt ; READ id
CMP id ; REQUESTED id?
BEQ loadt5 ; YES ->
LDA id
CMP #0 ; IGNORE id?
BEQ loadt5 ; YES ->
CMP #$ff ; IGNORE START ADDRESS?
BEQ loadt6 ; YES ->
BNE loadt ; NEXT PROGRAM, ALWAYS ->
;
loadt5 JSR rdbyt ; GET sa FROM TAPE
JSR chkt
STA veb+1
JSR rdbyt
JSR chkt
STA veb+2
JMP loadt7
;
loadt6 JSR rdbyt ; GET sa FROM TAPE
JSR chkt ; BUT IGNORE
JSR rdbyt
JSR chkt
;
loadt7 LDX #2
load13 JSR rdcht
CMP #$2f ; LAST CHAR?
BEQ loadt5 ; YES ->
JSR packt ; CONVERT TO HEX
BNE loadt9 ; y=1, NON-HEX CHAR
DEX ; 2 CHARS?
BNE load13 ; NO -> NEXT ONE
JSR chkt ; COMPUTE CHECKSUM
JMP veb
;
load12 JSR incveb ; INCREMENT DATAPOINTER
JMP loadt7
;
loadt8 JSR rdbyt ; eod COMPARE CHECKSUM
CMP chkl
BNE loadt9
JSR rdbyt
CMP chkh
BNE loadt9
LDA #0
BEQ load10 ; NORMAL EXIT, ALWAYS ->
;
loadt9 LDA #$ff ; ERROR EXIT
load10 STA pointl
STA pointh
JMP start ; DISPLAY VALUES
;
; mOVE START ADDRESS TO veb+1,2
intveb LDA sal
STA veb+1
LDA sah
STA veb+2
LDA #$60 ; CODE FOR rts
STA veb+3
LDA #0
STA chkl
STA chkh
RTS
;
; cOMPUTE CHECKSUM FOR TAPE LOAD
chkt TAY
CLC
ADC chkl
STA chkl
LDA chkh
ADC #0
STA chkh
TYA
RTS
;
; oUTPUT ONE BYTE
outbtc JSR chkt
outbt TAY
LSR
LSR
LSR
LSR
JSR hexout ; OUTPUT msd
TYA
JSR hexout ; OUTPUT lsd
TYA
RTS
;
; cONVERT lsd OF a TO ascii
hexout AND #$0f
CMP #10
CLC
BMI hex1
ADC #7
hex1 ADC #$30
;
; oUTPUT TO TAPE 1 ascii
outcht STX savx
STY savx+1
LDY #8 ; STARTBIT
cht1 JSR one
LSR ; GET DATA BIT
BCS cht2
JSR one
JMP cht3
cht2 JSR zro
cht3 JSR zro
DEY ; ALL BITS?
BNE cht1 ; NO ->
LDX savx
LDY savx+1
RTS
;
; oUTPUT A 1 TO TAPE: 9 PULSES OF 138 US EACH
one LDX #9
PHA
one1 BIT clkrdi ; WAIT FOR TIMEOUT
BPL one1
LDA #126
STA clk1t
LDA #$a7
STA sbd ; pb7 := 1
one2 BIT clkrdi ; WAIT FOR TIMEOUT
BPL one2
LDA #126
STA clk1t
LDA #$27
STA sbd ; pb7 := 0
DEX ; ALL PULSES?
BNE one1 ; NO ->
PLA
RTS
;
; oUTPUT A 0 TO TAPE: 6 PULSES OF 207 US EACH
zro LDX #6
PHA
zro1 BIT clkrdi ; WAIT FOR TIMEOUT
BPL zro1
LDA #195
STA clk1t
LDA #$a7
STA sbd ; pb7 := 1
zro2 BIT clkrdi ; WAIT FOR TIMEOUT
BPL zro2
LDA #195
STA clk1t
LDA #$27
STA sbd ; pb7 := 0
DEX ; ALL PULSES?
BNE zro1 ; NO ->
PLA
RTS
;
; iNCREMENT veb+1,2
incveb INC veb+1
BNE incve1
INC veb+2
incve1 RTS
;
; rEAD BYTE FROM TAPE
rdbyt JSR rdcht
JSR packt
rdbyt2 JSR rdcht
JSR packt
RTS
;
; pACK ascii IN a AS HEX DATA
packt CMP #$30 ; ascii ?
BMI packt3 ; NO ->
CMP #$47
BPL packt3 ; NO ->
CMP #$40 ; > '9' ?
BMI packt1 ; NO ->
CLC
ADC #9
packt1 ROL
ROL
ROL
ROL
LDY #4
packt2 ROL
ROL savx
DEY
BNE packt2
LDA savx
;
; aT THIS POINT y ALREADY IS 0 (= VALID HEX CHAR)
LDY #0 ; SET THE ZERO-FLAG
RTS
;
; y=0 AT THIS POINT, DONE IN LABEL rdbit4
packt3 INY ; y:=1 = INVALID HEX CHAR
RTS
;
; gET 1 CHAR FROM TAPE IN a
rdcht STX savx+2
LDX #8 ; READ 8 BITS
rdcht1 JSR rdbit
LSR savx+1
ORA savx+1
STA savx+1
DEX
BNE rdcht1
;
LDA savx+1
ROL
LSR
LDX savx+2
RTS
;
; gET 1 BIT FROM TAPE AND RETURN IT IN BIT 7 OF a
rdbit BIT sbd ; WAIT FOR END OF STARTBIT
BPL rdbit
LDA clkrdt ; GET START BIT TIME
LDY #$ff ; a := 256 - t1
STY clk64t
;
LDY #$14
rdbit3 DEY ; DELAY 100 US
BNE rdbit3
rdbit2 BIT sbd
BMI rdbit2 ; WAIT FOR NEXT START BIT
;
SEC
SBC clkrdt
LDY #$ff
STY clk64t
;
LDY #7
rdbit4 DEY ; DELAY 50 US
BNE rdbit4
;
EOR #$ff ; COMPLEMENT SIGN
AND #$80 ; MASK SIGN
RTS
;
; OUTPUT 166 US PULSE STRING FOR TESTING PURPOSES
; nO DOCUMENTATION FOUND ABOUT THIS. i THINK IT IS USED TO
; CALIBRATE THE 565
pllcall LDA #$27
STA sbd ; TURN OFF DATIN pb5=1
LDA #$bf
STA pbdd
;
pll1 BIT clkrdi
BPL pll1
LDA #154 ; WAIT 166 US
STA clk1t
LDA #$a7 ; OUTPUT pb7=1
STA sbd
;
pll2 BIT clkrdi
BPL pll2
LDA #154
STA clk1t
LDA #$27 ; OUTPUT pb7=0
STA sbd
JMP pll1
;
.BA $1bfa
nmip27 .WO pllcall
rstp27 .WO pllcall
irqp27 .WO pllcall
;
;
;
; kim-ENTRY VIA nmi OR irq
save STA acc
PLA
STA preg
;
; kim-ENTRY VIA jsr
savea PLA
STA pcl
STA pointl
PLA
STA pch
STA pointh
;
saveb STY yreg
STX xreg
TSX
STX spuser
JSR inits
JMP start
;
; nmi AND irq ARE CALLED VIA ram-VECTOR. tHIS ENABLES THE PROGRAMMER
; TO INSERT HIS OWN ROUTINES.
; cOMMENT: IS NOT INITIALISED ANYWHERE, SO ANY ACCIDENTAL nmi OR irq
; CAN LEAD TO DISASTER !
nmit JMP (nmiv)
irqt JMP (irqv)
;
; tHE kim STARTS HERE AFTER A RESET
reset LDX #$ff
TXS ; SET STACK
STX spuser
JSR inits
;
; dETERMINE CHARACTERS PER SECOND
detcps LDA #$ff ; COUNT STARTBIT
STA cnth30 ; ZERO cnth30
;
; tEST FIRST KEYBOARD OR TELEPRINTER
LDA #1 ; MASK BIT 0
det1 BIT sad ; TEST FOR TELEPRINTER
BNE start ; NO ->
BMI det1 ; NO STARTBIT, WAIT FOR IT ->
LDA #$fc
det3 CLC ; THIS LOOP COUNTS STARTBIT TIME
ADC #1 ; a=0 ?
BCC det2 ; NO ->
INC cnth30
det2 LDY sad ; CHECK FOR END OF STARTBIT
BPL det3 ; NO ->
STA cntl30
LDX #8
JSR get5 ; GET REST OF CHAR
;
; mAKE tty/kb SELECTION
start JSR init1
LDA #1 ; READ JUMPER
BIT sad ; tty ?
BNE ttykb ; NO -> KEYBOARD/DISPLAY-ROUTINE
JSR crlf ; PRINT RETURN/LINEFEED
LDX #$0a
JSR prtst ; PRINT 'kim'
JMP show1
;
;
clear LDA #0
STA inl ; CLEAR INPUTBUFFER
STA inh
;
read JSR getch ; GET CHAR FROM tty
CMP #1 ; 1 HAS NO MEANING FOR tty
BEQ ttykb ; 1 = kb-MODE ->
JSR pack
JMP scan
;
; mAIN ROUTINE FOR KEYBOARD AND DISPLAY
ttykb JSR scand ; WAIT UNTIL no KEY PRESSED
BNE start ; IF PRESSED, WAIT AGAIN ->
ttykb1 LDA #1 ; CHECK kb/tty MODE
BIT sad ; tty?
BEQ start ; YES ->
JSR scand ; wAIT FOR KEY...
BEQ ttykb1 ; NO KEY ->
JSR scand ; DEBOUNCE KEY
BEQ ttykb1 ; NO KEY ->
;
getk JSR getkey
CMP #$15 ; >= $15 = ILLEGAL
BPL start ; YES ->
CMP #$14
BEQ pccmd ; DISPLAY pROGRAM cOUNTER
CMP #$10
BEQ addrm ; ADDRESMODE
CMP #$11
BEQ datam ; DATAMODE
CMP #$12
BEQ step ; STEP
CMP #$13
BEQ gov ; EXECUTE PROGRAM
;
; oNE OF THE HEXIDECIMAL BUTTONS HAS BEEN PUSHED
data ASL ; MOVE lsb KEY NUMBER TO msb
ASL
ASL
ASL
STA temp ; STORE FOR DATAMODE
LDX #4
data1 LDY mode ; PART OF ADDRESS?
BNE addr ; YES ->
LDA (pointl),y ; GET DATA
ASL temp
ROL ; msb-temp = msb-KEY -> a
STA (pointl),y ; STORE NEW DATA
JMP data2
addr ASL ; temp NOT NEEDED HERE
ROL pointl ; msb-KEY -> pointl
ROL pointh ; pointl -> pointh
data2 DEX ; 4 TIMES = COMPLETE NIBBLE?
BNE data1 ; NO ->
BEQ datam2 ; -> ALWAYS
;
; sWITCH TO ADDRESS MODE
addrm LDA #1
BNE datam1 ; -> ALWAYS
;
; sWITCH TO DATA MODE
datam LDA #0
datam1 STA mode
datam2 JMP start
;
; iNCREMENT ADDRESS ON DISPLAY
step JSR incpt
JMP start
;
gov JMP goexec
;
; dISPLAY pc BY MOVING IT TO point
pccmd LDA pcl
STA pointl
LDA pch
STA pointh
JMP start
;
; lOAD PAPERTAPE FROM tty
load JSR getch
CMP #$3b ; ":", SEMICOLON?
BNE load ; nO -> AGAIN
loads LDA #0
STA chksum
STA chkhi
;
JSR getbyt ; GET BYTE cnt
TAX
JSR chk ; cOMPUTE CHECKSUM
;
JSR getbyt ; GET ADDRESS hi
STA pointh
JSR chk ; cOMPUTE CHECKSUM
;
JSR getbyt ; GET ADDRESS lo
STA pointl
JSR chk ; cOMPUTE CHECKSUM
;
TXA ; cnt = 0 ?
BEQ load3
;
load2 JSR getbyt ; GET data
STA (pointl),Y ; STORE DATA
JSR chk
JSR incpt
DEX
BNE load2
INX ; x=1 = DATA RECORD
; x=0 = LAST RECORD
;
load3 JSR getbyt ; COMPARE CHECKSUM
CMP chkhi
BNE loade1
JSR getbyt
CMP chksum
BNE loader
;
TXA ; x=0 = LAST RECORD
BNE load
;
load7 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 ERROR kim
BNE load8 ; ALWAYS ->
;
; dUMP TO tty FROM OPEN CELL ADDRESS TO limhl, limhh
dump LDA #0
STA inl
STA inh ; CLEAR RECORD COUNT
dump0 LDA #0
STA chkhi ; CLEAR CHECKSUM
STA chksum
;
dump1 JSR crlf
LDA #$3b ; ":"
JSR outch
;
; cHECK IF pointl/h >= eal/h
LDA pointl
CMP eal
;
LDA pointh
SBC eah
BCC dump4 ; NO ->
;
LDA #0 ; PRINT LAST RECORD
JSR prtbyt ; 0 BYTES
JSR open
JSR prtpnt
;
LDA chkhi ; PRINT CHECKSUM
JSR prtpnt ; FOR LAST RECORD
LDA chksum
JSR prtbyt
JSR chk
JMP clear
;
dump4 LDA #$18 ; PRINT 24 BYTES
TAX ; SAVE AS INDEX
JSR prtbyt
JSR chk
JSR prtpnt
;
dump2 LDY #0
LDA (pointl),Y
JSR prtbyt ; PRINT DATA
JSR chk
JSR incpt
DEX ; pRINTED EVERYTHING?
BNE dump2 ; nO ->
;
LDA chkhi
JSR prtbyt ; PRINT CHECKSUM
LDA chksum
JSR prtbyt
INC inl ; INCREMENT RECOURD COUNTER
BNE dump3
INC inh
dump3 JMP dump0
;
space JSR open ; OPEN NEW CELL
show JSR crlf
show1 JSR prtpnt
JSR outsp ; PRINT SPACE
LDY #0
LDA (pointl),Y ; PRINT DATA
JSR prtbyt
JSR outsp ; PRINT SPACE
JMP clear
;
rtrn JSR incpt ; NEXT ADDRESS
JMP show
; sTART A PROGRAM AT DISPLAYED ADDRESS. rti IS USED AS A COMFORTABLE
; WAY TO DEFINE ALL FLAGS IN ONE MOVE.
goexec LDX spuser ; USER USER DEFINED STACK
TXS
LDA pointh ; PROGRAM RUNS FROM
PHA ; DISPLAYED ADDRESS
LDA pointl
PHA
LDA preg ; USER DEFINED fLAG REGISTER
PHA
LDX xreg
LDY yreg
LDA acc
RTI ; START PROGRAM
;
; tAKE CARE IF tty-INPUT
scan CMP #$20 ; OPEN NEW CELL
BEQ space
CMP #$7f ; RUB OUT, RESTART kim
BEQ stv
CMP #$0d ; NEXT CELL
BEQ rtrn
CMP #$0a ; PREV CELL
BEQ feed
CMP #$2e ; "." = MODIFY CELL
BEQ modify
CMP #$47 ; "g" = EXEC PROGRAM
BEQ goexec
CMP #$51 ; "q" = DUMP FROM OPEN CELL
BEQ dumpv ; TO hi LIMIT
CMP #$4c ; "l" = LOAD TAPE
BEQ loadv
JMP read ; IGNORE ILLEGAL char
;
stv JMP start
dumpv JMP dump
loadv JMP load
;
feed SEC
LDA pointl ; DECREMENT pointl/h
SBC #1
STA pointl
BCS feed1
DEC pointh
feed1 JMP show
;
modify LDY #0 ; GET CONTENTS OF INPUT BUFFER
LDA inl ; inl AND STORE IN LOCATION
STA (pointl),Y ; SPECIFIED BY point
JMP rtrn
;
; sUBROUTINE TO PRINT point = ADDRESS
prtpnt LDA pointh
JSR prtbyt
JSR chk
LDA pointl
JSR prtbyt
JSR chk
RTS
;
; pRINT ascii-STRING FROM top+x TO top
crlf LDX #7 ; OUTPUT <return> AND <lf>
prtst LDA top,X
JSR outch
DEX ; EVERYTHING?
BPL prtst ; NO ->
prt1 RTS
;
; pRINT 1 HEX BYTE AS 2 ascii CHARS
prtbyt STA temp ; SAVE a
LSR ; SHIFT a 4 TIMES
LSR
LSR
LSR
JSR hexta ; CONVERT BIT 4..7 TO hex AND PRINT
LDA temp
JSR hexta ; CONVERT BIT 0..7 TO hex AND PRINT
LDA temp ; RESTORE a
RTS
;
hexta AND #$0f ; MASK BIT 0..4
CMP #$0a ; > 10 ?
CLC
BMI hexta1 ; NO ->
ADC #7 ; a..f
hexta1 ADC #$30 ; CONVERT TO ascii-CHAR...
JMP outch ; ...AND PRINT IT
;
; gET CHAR FROM tty IN a
getch STX tmpx
LDX #8 ; COUNT 8 BITS
LDA #1
get1 BIT sad ; CHECK IF tty-MODE
BNE get6 ; NO ->
; pa7 IS INPUT tty
BMI get1 ; WAIT FOR STARTBIT
JSR delay ; DELAY 1 BIT
;
; bY DELAYING ANOTHER HALF BIT TIME, YOU READ THE BIT IN THE MIDDLE
; OF EVERY BIT.
get5 JSR dehalf ; DELAY 1/2 BIT TIME
get2 LDA sad
AND #$80 ; MASK BIT 7
LSR char ; SHIFT LAST RESULT
ORA char ; or IT WITH NEW BIT
STA char ; AND STORE IT AGAIN
JSR delay
DEX
BNE get2 ; NEXT BIT
JSR dehalf ; WHY ????
;
LDX tmpx
LDA char
ROL ; SHIFT OFF STOPBIT
LSR
get6 RTS
;
; iNITIALIZATION 6530 $1e88
inits LDX #1 ; SET DISPLAY TO ADDRESS MODE
STX mode
;
init1 LDx #0
STX padd ; pa0..pa7 = INPUT
LDx #$3f
STX pbdd ; pb0..pb5 = OUTPUT
; pb6, pb7 = INPUT
LDX #7 ; ENABLE 74145 OUTPUT 3 TO
STX sbd ; CHECK kb/tty-MODE
CLD
SEI
RTS
;
; oUTPUT CHAR IN a TO tty $1e9e
outsp LDA #" " ; PRINT SPACE
outch STA char
STX tmpx
JSR delay
LDA sbd
AND #$fe ; SEND STARTBIT
STA sbd ; pb0 = 0 -> tty := (h)
JSR delay
;
LDX #8 ; SEND CHARACTER
out1 LDA sbd
AND #$fe ; CLEAR BIT 0
LSR char ; SHIFT BYTE
ADC #0 ; ADD cARRY = FORMER BIT 0
STA sbd ; OUTPUT BIT
JSR delay
DEX ; ALL BITS?
BNE out1 ; NO ->
LDA sbd
ORA #1
STA sbd ; STOP BIT
JSR delay
LDX tmpx
RTS
;
; dELAY 1 BIT TIME AS DETERMINED BY detcps
delay LDA cnth30
STA timh
LDA cntl30
de2 SEC
de4 SBC #1
BCS de3 ; a<>$ff ->
DEC timh
de3 LDY timh ; timh > 0 ?
BPL de2 ; YES ->
RTS
;
; dELAY HALF A BIT TIME
dehalf LDA cnth30
STA timh
LDA cntl30
LSR
LSR timh
BCC de2
ORA #$80
BCS de4 ; ALWAYS ->
; wHY NOT:
; LSR timh
; ROR
; JMP de2
; ????
;
;
; dETERMINE IF KEY IS DEPRESSED: no -> a=0, yes -> a>0
ak LDY #3 ; 3 ROWS
LDx #1 ; SELECT 74145 OUTPUT 0
onekey LDA #$ff ; INITIAL VALUE
;
aka STX sbd ; ENABLE OUTPUT = SELECT ROW
INX
INX ; PREPARE FOR NEXT ROW
AND sad ; a := a && (pa0..pa7)
DEY ; ALL ROWS?
BNE aka ; NO ->
LDY #7
STY sbd ; SELECT 74145 OUTPUT 3 (NOT USED)
;
ORA #$80 ; MASK BIT 7 OF a
EOR #$ff ; IF a STILL IS $ff -> a := 0
RTS
;
; oUTPUT TO 7-SEGMENT-DISPLAY
scand LDY #0 ; pointl/pointh = ADDRESS ON DISPLAY
LDA (pointl),y ; GET DATA FROM THIS ADDRESS
STA inh ; STORE IN inh =
scands LDA #$7f ; pa0..pa6 := OUTPUT
STA padd
LDx #9 ; sTART WITH DISPLAY AT OUTPUT 4
LDY #3 ; 3 BYTES TO BE SHOWN
;
scand1 LDA inl_a,Y ; GET BYTE
LSR ; GET msd BY SHIFTING a
LSR
LSR
LSR
JSR convd
LDA inl_a,Y ; GET BYTE AGAIN
AND #$0f ; GET lsd
JSR convd
DEY ; ALL ?
BNE scand1 ; NO ->
STY sbd ; ALL DIGITS OFF
LDA #0
STA padd ; pa0..pa7 := INPUT
JMP ak
;
; cONVERT DIGIT INTO 7-SEGMENT-VALUE
convd STY temp
TAY
LDA table,y
LDY #0
STY sad ; TURN OFF SEGMENTS
STX sbd ; SELECT 7-S-DISPLAY
STA sad ; OUTPUT CODE ON DISPLAY
LDY #$7f ; DELAY {$7e}500 CYCLES
convd1 DEY
BNE convd1
INX ; NEXT DISPLAY
INX
LDY temp
RTS
;
; iNCREMENT point = ADDRESS ON DISPLAY
incpt INC pointl
BNE incpt2
INC pointh
incpt2 RTS
;
; gET KEY FROM KEYBOARD IN a
getkey LDX #$21 ; ROW 0 / DISABLE INPUT tty
getke5 LDY #1 ; ONLY ONE ROW IN THE TIME
JSR onekey ; KEY?
BNE keyin ; YES ->
CPX #$27 ; LAST ROW?
BNE getke5 ; NO, NEXT ONE ->
LDA #$15 ; 15 = NO KEY
RTS
;
keyin LDY #$ff ; y := KEY NUMBER
keyin1 ASL ; SHIFT a UNTIL
BCS keyin2 ; BIT = 1 ->
;
; cOMMENT: BIT 7 IS ALWAYS 0 SO cARRY IS ALWAYS 0 THE FIRST TIME
; AND ALLOWING y TO BECOME 0 (KEY $ff DOES NOT EXIST)
INY
BPL keyin1 ; ALWAYS ->
keyin2 TXA
AND #$0f ; STRIP BIT4..7
LSR ; a := ROW+1
TAX ; x := ACTUAL ROW+1
TYA
BPL keyin4 ; ALWAYS, BECAUSE y<7 ->
;
; aDD 7 TO a FOR EVERY ROW ABOVE 0 TO GET ACTUAL KEY NUMBER
keyin3 CLC
ADC #7 ; ADD (x-1) TIMES 7 TO a
keyin4 DEX ; COUNTDOWN TO 0
BNE keyin3
RTS ; a IS ALWAYS < 21 EG. < $15
;
; cOMPUTE CHECKSUM
chk CLC
ADC chksum
STA chksum
LDA chkhi
ADC #0
STA chkhi
RTS
;
; gET 2 HEX-CHARS AND PACK INTO inl AND inh
; nON HEX CHAR WILL BE LOADED AS NEARSEST HEX EQUIVALENT
getbyt JSR getch
JSR pack
LSR getch
JSR pack
LDA inl
RTS
;
; sHIFT CHAR IN a INTO inl AND inh
pack CMP #$30 ; IS HEX?
BMI updat2 ; < = NO ->
CMP #$47
BPL updat2 ; > = NO ->
hexnum CMP #$40 ; a..f ?
BMI update ; NO ->
hexalp CLC
ADC #9
update ROL ; SHIFT TO BIT 4..7
ROL
ROL
ROL
LDY #4 ; SHIFT INTO inl/inh
updat1 ROL
ROL inl
ROL inh
DEY ; 4 TIMES?
BNE updat1 ; NO ->
LDA #0 ; IF HEX NUMBER -> a := 0
updat2 RTS
;
open LDA inl ; MOVE i/o-BUFFER TO point
STA pointl
LDA inh
STA pointh
RTS
;
; tABELS
top .BY 0, 0, 0, 0, 0, 0, 10, 13
.TX "mik"
.BY " ", $13
.TX "rre "
.BY $13
; hEX -> 7-SEGMENT 0 1 2 3 4 5 6 7
table .BY $bf, $86, $db, $cf, $e6, $ed, $fd, $87
; 8 9 a b c d e f
.BY $ff, $ef, $f7, $fc, $b9, $de, $f9, $f1
;
; cOMMENT: IF EVERYTHING IS COMPILED RIGHT, NEXT VECTORS SHOULD
; START AT $fffa
nmient .WO nmit
rstent .WO reset
irqent .WO irqt
.EN