home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-07-30 | 81.4 KB | 1,945 lines |
- # $iD: 64DOC,V 1.8 1994/06/03 19:50:04 JOPI eXP $
- #
- # tHIS FILE IS PART OF cOMMODORE 64 EMULATOR
- # AND pROGRAM dEVELOPMENT sYSTEM.
- #
- # sEE readme FOR COPYRIGHT NOTICE
- #
- # tHIS FILE CONTAINS DOCUMENTATION FOR 6502/6510/8500/8502 INSTRUCTION SET.
- #
- #
- # wRITTEN BY
- # jOHN wEST (JOHN@UCC.GU.UWA.EDU.AU)
- # mARKO m{$e4}KEL{$e4} (mARKO.mAKELA@hut.fi)
- #
- #
- # $lOG: 64DOC,V $
- # rEVISION 1.8 1994/06/03 19:50:04 JOPI
- # pATCHLEVEL 2
- #
- # rEVISION 1.7 1994/04/15 13:07:04 JOPI
- # 65XX rEGISTER DESCRIPTIONS ADDED
- #
- # rEVISION 1.6 1994/02/18 16:09:36 JOPI
- #
- # rEVISION 1.5 1994/01/26 16:08:37 JOPI
- # x64 VERSION 0.2 pl 1
- #
- # rEVISION 1.4 1993/11/10 01:55:34 JOPI
- #
- # rEVISION 1.3 93/06/21 13:37:18 JOPI
- # x64 VERSION 0.2 pl 0
- #
- # rEVISION 1.2 93/06/21 13:07:15 JOPI
- # *** EMPTY LOG MESSAGE ***
- #
- #
-
- nOTE: tO EXTRACT THE UUENCODED ml PROGRAMS IN THIS ARTICLE MOST
- EASILY YOU MAY USE E.G. "UUD" BY eDWIN kREMER <EDWIN@ZLOTTY>,
- WHICH EXTRACTS THEM ALL AT ONCE.
-
-
-
- dOCUMENTATION FOR THE nmos 65XX/85XX iNSTRUCTION sET
-
- 6510 iNSTRUCTIONS BY aDDRESSING mODES
- 6502 rEGISTERS
- 6510/8502 uNDOCUMENTED cOMMANDS
- rEGISTER SELECTION FOR LOAD AND STORE
- dECIMAL MODE IN nmos 6500 SERIES
- 6510 FEATURES
- dIFFERENT cpu TYPES
- 6510 iNSTRUCTION tIMING
- hOW rEAL pROGRAMMERS aCKNOWLEDGE iNTERRUPTS
- mEMORY mANAGEMENT
- aUTOSTART cODE
- nOTES
- rEFERENCES
-
-
- 6510 iNSTRUCTIONS BY aDDRESSING mODES
-
- OFF- ++++++++++ pOSITIVE ++++++++++ ---------- nEGATIVE ----------
- SET 00 20 40 60 80 A0 C0 E0 MODE
-
- +00 brk jsr rti rts nop* ldy cpy cpx iMPL/IMMED
- +01 ora and eor adc sta lda cmp sbc (INDIR,X)
- +02 T T T T nop*T ldx nop*T nop*T ? /IMMED
- +03 slo* rla* sre* rra* sax* lax* dcp* isb* (INDIR,X)
- +04 nop* bit nop* nop* sty ldy cpy cpx zEROPAGE
- +05 ora and eor adc sta lda cmp sbc zEROPAGE
- +06 asl rol lsr ror stx ldx dec inc zEROPAGE
- +07 slo* rla* sre* rra* sax* lax* dcp* isb* zEROPAGE
-
- +08 php plp pha pla dey tay iny inx iMPLIED
- +09 ora and eor adc nop* lda cmp sbc iMMEDIATE
- +0A asl rol lsr ror txa tax dex nop aCCU/IMPL
- +0B anc** anc** asr** arr** ane** lxa** sbx** sbc* iMMEDIATE
- +0C nop* bit jmp jmp () sty ldy cpy cpx aBSOLUTE
- +0D ora and eor adc sta lda cmp sbc aBSOLUTE
- +0E asl rol lsr ror stx ldx dec inc aBSOLUTE
- +0F slo* rla* sre* rra* sax* lax* dcp* isb* aBSOLUTE
-
- +10 bpl bmi bvc bvs bcc bcs bne beq rELATIVE
- +11 ora and eor adc sta lda cmp sbc (INDIR),Y
- +12 T T T T T T T T ?
- +13 slo* rla* sre* rra* sha** lax* dcp* isb* (INDIR),Y
- +14 nop* nop* nop* nop* sty ldy nop* nop* zEROPAGE,X
- +15 ora and eor adc sta lda cmp sbc zEROPAGE,X
- +16 asl rol lsr ror stx Y) ldx Y) dec inc zEROPAGE,X
- +17 slo* rla* sre* rra* sax* Y) lax* Y) dcp* isb* zEROPAGE,X
-
- +18 clc sec cli sei tya clv cld sed iMPLIED
- +19 ora and eor adc sta lda cmp sbc aBSOLUTE,Y
- +1A nop* nop* nop* nop* txs tsx nop* nop* iMPLIED
- +1B slo* rla* sre* rra* shs** las** dcp* isb* aBSOLUTE,Y
- +1C nop* nop* nop* nop* shy** ldy nop* nop* aBSOLUTE,X
- +1D ora and eor adc sta lda cmp sbc aBSOLUTE,X
- +1E asl rol lsr ror shx**Y) ldx Y) dec inc aBSOLUTE,X
- +1F slo* rla* sre* rra* sha**Y) lax* Y) dcp* isb* aBSOLUTE,X
-
-
- ror INTRUCTION IS AVAILABLE ON mc650X MICROPROCESSORS AFTER
- jUNE, 1976.
-
-
- lEGEND:
-
- T jAMS THE MACHINE
- *T jAMS VERY RARELY
- * uNDOCUMENTED COMMAND
- ** uNUSUAL OPERATION
- Y) INDEXED USING y INSTEAD OF x
- () INDIRECT INSTEAD OF ABSOLUTE
-
- nOTE THAT THE nop INSTRUCTIONS DO HAVE OTHER ADDRESSING MODES
- THAN THE IMPLIED ADDRESSING. tHE nop INSTRUCTION IS JUST LIKE
- ANY OTHER LOAD INSTRUCTION, EXCEPT IT DOES NOT STORE THE
- RESULT ANYWHERE NOR AFFECTS THE FLAGS.
-
-
- 6502 rEGISTERS
-
- tHE nmos 65XX PROCESSORS ARE NOT RUINED WITH TOO MANY REGISTERS. iN
- ADDITION TO THAT, THE REGISTERS ARE MOSTLY 8-BIT. hERE IS A BRIEF
- DESCRIPTION OF EACH REGISTER:
-
- pc pROGRAM cOUNTER
-
- tHIS REGISTER POINTS THE ADDRESS FROM WHICH THE NEXT
- INSTRUCTION BYTE (OPCODE OR PARAMETER) WILL BE FETCHED.
- uNLIKE OTHER REGISTERS, THIS ONE IS 16 BITS IN LENGTH. tHE
- LOW AND HIGH 8-BIT HALVES OF THE REGISTER ARE CALLED pcl
- AND pch, RESPECTIVELY.
-
- tHE pROGRAM cOUNTER MAY BE READ BY PUSHING ITS VALUE ON
- THE STACK. tHIS CAN BE DONE EITHER BY JUMPING TO A
- SUBROUTINE OR BY CAUSING AN INTERRUPT.
-
- s sTACK POINTER
-
- tHE nmos 65XX PROCESSORS HAVE 256 BYTES OF STACK MEMORY,
- RANGING FROM $0100 TO $01ff. tHE s REGISTER IS A 8-BIT
- OFFSET TO THE STACK PAGE. iN OTHER WORDS, WHENEVER
- ANYTHING IS BEING PUSHED ON THE STACK, IT WILL BE STORED
- TO THE ADDRESS $0100+s.
-
- tHE sTACK POINTER CAN BE READ AND WRITTEN BY TRANSFERING
- ITS VALUE TO OR FROM THE INDEX REGISTER x (SEE BELOW) WITH
- THE tsx AND txs INSTRUCTIONS.
-
- p pROCESSOR STATUS
-
- tHIS 8-BIT REGISTER STORES THE STATE OF THE PROCESSOR. tHE
- BITS IN THIS REGISTER ARE CALLED FLAGS. mOST OF THE FLAGS
- HAVE SOMETHING TO DO WITH ARITHMETIC OPERATIONS.
-
- tHE p REGISTER CAN BE READ BY PUSHING IT ON THE STACK
- (WITH php OR BY CAUSING AN INTERRUPT). iF YOU ONLY NEED TO
- READ ONE FLAG, YOU CAN USE THE BRANCH INSTRUCTIONS.
- sETTING THE FLAGS IS POSSIBLE BY PULLING THE p REGISTER
- FROM STACK OR BY USING THE FLAG SET OR CLEAR INSTRUCTIONS.
-
- fOLLOWING IS A LIST OF THE FLAGS, STARTING FROM THE 8TH
- BIT OF THE p REGISTER (BIT 7, VALUE $80):
-
- n nEGATIVE FLAG
-
- tHIS FLAG WILL BE SET AFTER ANY ARITHMETIC OPERATIONS
- (WHEN ANY OF THE REGISTERS a, x OR y IS BEING LOADED
- WITH A VALUE). gENERALLY, THE n FLAG WILL BE COPIED
- FROM THE TOPMOST BIT OF THE REGISTER BEING LOADED.
-
- nOTE THAT txs (tRANSFER x TO s) IS NOT AN ARITHMETIC
- OPERATION. aLSO NOTE THAT THE bit INSTRUCTION AFFECTS
- THE nEGATIVE FLAG JUST LIKE ARITHMETIC OPERATIONS.
- fINALLY, THE nEGATIVE FLAG BEHAVES DIFFERENTLY IN
- dECIMAL OPERATIONS (SEE DESCRIPTION BELOW).
-
- v OvERFLOW FLAG
-
- lIKE THE nEGATIVE FLAG, THIS FLAG IS INTENDED TO BE
- USED WITH 8-BIT SIGNED INTEGER NUMBERS. tHE FLAG WILL
- BE AFFECTED BY ADDITION AND SUBTRACTION, THE
- INSTRUCTIONS plp, clv AND bit, AND THE HARDWARE SIGNAL
- -so. nOTE THAT THERE IS NO sev INSTRUCTION, EVEN THOUGH
- THE mos ENGINEERS LOVED TO USE eAST eUROPEAN ABBREVIATIONS,
- LIKE ddr (dEUTSCHE dEMOKRATISCHE rEPUBLIK VS. dATA
- dIRECTION rEGISTER). (tHE rUSSIAN ABBREVIATION FOR THEIR
- FORMER TRADE ASSOCIATION comecon IS sev.) tHE -so
- (sET oVERFLOW) SIGNAL IS AVAILABLE ON SOME PROCESSORS,
- AT LEAST THE 6502, TO SET THE v FLAG. tHIS ENABLES
- RESPONSE TO AN i/o ACTIVITY IN EQUAL OR LESS THAN
- THREE CLOCK CYCLES WHEN USING A bvc INSTRUCTION BRANCHING
- TO ITSELF ($50 $fe).
-
- tHE clv INSTRUCTION CLEARS THE v FLAG, AND THE plp AND
- bit INSTRUCTIONS COPY THE FLAG VALUE FROM THE BIT 6 OF
- THE TOPMOST STACK ENTRY OR FROM MEMORY.
-
- aFTER A BINARY ADDITION OR SUBTRACTION, THE v FLAG
- WILL BE SET ON A SIGN OVERFLOW, CLEARED OTHERWISE.
- wHAT IS A SIGN OVERFLOW? fOR INSTANCE, IF YOU ARE
- TRYING TO ADD 123 AND 45 TOGETHER, THE RESULT (168)
- DOES NOT FIT IN A 8-BIT SIGNED INTEGER (UPPER LIMIT
- 127 AND LOWER LIMIT -128). sIMILARLY, ADDING -123 TO
- -45 CAUSES THE OVERFLOW, JUST LIKE SUBTRACTING -45
- FROM 123 OR 123 FROM -45 WOULD DO.
-
- lIKE THE n FLAG, THE v FLAG WILL NOT BE SET AS
- EXPECTED IN THE dECIMAL MODE. lATER IN THIS DOCUMENT
- IS A PRECISE OPERATION DESCRIPTION.
-
- a COMMON MISBELIEF IS THAT THE v FLAG COULD ONLY BE
- SET BY ARITHMETIC OPERATIONS, NOT CLEARED.
-
- 1 UNUSED FLAG
-
- tO THE CURRENT KNOWLEDGE, THIS FLAG IS ALWAYS 1.
-
- b bREAK FLAG
-
- tHIS FLAG IS USED TO DISTINGUISH SOFTWARE (brk)
- INTERRUPTS FROM HARDWARE INTERRUPTS (irq OR nmi). tHE
- b FLAG IS ALWAYS SET EXCEPT WHEN THE p REGISTER IS
- BEING PUSHED ON STACK WHEN JUMPING TO AN INTERRUPT
- ROUTINE TO PROCESS ONLY A HARDWARE INTERRUPT.
-
- tHE OFFICIAL nmos 65XX DOCUMENTATION CLAIMS THAT THE
- brk INSTRUCTION COULD ONLY CAUSE A JUMP TO THE irq
- VECTOR ($fffe). hOWEVER, IF AN nmi INTERRUPT OCCURS
- WHILE EXECUTING A brk INSTRUCTION, THE PROCESSOR WILL
- JUMP TO THE nmi VECTOR ($fffa), AND THE p REGISTER
- WILL BE PUSHED ON THE STACK WITH THE b FLAG SET.
-
- d dECIMAL MODE FLAG
-
- tHIS FLAG IS USED TO SELECT THE (bINARY cODED) dECIMAL
- MODE FOR ADDITION AND SUBTRACTION. iN MOST
- APPLICATIONS, THE FLAG IS ZERO.
-
- tHE dECIMAL MODE HAS MANY ODDITIES, AND IT OPERATES
- DIFFERENTLY ON cmos PROCESSORS. sEE THE DESCRIPTION
- OF THE adc, sbc AND arr INSTRUCTIONS BELOW.
-
- i iNTERRUPT DISABLE FLAG
-
- tHIS FLAG CAN BE USED TO PREVENT THE PROCESSOR FROM
- JUMPING TO THE irq HANDLER VECTOR ($fffe) WHENEVER THE
- HARDWARE LINE -irq IS ACTIVE. tHE FLAG WILL BE
- AUTOMATICALLY SET AFTER TAKING AN INTERRUPT, SO THAT
- THE PROCESSOR WOULD NOT KEEP JUMPING TO THE INTERRUPT
- ROUTINE IF THE -irq SIGNAL REMAINS LOW FOR SEVERAL
- CLOCK CYCLES.
-
- z zERO FLAG
-
- tHE zERO FLAG WILL BE AFFECTED IN THE SAME CASES THAN
- THE nEGATIVE FLAG. gENERALLY, IT WILL BE SET IF AN
- ARITHMETIC REGISTER IS BEING LOADED WITH THE VALUE
- ZERO, AND CLEARED OTHERWISE. tHE FLAG WILL BEHAVE
- DIFFERENTLY IN dECIMAL OPERATIONS.
-
- c cARRY FLAG
-
- tHIS FLAG IS USED IN ADDITIONS, SUBTRACTIONS,
- COMPARISONS AND BIT ROTATIONS. iN ADDITIONS AND
- SUBTRACTIONS, IT ACTS AS A 9TH BIT AND LETS YOU TO
- CHAIN OPERATIONS TO CALCULATE WITH BIGGER THAN 8-BIT
- NUMBERS. wHEN SUBTRACTING, THE cARRY FLAG IS THE
- NEGATIVE OF bORROW: IF AN OVERFLOW OCCURS, THE FLAG
- WILL BE CLEAR, OTHERWISE SET. cOMPARISONS ARE A
- SPECIAL CASE OF SUBTRACTION: THEY ASSUME cARRY FLAG
- SET AND dECIMAL FLAG CLEAR, AND DO NOT STORE THE
- RESULT OF THE SUBTRACTION ANYWHERE.
-
- tHERE ARE FOUR KINDS OF BIT ROTATIONS. aLL OF THEM
- STORE THE BIT THAT IS BEING ROTATED OFF TO THE cARRY
- FLAG. tHE LEFT SHIFTING INSTRUCTIONS ARE rol AND asl.
- rol COPIES THE INITIAL cARRY FLAG TO THE LOWMOST BIT
- OF THE BYTE; asl ALWAYS CLEARS IT. sIMILARLY, THE ror
- AND lsr INSTRUCTIONS SHIFT TO THE RIGHT.
-
- a aCCUMULATOR
-
- tHE ACCUMULATOR IS THE MAIN REGISTER FOR ARITHMETIC AND
- LOGIC OPERATIONS. uNLIKE THE INDEX REGISTERS x AND y, IT
- HAS A DIRECT CONNECTION TO THE aRITHMETIC AND lOGIC uNIT
- (alu). tHIS IS WHY MANY OPERATIONS ARE ONLY AVAILABLE FOR
- THE ACCUMULATOR, NOT THE INDEX REGISTERS.
-
- x iNDEX REGISTER x
-
- tHIS IS THE MAIN REGISTER FOR ADDRESSING DATA WITH
- INDICES. iT HAS A SPECIAL ADDRESSING MODE, INDEXED
- INDIRECT, WHICH LETS YOU TO HAVE A VECTOR TABLE ON THE
- ZERO PAGE.
-
- y iNDEX REGISTER y
-
- tHE y REGISTER HAS THE LEAST OPERATIONS AVAILABLE. oN THE
- OTHER HAND, ONLY IT HAS THE INDIRECT INDEXED ADDRESSING
- MODE THAT ENABLES ACCESS TO ANY MEMORY PLACE WITHOUT
- HAVING TO USE SELF-MODIFYING CODE.
-
-
-
- 6510/8502 uNDOCUMENTED cOMMANDS
-
- -- a BRIEF EXPLANATION ABOUT WHAT MAY HAPPEN WHILE
- USING DON'T CARE STATES.
-
-
- ane $8b a = (a {$7c} #$ee) & x & #BYTE
- SAME AS
- a = ((a & #$11 & x) {$7c} ( #$ee & x)) & #BYTE
-
- iN REAL 6510/8502 THE INTERNAL PARAMETER #$11
- MAY OCCASIONALLY BE #$10, #$01 OR EVEN #$00.
- tHIS OCCURS WHEN THE VIDEO CHIP STARTS dma
- BETWEEN THE OPCODE FETCH AND THE PARAMETER FETCH
- OF THE INSTRUCTION. tHE VALUE PROBABLY DEPENDS
- ON THE DATA THAT WAS LEFT ON THE BUS BY THE vic-ii.
-
- lxa $ab c=lEHTI: a = x = ane
- aLTERNATE: a = x = (a & #BYTE)
-
- txa AND tax HAVE TO BE RESPONSIBLE FOR THESE.
-
- sha $93,$9f sTORE (a & x & (addr_hi + 1))
- shx $9e sTORE (x & (addr_hi + 1))
- shy $9c sTORE (y & (addr_hi + 1))
- shs $9b sha AND txs, WHERE x IS REPLACED BY (a & x).
-
- nOTE: tHE VALUE TO BE STORED IS COPIED ALSO
- TO addr_hi IF PAGE BOUNDARY IS CROSSED.
-
- sbx $cb cARRY AND dECIMAL FLAGS ARE IGNORED BUT THE
- cARRY FLAG WILL BE SET IN SUBSTRACTION. tHIS
- IS DUE TO THE cmp COMMAND, WHICH IS EXECUTED
- INSTEAD OF THE REAL sbc.
-
- arr $6b tHIS INSTRUCTION FIRST PERFORMS AN and
- BETWEEN THE ACCUMULATOR AND THE IMMEDIATE
- PARAMETER, THEN IT SHIFTS THE ACCUMULATOR TO
- THE RIGHT. hOWEVER, THIS IS NOT THE WHOLE
- TRUTH. sEE THE DESCRIPTION BELOW.
-
- mANY UNDOCUMENTED COMMANDS DO NOT USE and BETWEEN REGISTERS, THE cpu
- JUST THROWS THE BYTES TO A BUS SIMULTANEOUSLY AND LETS THE
- OPEN-COLLECTOR DRIVERS PERFORM THE and. i.E. THE COMMAND CALLED 'sax',
- WHICH IS IN THE store SECTION (OPCODES $a0...$bf), STORES THE RESULT
- OF (a & x) BY THIS WAY.
-
- mORE FORTUNATE IS ITS OPPOSITE, 'lax' WHICH JUST LOADS A BYTE
- SIMULTANEOUSLY INTO BOTH a AND x.
-
-
- $6b arr
-
- tHIS INSTRUCTION SEEMS TO BE A HARMLESS COMBINATION OF and AND ror AT
- FIRST SIGHT, BUT IT TURNS OUT THAT IT AFFECTS THE v FLAG AND ALSO HAS
- A SPECIAL KIND OF DECIMAL MODE. tHIS IS BECAUSE THE INSTRUCTION HAS
- INHERITED SOME PROPERTIES OF THE adc INSTRUCTION ($69) IN ADDITION TO
- THE ror ($6a).
-
- iN bINARY MODE (d FLAG CLEAR), THE INSTRUCTION EFFECTIVELY DOES AN and
- BETWEEN THE ACCUMULATOR AND THE IMMEDIATE PARAMETER, AND THEN SHIFTS
- THE ACCUMULATOR TO THE RIGHT, COPYING THE c FLAG TO THE 8TH BIT. iT
- SETS THE nEGATIVE AND zERO FLAGS JUST LIKE THE ror WOULD. tHE adc CODE
- SHOWS UP IN THE cARRY AND OvERFLOW FLAGS. tHE c FLAG WILL BE COPIED
- FROM THE BIT 6 OF THE RESULT (WHICH DOESN'T SEEM TOO LOGICAL), AND THE
- v FLAG IS THE RESULT OF AN eXCLUSIVE or OPERATION BETWEEN THE BIT 6
- AND THE BIT 5 OF THE RESULT. tHIS MAKES SENSE, SINCE THE v FLAG WILL
- BE NORMALLY SET BY AN eXCLUSIVE or, TOO.
-
- iN dECIMAL MODE (d FLAG SET), THE arr INSTRUCTION FIRST PERFORMS THE
- and AND ror, JUST LIKE IN bINARY MODE. tHE n FLAG WILL BE COPIED FROM
- THE INITIAL c FLAG, AND THE z FLAG WILL BE SET ACCORDING TO THE ror
- RESULT, AS EXPECTED. tHE v FLAG WILL BE SET IF THE BIT 6 OF THE
- ACCUMULATOR CHANGED ITS STATE BETWEEN THE and AND THE ror, CLEARED
- OTHERWISE.
-
- nOW COMES THE FUNNY PART. iF THE LOW NYBBLE OF THE and RESULT,
- INCREMENTED BY ITS LOWMOST BIT, IS GREATER THAN 5, THE LOW NYBBLE IN
- THE ror RESULT WILL BE INCREMENTED BY 6. tHE LOW NYBBLE MAY OVERFLOW
- AS A CONSEQUENCE OF THIS bcd FIXUP, BUT THE HIGH NYBBLE WON'T BE
- ADJUSTED. tHE HIGH NYBBLE WILL BE bcd FIXED IN A SIMILAR WAY. iF THE
- HIGH NYBBLE OF THE and RESULT, INCREMENTED BY ITS LOWMOST BIT, IS
- GREATER THAN 5, THE HIGH NYBBLE IN THE ror RESULT WILL BE INCREMENTED
- BY 6, AND THE cARRY FLAG WILL BE SET. oTHERWISE THE c FLAG WILL BE
- CLEARED.
-
- tO HELP YOU UNDERSTAND THIS DESCRIPTION, HERE IS A c ROUTINE THAT
- ILLUSTRATES THE arr OPERATION IN dECIMAL MODE:
-
- UNSIGNED
- a, /* aCCUMULATOR */
- al, /* LOW NYBBLE OF ACCUMULATOR */
- ah, /* HIGH NYBBLE OF ACCUMULATOR */
-
- c, /* cARRY FLAG */
- z, /* zERO FLAG */
- v, /* OvERFLOW FLAG */
- n, /* nEGATIVE FLAG */
-
- T, /* TEMPORARY VALUE */
- S; /* VALUE TO BE arrED WITH aCCUMULATOR */
-
- T = a & S; /* pERFORM THE and. */
-
- ah = T >> 4; /* sEPARATE THE HIGH */
- al = T & 15; /* AND LOW NYBBLES. */
-
- n = c; /* sET THE n AND */
- z = !(a = (T >> 1) {$7c} (c << 7)); /* z FLAGS TRADITIONALLY */
- v = (T ^ a) & 64; /* AND v FLAG IN A WEIRD WAY. */
-
- IF (al + (al & 1) > 5) /* bcd "FIXUP" FOR LOW NYBBLE. */
- a = (a & 0Xf0) {$7c} ((a + 6) & 0Xf);
-
- IF (c = ah + (ah & 1) > 5) /* sET THE cARRY FLAG. */
- a = (a + 0X60) & 0Xff; /* bcd "FIXUP" FOR HIGH NYBBLE. */
-
-
-
- $cb sbx x <- (a & x) - iMMEDIATE
-
- tHE 'sbx' ($cb) MAY SEEM TO BE VERY COMPLEX OPERATION, EVEN THOUGH IT
- IS A COMBINATION OF THE SUBTRACTION OF ACCUMULATOR AND PARAMETER, AS
- IN THE 'cmp' INSTRUCTION, AND THE COMMAND 'dex'. aS A RESULT, BOTH a
- AND x ARE CONNECTED TO alu BUT ONLY THE SUBTRACTION TAKES PLACE. sINCE
- THE COMPARISON LOGIC WAS USED, THE RESULT OF SUBTRACTION SHOULD BE
- NORMALLY IGNORED, BUT THE 'dex' NOW HAPPILY STORES TO x THE VALUE OF
- (a & x) - iMMEDIATE. tHAT IS WHY THIS INSTRUCTION DOES NOT HAVE ANY
- DECIMAL MODE, AND IT DOES NOT AFFECT THE v FLAG. aLSO cARRY FLAG WILL
- BE IGNORED IN THE SUBTRACTION BUT SET ACCORDING TO THE RESULT.
-
- pROOF:
-
- BEGIN 644 VSBX
- m{$60}0@9$,d'gl(h-#,ijc(u-js"*#0t*:hr-@{$60}{$60}{$60}*d{$60}h#v1*z{$60}_d2n@09$kj0>%
- m^qbe^vezj+$kh#f1*zd{$60}2"bi{$60}*({$60}rp{$60}(:-b@.5$k*4#p{$60}e@{$60}h#vq*sai{$60})$k
- jd-z@/[$k:0"1*y#4j2x@to\xh$&q*vd{$60}d2n0q,;[$+188/_^]_:_ok>v
- {$60}
- END
-
- AND
-
- BEGIN 644 SBX
- m{$60}0@9$,d'gl(h-#,ijc(u-js"*#0t*:hr-@{$60}{$60}{$60}'bi{$60}*!-d2n@3y$kh%&1*zd#
- ma?l8i?m*2){$60}#j1@lj3b@29$k:$j0{$60}zgx+*g8r)$k&/bxj?2b8\l)aop(:(7]
- mv#b@3;$kh$\q*z!1\2l(1?sp{$60}0!h1?tim]#xh$vq*sai{$60})$kd,n@3[$k:0"1
- 9*y#!j2x@to\xh%&q*vd{$60}d2n0l<;[$))88-#x
- {$60}
- END
-
- tHESE TEST PROGRAMS SHOW IF YOUR MACHINE IS COMPATIBLE WITH OURS
- REGARDING THE OPCODE $cb. tHE FIRST TEST, VSBX, PROVES THAT sbx DOES
- NOT AFFECT THE v FLAG. tHE LATTER ONE, SBX, PROVES THE REST OF OUR
- THEORY. tHE VSBX TEST TESTS 33554432 sbx COMBINATIONS (16777216
- DIFFERENT a, x AND iMMEDIATE COMBINATIONS, AND TWO DIFFERENT v FLAG
- STATES), AND THE SBX TEST DOUBLES THAT AMOUNT (16777216*4 d AND c FLAG
- COMBINATIONS). bOTH TESTS HAVE RUN SUCCESSFULLY ON A c64 AND A vIC20.
- tHEY OUGHT TO RUN ON c16, +4 AND THE pet SERIES AS WELL. tHE TESTS
- STOP WITH brk, IF THE OPCODE $cb DOES NOT WORK AS EXPECTED. sUCCESSFUL
- OPERATION ENDS IN rts. aS THE TESTS ARE VERY SLOW, THEY PRINT DOTS ON
- THE SCREEN WHILE RUNNING SO THAT YOU KNOW THAT THE MACHINE HAS NOT
- JAMMED. oN COMPUTERS RUNNING AT 1 mhZ, THE FIRST TEST PRINTS
- APPROXIMATELY ONE DOT EVERY FOUR SECONDS AND A TOTAL OF 2048 DOTS,
- WHEREAS THE SECOND ONE PRINTS HALF THAT AMOUNT, ONE DOT EVERY SEVEN
- SECONDS.
-
- iF THE TESTS FAIL ON YOUR MACHINE, PLEASE LET US KNOW YOUR PROCESSOR'S
- PART NUMBER AND REVISION. iF POSSIBLE, SAVE THE EXECUTABLE (AFTER IT
- HAS STOPPED WITH brk) UNDER ANOTHER NAME AND SEND IT TO US SO THAT WE
- KNOW AT WHICH STAGE THE PROGRAM STOPPED.
-
- tHE FOLLOWING PROGRAM IS A cOMMODORE 64 EXECUTABLE THAT mARKO m{$e4}KEL{$e4}
- DEVELOPED WHEN TRYING TO FIND OUT HOW THE v FLAG IS AFFECTED BY sbx.
- (iT WAS BELIEVED THAT THE sbx AFFECTS THE FLAG IN A WEIRD WAY, AND
- THIS PROGRAM SHOWS HOW sbx SETS THE FLAG DIFFERENTLY FROM sbc.) yOU
- MAY FIND THE SUBROUTINE AT $c150 USEFUL WHEN RESEARCHING OTHER
- UNDOCUMENTED INSTRUCTIONS' FLAGS. rUN THE PROGRAM IN A MACHINE
- LANGUAGE MONITOR, AS IT MAKES USE OF THE brk INSTRUCTION. tHE RESULT
- TABLES WILL BE WRITTEN ON PAGES $c2 AND $c3.
-
- BEGIN 644 SBX-C100
- m{$60},%xh{$60}",#l&,$,&,$l&xj8*b@ll7aol(:(7\n#bm#l$m$,'m$l$(q?op{$60}b@{$60}
- m:$7\\{$60},@4,'n#l'0u.x0p=#/sb#0[a+!t,<{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60}{$60})bj\!>m#l$m
- l$,'=_\'0":t2p=w_pm{$60}!8,k0z:t.p2t0p9d{$60}pid{$60}!*t2p9d{$60}pyd{$60}!<c0y{$60}{$60}m
- {$60}
- END
-
-
- oTHER UNDOCUMENTED INSTRUCTIONS USUALLY CAUSE TWO PRECEDING OPCODES
- BEING EXECUTED. hOWEVER 'nop' SEEMS TO COMPLETELY DISAPPEAR FROM 'sbc'
- CODE $eb.
-
- tHE MOST DIFFICULT TO COMPREHEND ARE THE REST OF THE INSTRUCTIONS
- LOCATED ON THE '$0b' LINE.
-
- aLL THE INSTRUCTIONS LOCATED AT THE POSITIVE (LEFT) SIDE OF THIS LINE
- SHOULD ROTATE EITHER MEMORY OR THE ACCUMULATOR, BUT THE ADDRESSING
- MODE TURNS OUT TO BE IMMEDIATE! nO PROBLEM. jUST READ THE OPERAND, LET
- IT BE andED WITH THE ACCUMULATOR AND FINALLY USE ACCUMULATOR
- ADDRESSING MODE FOR THE INSTRUCTIONS ABOVE THEM.
-
- religion_mode_on
- /* tHIS PART OF THE DOCUMENT IS NOT ACCURATE. yOU CAN
- READ IT AS A FAIRY TALE, BUT DO NOT COUNT ON IT WHEN
- PERFORMING YOUR OWN MEASUREMENTS. */
-
- tHE REST TWO INSTRUCTIONS ON THE SAME LINE, CALLED 'ane' AND 'lxa'
- ($8b AND $ab RESPECTIVELY) OFTEN GIVE QUITE UNPREDICTABLE RESULTS.
- hOWEVER, THE MOST USUAL OPERATION IS TO STORE ((a {$7c} #$EE) & x & #$NN)
- TO ACCUMULATOR. nOTE THAT THIS DOES NOT WORK RELIABLY IN A REAL 64!
- iN THE cOMMODORE 128 THE OPCODE $8b USES VALUES 8c, cc, ee, AND
- OCCASIONALLY 0c AND 8e FOR THE or INSTEAD OF ee,ef,fe AND ff USED IN
- THE c64. wITH A c128 RUNNING AT 2 mhZ #$ee IS ALWAYS USED. oPCODE $ab
- DOES NOT CAUSE THIS or TAKING PLACE ON 8502 WHILE 6510 ALWAYS PERFORMS
- IT. nOTE THAT THIS BEHAVIOUR DEPENDS ON PROCESSOR AND/OR VIDEO CHIP
- REVISION.
-
- lET'S TAKE A CLOSER LOOK AT $8b (6510).
-
- a <- x & d & (a {$7c} val)
-
- WHERE val COMES FROM THIS TABLE:
-
- x HIGH d HIGH d LOW val
- EVEN EVEN --- $ee (1)
- EVEN ODD --- $ee
- ODD EVEN --- $ee
- ODD ODD 0 $ee
- ODD ODD NOT 0 $fe (2)
-
- (1) iF THE BOTTOM 2 BITS OF a ARE BOTH 1, THEN THE lsb OF THE RESULT MAY
- BE 0. tHE VALUES OF x AND d ARE DIFFERENT EVERY TIME i RUN THE TEST.
- tHIS APPEARS TO BE VERY RARE.
- (2) val IS $fe MOST OF THE TIME. sOMETIMES IT IS $ee - IT SEEMS TO BE RANDOM,
- NOT RELATED TO ANY OF THE DATA. tHIS IS MUCH MORE COMMON THAN (1).
-
- iN DECIMAL MODE, val IS USUALLY $fe.
-
-
- tWO DIFFERENT FUNCTIONS HAVE BEEN DISCOVERED FOR lxa, OPCODE $ab. oNE
- IS a = x = ane (SEE ABOVE) AND THE OTHER, ENCOUNTERED WITH 6510 AND
- 8502, IS LESS COMPLICATED a = x = (a & #BYTE). hOWEVER, ACCORDING TO
- WHAT IS REPORTED, THE VERSION ALTERING ONLY THE LOWEST BITS OF EACH
- NYBBLE SEEMS TO BE MORE COMMON.
-
- wHAT HAPPENS, IS THAT $ab LOADS A VALUE INTO BOTH a AND x, andING THE
- LOW BIT OF EACH NYBBLE WITH THE CORRESPONDING BIT OF THE OLD
- a. hOWEVER, THERE ARE EXCEPTIONS. sOMETIMES THE LOW BIT IS CLEARED
- EVEN WHEN a CONTAINS A '1', AND SOMETIMES OTHER BITS ARE CLEARED. tHE
- EXCEPTIONS SEEM RANDOM (THEY CHANGE EVERY TIME i RUN THE TEST). oOPS -
- THAT WAS IN DECIMAL MODE. mUCH THE SAME WITH d=0.
-
- wHAT CAUSES THE RANDOMNESS? pROBABLY IT IS THAT IT IS MARGINAL LOGIC
- LEVELS - WHEN TOO MUCH WIRED-ANDING GOES ON, SOME OF THE SIGNALS GET
- VERY CLOSE TO THE THRESHOLD. pERHAPS WE'RE SEEING SOME OF THEM STEP
- OVER IT. tHE LOW BIT OF EACH NYBBLE IS SPECIAL, SINCE IT HAS TO COPE
- WITH CARRY DIFFERENTLY (REMEMBER DECIMAL MODE). wE NEVER SEE A '0'
- TURN INTO A '1'.
-
- sINCE THESE INSTRUCTIONS ARE UNPREDICTABLE, THEY SHOULD NOT BE USED.
-
- tHERE IS STILL VERY STRANGE INSTRUCTION LEFT, THE ONE NAMED sha/x/y,
- WHICH IS THE ONLY ONE WITH ONLY INDEXED ADDRESSING MODES. aCTUALLY,
- THE COMMANDS 'sha', 'shx' AND 'shy' ARE GENERATED BY THE INDEXING
- ALGORITHM.
-
- wHILE USING INDEXED ADDRESSING, EFFECTIVE ADDRESS FOR PAGE BOUNDARY
- CROSSING IS CALCULATED AS SOON AS POSSIBLE SO IT DOES NOT SLOW DOWN
- OPERATION. aS A RESULT, IN THE CASE OF sha/x/y, THE ADDRESS AND DATA
- ARE PROCESSED AT THE SAME TIME MAKING and BETWEEN THEM TO TAKE PLACE.
- tHUS, THE VALUE TO BE STORED BY sax, FOR EXAMPLE, IS IN FACT (a & x &
- (addr_hi + 1)). oN PAGE BOUNDARY CROSSING THE SAME VALUE IS COPIED
- ALSO TO HIGH BYTE OF THE EFFECTIVE ADDRESS.
-
- religion_mode_off
-
- rEGISTER SELECTION FOR LOAD AND STORE
-
- BIT1 BIT0 a x y
- 0 0 X
- 0 1 X
- 1 0 X
- 1 1 X X
-
- sO, a AND x ARE SELECTED BY BITS 1 AND 0 RESPECTIVELY, WHILE
- {$7e}(BIT1{$7c}BIT0) ENABLES y.
-
- iNDEXING IS DETERMINED BY BIT4, EVEN IN RELATIVE ADDRESSING MODE,
- WHICH IS ONE KIND OF INDEXING.
-
- lINES CONTAINING OPCODES XXX000X1 (01 AND 03) ARE TREATED AS ABSOLUTE
- AFTER THE EFFECTIVE ADDRESS HAS BEEN LOADED INTO cpu.
-
- zEROPAGE,Y AND aBSOLUTE,Y (CODES 10X1 X11X) ARE DISTINQUISHED BY BIT5.
-
-
- dECIMAL MODE IN nmos 6500 SERIES
-
- mOST SOURCES CLAIM THAT THE nmos 6500 SERIES SETS THE n, v AND z
- FLAGS UNPREDICTABLY WHEN PERFORMING ADDITION OR SUBTRACTION IN DECIMAL
- MODE. oF COURSE, THIS IS NOT TRUE. wHILE TESTING HOW THE FLAGS ARE
- SET, i ALSO WANTED TO SEE WHAT HAPPENS IF YOU USE ILLEGAL bcd VALUES.
-
- adc WORKS IN dECIMAL MODE IN A QUITE COMPLICATED WAY. iT IS AMAZING
- HOW IT CAN DO THAT ALL IN A SINGLE CYCLE. hERE'S A c CODE VERSION OF
- THE INSTRUCTION:
-
- UNSIGNED
- a, /* aCCUMULATOR */
- al, /* LOW NYBBLE OF ACCUMULATOR */
- ah, /* HIGH NYBBLE OF ACCUMULATOR */
-
- c, /* cARRY FLAG */
- z, /* zERO FLAG */
- v, /* OvERFLOW FLAG */
- n, /* nEGATIVE FLAG */
-
- S; /* VALUE TO BE ADDED TO aCCUMULATOR */
-
- al = (a & 15) + (S & 15) + c; /* cALCULATE THE LOWER NYBBLE. */
-
- ah = (a >> 4) + (S >> 4) + (al > 15); /* cALCULATE THE UPPER NYBBLE. */
-
- IF (al > 9) al += 6; /* bcd FIXUP FOR LOWER NYBBLE. */
-
- z = ((a + S + c) & 255 != 0); /* zERO FLAG IS SET JUST
- LIKE IN bINARY MODE. */
-
- /* nEGATIVE AND oVERFLOW FLAGS ARE SET WITH THE SAME LOGIC THAN IN
- bINARY MODE, BUT AFTER FIXING THE LOWER NYBBLE. */
-
- n = (ah & 8 != 0);
- v = ((ah << 4) ^ a) & 128 && !((a ^ S) & 128);
-
- IF (ah > 9) ah += 6; /* bcd FIXUP FOR UPPER NYBBLE. */
-
- /* cARRY IS THE ONLY FLAG SET AFTER FIXING THE RESULT. */
-
- c = (ah > 15);
- a = ((ah << 4) {$7c} (al & 15)) & 255;
-
-
- tHE c FLAG IS SET AS THE QUICHE EATERS EXPECT, BUT THE n AND v FLAGS
- ARE SET AFTER FIXING THE LOWER NYBBLE BUT BEFORE FIXING THE UPPER ONE.
- tHEY USE THE SAME LOGIC THAN BINARY MODE adc. tHE z FLAG IS SET BEFORE
- ANY bcd FIXUP, SO THE d FLAG DOES NOT HAVE ANY INFLUENCE ON IT.
-
- pROOF: tHE FOLLOWING TEST PROGRAM TESTS ALL 131072 adc COMBINATIONS IN
- dECIMAL MODE, AND ABORTS WITH brk IF ANYTHING BREAKS THIS THEORY.
- iF EVERYTHING GOES WELL, IT ENDS IN rts.
-
- BEGIN 600 DADC
- m 0@9",d'gl(h-#,ijc(u-js"*#0t*:hr-@ 'bi&* a/n$_$b@+)$kh(v1
- m*q@(i?pi#x7]i?li#v7]r0j0 fd%j"d/a?ve^rgp9?pi\ c $) ":0^jl @h
- ml ?)h) &""@x:5\x!?v%_0ah*3w@ ! ""8"hbd7[$ je^t7\, 28"4"h**7[
- m9?s0!)@) j@8n/be^v7\v a%_= g:(3]1?w0(.;[t(?f_-"#:$d8\ )88*d=
- 0&&4ka?ni &4la?ri.&s[ a%
-
- END
-
- aLL PROGRAMS IN THIS CHAPTER HAVE BEEN SUCCESSFULLY TESTED ON A vIC20
- AND A cOMMODORE 64 AND A cOMMODORE 128d IN c64 MODE. tHEY SHOULD RUN ON
- c16, +4 AND ON THE pet SERIES AS WELL. iF NOT, PLEASE REPORT THE PROBLEM
- TO mARKO m{$e4}KEL{$e4}. eACH TEST IN THIS CHAPTER SHOULD RUN IN LESS THAN A
- MINUTE AT 1 mhZ.
-
- sbc IS MUCH EASIER. jUST LIKE cmp, ITS FLAGS ARE NOT AFFECTED BY
- THE d FLAG.
-
- pROOF:
-
- BEGIN 600 DSBC-CMP-FLAGS
- m 0@9",d'gl(h-#,ijc(u-js"*#0t*:hr-@ 'b@ (3[a/rb xh8:66hl2n@
- m09$kh$r1*xii::bq*z!%d2n@4)$k^#bxi?oe_-@(:(7].+be^^7\"&a%_? !
- 5 .;[t./f_-#?ra"_8!@xcey<7%
-
- END
-
-
- tHE ONLY DIFFERENCE IN sbc'S OPERATION IN DECIMAL MODE FROM BINARY MODE
- IS THE RESULT-FIXUP:
-
- UNSIGNED
- a, /* aCCUMULATOR */
- al, /* LOW NYBBLE OF ACCUMULATOR */
- ah, /* HIGH NYBBLE OF ACCUMULATOR */
-
- c, /* cARRY FLAG */
- z, /* zERO FLAG */
- v, /* OvERFLOW FLAG */
- n, /* nEGATIVE FLAG */
-
- S; /* VALUE TO BE ADDED TO aCCUMULATOR */
-
- al = (a & 15) - (S & 15) - !c; /* cALCULATE THE LOWER NYBBLE. */
-
- IF (al & 16) al -= 6; /* bcd FIXUP FOR LOWER NYBBLE. */
-
- ah = (a >> 4) - (S >> 4) - (al & 16); /* cALCULATE THE UPPER NYBBLE. */
-
- IF (ah & 16) ah -= 6; /* bcd FIXUP FOR UPPER NYBBLE. */
-
- /* tHE FLAGS ARE SET JUST LIKE IN bINARY MODE. */
-
- c = (a - S - !c) & 256 != 0;
- z = (a - S - !c) & 255 != 0;
- v = ((a - S - !c) ^ S) & 128 && (a ^ S) & 128;
- n = (a - S - !c) & 128 != 0;
-
- a = ((ah << 4) {$7c} (al & 15)) & 255;
-
-
- aGAIN z FLAG IS SET BEFORE ANY bcd FIXUP. tHE n AND v FLAGS ARE SET
- AT ANY TIME BEFORE FIXING THE HIGH NYBBLE. tHE c FLAG MAY BE SET IN ANY
- PHASE.
-
- dECIMAL SUBTRACTION IS EASIER THAN DECIMAL ADDITION, AS YOU HAVE TO
- MAKE THE bcd FIXUP ONLY WHEN A NYBBLE OVERFLOWS. iN DECIMAL ADDITION,
- YOU HAD TO VERIFY IF THE NYBBLE WAS GREATER THAN 9. tHE PROCESSOR HAS
- AN INTERNAL "HALF CARRY" FLAG FOR THE LOWER NYBBLE, USED TO TRIGGER
- THE bcd FIXUP. wHEN CALCULATING WITH LEGAL bcd VALUES, THE LOWER NYBBLE
- CANNOT OVERFLOW AGAIN WHEN FIXING IT.
- sO, THE PROCESSOR DOES NOT HANDLE OVERFLOWS WHILE PERFORMING THE FIXUP.
- sIMILARLY, THE bcd FIXUP OCCURS IN THE HIGH NYBBLE ONLY IF THE VALUE
- OVERFLOWS, I.E. WHEN THE c FLAG WILL BE CLEARED.
-
- bECAUSE sbc'S FLAGS ARE NOT AFFECTED BY THE dECIMAL MODE FLAG, YOU
- COULD GUESS THAT cmp USES THE sbc LOGIC, ONLY SETTING THE c FLAG
- FIRST. bUT THE sbx INSTRUCTION SHOWS THAT cmp ALSO TEMPORARILY CLEARS
- THE d FLAG, ALTHOUGH IT IS TOTALLY UNNECESSARY.
-
- tHE FOLLOWING PROGRAM, WHICH TESTS sbc'S RESULT AND FLAGS,
- CONTAINS THE 6502 VERSION OF THE PSEUDO CODE EXAMPLE ABOVE.
-
- BEGIN 600 DSBC
- m 0@9",d'gl(h-#,ijc(u-js"*#0t*:hr-@ 'bi&* a/n$_$b@+)$kh':1
- m*s@(i?pi#x7]i?li#^7]l /i!1@i#zbe_"gpa?ve^rgp"#ce_2gpl ki7rbp
- m#nd/.+ )*+ &z0^p ne?a/t%_87]*+be^^7\"&bh.+cxi?oe_-@(1?w0fvb$
- 8_47]t)3f^]">yos0ffa)&- $j3c0b%a@
-
- END
-
- oBVIOUSLY THE UNDOCUMENTED INSTRUCTIONS rra (ror+adc) AND isb
- (inc+sbc) HAVE INHERITED ALSO THE DECIMAL OPERATION FROM THE OFFICIAL
- INSTRUCTIONS adc AND sbc. tHE PROGRAM DRORADC PROVES THIS STATEMENT
- FOR ror, AND THE DINCSBC TEST PROVES THIS FOR isb. fINALLY,
- DINCSBC-DECCMP PROVES THAT isb'S AND dcp'S (dec+cmp) FLAGS ARE NOT
- AFFECTED BY THE d FLAG.
-
- BEGIN 644 DRORADC
- m{$60}0@9",d'gl(h-#,ijc(u-js"*#0t*:hr-@{$60}{$60}{$60}'bi&*{$60}{$60}a/n$_$b@+)$kh(v1
- m*s@(i?pi#x7]i?li#v7]r0j0{$60}fd%j"d/a?ve^rgp9?pi\{$60}c{$60}$){$60}":0^jl{$60}@h
- ml{$60}?)h){$60}&""@x:5\x!?v%_0ah*3w@{$60}!{$60}""8"hbd7[${$60}je^t7\,{$60}28"4"h**7[
- m9?s0!)@){$60}j@xn/be^r;\9_s8"$7]t"=ha/u%_={$60}@yoo0a>;\t(%h21cp{$60}ea@
- 2j1t892n%^zd{$60}92r%_*dx;/l{$60}
- {$60}
- END
-
- BEGIN 644 DINCSBC
- m{$60}0@9",d'gl(h-#,ijc(u-js"*#0t*:hr-@{$60}{$60}{$60}'bi&*{$60}{$60}a/n$_$b@+)$kh':1
- m*s@(i?pi#x7]i?li#^7]l{$60}/i!1@i#zbe_"gpa?ve^rgp"#ce_2gpl{$60}ki7rbp
- m#nd/.+{$60})*+{$60}&z0^p{$60}ne?a/t%_87]*+be^^7\"&bh.+cxi?o&_.?\v{$60}a%_="9
- ::(3]1?w0dn;[t)sf_-"8:$d8t{$60}2i.-"&6\
- {$60}
- END
-
- BEGIN 644 DINCSBC-DECCMP
- m{$60}0@9",d'gl(h-#,ijc(u-js"*#0t*:hr-@{$60}{$60}{$60}'b@{$60}(3[a/rb{$60}xh8:7>hl2n@
- m3y$kh%r1*xii>zbq*z!3d2n@8)$kbfe_j+$kh%61*z!bd2ox.+be^^;\q_s8
- l"&b%_3bxi?of_,?\"&a%_?{$60}!{$60}.;[t-_f_-#;ra"m8!@xcfyl;&q\?gyp#8
- {$60}
- END
-
-
-
- 6510 FEATURES
-
- O php ALWAYS PUSHES THE bREAK (b) FLAG AS A {$60}1' TO THE STACK.
- jUKKA tAPANIM{$e4}KI CLAIMED IN c=LEHTI ISSUE 3/89, ON PAGE 27 THAT THE
- PROCESSOR MAKES A LOGICAL or BETWEEN THE STATUS REGISTER'S BIT 4
- AND THE BIT 8 OF THE STACK POINTER REGISTER (WHICH IS ALWAYS 1).
- hE DID NOT GIVE ANY REASONS FOR THIS ARGUMENT, AND HAS REFUSED TO CLARIFY
- IT AFTERWARDS. wELL, THIS WAS NOT THE ONLY ERROR IN HIS ARTICLE...
-
- O iNDIRECT ADDRESSING MODES DO NOT HANDLE PAGE BOUNDARY CROSSING AT ALL.
- wHEN THE PARAMETER'S LOW BYTE IS $ff, THE EFFECTIVE ADDRESS WRAPS
- AROUND AND THE cpu FETCHES HIGH BYTE FROM $XX00 INSTEAD OF $XX00+$0100.
- e.G. jmp ($01ff) FETCHES pcl FROM $01ff AND pch FROM $0100,
- AND lda ($ff),y FETCHES THE BASE ADDRESS FROM $ff AND $00.
-
- O iNDEXED ZERO PAGE ADDRESSING MODES NEVER FIX THE PAGE ADDRESS ON
- CROSSING THE ZERO PAGE BOUNDARY.
- e.G. ldx #$01 : lda ($ff,x) LOADS THE EFFECTIVE ADDRESS FROM $00 AND $01.
-
- O tHE PROCESSOR ALWAYS FETCHES THE BYTE FOLLOWING A RELATIVE BRANCH
- INSTRUCTION. iF THE BRANCH IS TAKEN, THE PROCESSOR READS THEN THE
- OPCODE FROM THE DESTINATION ADDRESS. iF PAGE BOUNDARY IS CROSSED, IT
- FIRST READS A BYTE FROM THE OLD PAGE FROM A LOCATION THAT IS BIGGER
- OR SMALLER THAN THE CORRECT ADDRESS BY ONE PAGE.
-
- O iF YOU CROSS A PAGE BOUNDARY IN ANY OTHER INDEXED MODE,
- THE PROCESSOR READS AN INCORRECT LOCATION FIRST, A LOCATION THAT IS
- SMALLER BY ONE PAGE.
-
- O rEAD-mODIFY-wRITE INSTRUCTIONS WRITE UNMODIFIED DATA, THEN MODIFIED
- (SO inc EFFECTIVELY DOES ldx LOC;stx LOC;inx;stx LOC)
-
- O -rdy IS IGNORED DURING WRITES
- (tHIS IS WHY YOU MUST WAIT 3 CYCLES BEFORE DOING ANY dma --
- THE MAXIMUM NUMBER OF CONSECUTIVE WRITES IS 3, WHICH OCCURS
- DURING INTERRUPTS EXCEPT -reset.)
-
- O sOME UNDEFINED OPCODES MAY GIVE REALLY UNPREDICTABLE RESULTS.
-
- O aLL REGISTERS EXCEPT THE pROGRAM cOUNTER REMAIN UNMODIFIED AFTER -reset.
- (tHIS IS WHY YOU MUST PRESET d AND i FLAGS IN THE reset HANDLER.)
-
-
- dIFFERENT cpu TYPES
-
- tHE rOCKWELL DATA BOOKLET 29651n52 (TECHNICAL INFORMATION ABOUT r65c00
- MICROPROCESSORS, DATED oCTOBER 1984), LISTS THE FOLLOWING DIFFERENCES BETWEEN
- nmos r6502 MICROPROCESSOR AND cmos r65c00 FAMILY:
-
- 1. iNDEXED ADDRESSING ACROSS PAGE BOUNDARY.
- nmos: eXTRA READ OF INVALID ADDRESS.
- cmos: eXTRA READ OF LAST INSTRUCTION BYTE.
-
- 2. eXECUTION OF INVALID OP CODES.
- nmos: sOME TERMINATE ONLY BY RESET. rESULTS ARE UNDEFINED.
- cmos: aLL ARE nopS (RESERVED FOR FUTURE USE).
-
- 3. jUMP INDIRECT, OPERAND = xxff.
- nmos: pAGE ADDRESS DOES NOT INCREMENT.
- cmos: pAGE ADDRESS INCREMENTS AND ADDS ONE ADDITIONAL CYCLE.
-
- 4. rEAD/MODIFY/WRITE INSTRUCTIONS AT EFFECTIVE ADDRESS.
- nmos: oNE READ AND TWO WRITE CYCLES.
- cmos: tWO READ AND ONE WRITE CYCLE.
-
- 5. dECIMAL FLAG.
- nmos: iNDETERMINATE AFTER RESET.
- cmos: iNITIALIZED TO BINARY MODE (d=0) AFTER RESET AND INTERRUPTS.
-
- 6. fLAGS AFTER DECIMAL OPERATION.
- nmos: iNVALID n, v AND z FLAGS.
- cmos: vALID FLAG ADDS ONE ADDITIONAL CYCLE.
-
- 7. iNTERRUPT AFTER FETCH OF brk INSTRUCTION.
- nmos: iNTERRUPT VECTOR IS LOADED, brk VECTOR IS IGNORED.
- cmos: brk IS EXECUTED, THEN INTERRUPT IS EXECUTED.
-
-
-
- 6510 iNSTRUCTION tIMING
-
- tHE nmos 6500 SERIES PROCESSORS ALWAYS PERFORM AT LEAST TWO READS
- FOR EACH INSTRUCTION. iN ADDITION TO THE OPERATION CODE (OPCODE), THEY
- FETCH THE NEXT BYTE. tHIS IS QUITE EFFICIENT, AS MOST INSTRUCTIONS ARE
- TWO OR THREE BYTES LONG.
-
- tHE PROCESSORS ALSO USE A SORT OF PIPELINING. iF AN INSTRUCTION DOES
- NOT STORE DATA IN MEMORY ON ITS LAST CYCLE, THE PROCESSOR CAN FETCH
- THE OPCODE OF THE NEXT INSTRUCTION WHILE EXECUTING THE LAST CYCLE. fOR
- INSTANCE, THE INSTRUCTION eor #$ff TRULY TAKES THREE CYCLES. oN THE
- FIRST CYCLE, THE OPCODE $49 WILL BE FETCHED. dURING THE SECOND CYCLE
- THE PROCESSOR DECODES THE OPCODE AND FETCHES THE PARAMETER #$ff. oN
- THE THIRD CYCLE, THE PROCESSOR WILL PERFORM THE OPERATION AND STORE
- THE RESULT TO ACCUMULATOR, BUT SIMULTANEOUSLY IT FETCHES THE OPCODE
- FOR THE NEXT INSTRUCTION. tHIS IS WHY THE INSTRUCTION EFFECTIVELY
- TAKES ONLY TWO CYCLES.
-
- tHE FOLLOWING TABLES SHOW WHAT HAPPENS ON THE BUS WHILE EXECUTING
- DIFFERENT KINDS OF INSTRUCTIONS.
-
- iNTERRUPTS
-
- nmi AND irq BOTH TAKE 7 CYCLES. tHEIR TIMING DIAGRAM IS MUCH LIKE
- brk'S (SEE BELOW). irq WILL BE EXECUTED ONLY WHEN THE i FLAG IS
- CLEAR. irq AND brk BOTH SET THE i FLAG, WHEREAS THE nmi DOES NOT
- AFFECT ITS STATE.
-
- tHE PROCESSOR WILL USUALLY WAIT FOR THE CURRENT INSTRUCTION TO
- COMPLETE BEFORE EXECUTING THE INTERRUPT SEQUENCE. tO PROCESS THE
- INTERRUPT BEFORE THE NEXT INSTRUCTION, THE INTERRUPT MUST OCCUR
- BEFORE THE LAST CYCLE OF THE CURRENT INSTRUCTION.
-
- tHERE IS ONE EXCEPTION TO THIS RULE: THE brk INSTRUCTION. iF A
- HARDWARE INTERRUPT (nmi OR irq) OCCURS BEFORE THE FOURTH (FLAGS
- SAVING) CYCLE OF brk, THE brk INSTRUCTION WILL BE SKIPPED, AND
- THE PROCESSOR WILL JUMP TO THE HARDWARE INTERRUPT VECTOR. tHIS
- SEQUENCE WILL ALWAYS TAKE 7 CYCLES.
-
- yOU DO NOT COMPLETELY LOSE THE brk INTERRUPT, THE b FLAG WILL BE
- SET IN THE PUSHED STATUS REGISTER IF A brk INSTRUCTION GETS
- INTERRUPTED. wHEN brk AND irq OCCUR AT THE SAME TIME, THIS DOES
- NOT CAUSE ANY PROBLEMS, AS YOUR PROGRAM WILL CONSIDER IT AS A
- brk, AND THE irq WOULD OCCUR AGAIN AFTER THE PROCESSOR RETURNED
- FROM YOUR brk ROUTINE, UNLESS YOU CLEARED THE INTERRUPT SOURCE IN
- YOUR brk HANDLER. bUT THE SIMULTANEOUS OCCURRENCE OF nmi AND brk
- IS FAR MORE FATAL. iF YOU DO NOT CHECK THE b FLAG IN THE nmi
- ROUTINE AND SUBTRACT TWO FROM THE RETURN ADDRESS WHEN NEEDED, THE
- brk INSTRUCTION WILL BE SKIPPED.
-
- iF THE nmi AND irq INTERRUPTS OVERLAP EACH OTHER (ONE INTERRUPT
- OCCURS BEFORE FETCHING THE INTERRUPT VECTOR FOR THE OTHER
- INTERRUPT), THE PROCESSOR WILL MOST PROBABLY JUMP TO THE nmi
- VECTOR IN EVERY CASE, AND THEN JUMP TO THE irq VECTOR AFTER
- PROCESSING THE FIRST INSTRUCTION OF THE nmi HANDLER. tHIS HAS NOT
- BEEN MEASURED YET, BUT THE irq IS VERY SIMILAR TO brk, AND MANY
- SOURCES STATE THAT THE nmi HAS HIGHER PRIORITY THAN irq. hOWEVER,
- IT MIGHT BE THAT THE PROCESSOR TAKES THE INTERRUPT THAT COMES
- LATER, I.E. YOU COULD LOSE AN nmi INTERRUPT IF AN irq OCCURRED IN
- FOUR CYCLES AFTER IT.
-
- aFTER FINISHING THE INTERRUPT SEQUENCE, THE PROCESSOR WILL START
- TO EXECUTE THE FIRST INSTRUCTION OF THE INTERRUPT ROUTINE. tHIS
- PROVES THAT THE PROCESSOR USES A SORT OF PIPELINING: IT FINISHES
- THE CURRENT INSTRUCTION (OR INTERRUPT SEQUENCE) WHILE READING THE
- OPCODE OF THE NEXT INSTRUCTION.
-
- reset DOES NOT PUSH PROGRAM COUNTER ON STACK, AND IT LASTS
- PROBABLY 6 CYCLES AFTER DEACTIVATING THE SIGNAL. lIKE nmi, reset
- PRESERVES ALL REGISTERS EXCEPT pc.
-
-
- iNSTRUCTIONS ACCESSING THE STACK
-
- brk
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- -----------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY),
- INCREMENT pc
- 3 $0100,s w PUSH pch ON STACK, DECREMENT s
- 4 $0100,s w PUSH pcl ON STACK, DECREMENT s
- 5 $0100,s w PUSH p ON STACK (WITH b FLAG SET), DECREMENT s
- 6 $fffe r FETCH pcl
- 7 $ffff r FETCH pch
-
-
- rti
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- -----------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY)
- 3 $0100,s r INCREMENT s
- 4 $0100,s r PULL p FROM STACK, INCREMENT s
- 5 $0100,s r PULL pcl FROM STACK, INCREMENT s
- 6 $0100,s r PULL pch FROM STACK
-
-
- rts
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- -----------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY)
- 3 $0100,s r INCREMENT s
- 4 $0100,s r PULL pcl FROM STACK, INCREMENT s
- 5 $0100,s r PULL pch FROM STACK
- 6 pc r INCREMENT pc
-
-
- pha, php
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- -----------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY)
- 3 $0100,s w PUSH REGISTER ON STACK, DECREMENT s
-
-
- pla, plp
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- -----------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY)
- 3 $0100,s r INCREMENT s
- 4 $0100,s r PULL REGISTER FROM STACK
-
-
- jsr
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- -------------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH LOW ADDRESS BYTE, INCREMENT pc
- 3 $0100,s r INTERNAL OPERATION (PREDECREMENT s?)
- 4 $0100,s w PUSH pch ON STACK, DECREMENT s
- 5 $0100,s w PUSH pcl ON STACK, DECREMENT s
- 6 pc r COPY LOW ADDRESS BYTE TO pcl, FETCH HIGH ADDRESS
- BYTE TO pch
-
-
-
- aCCUMULATOR OR IMPLIED ADDRESSING
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- -----------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r READ NEXT INSTRUCTION BYTE (AND THROW IT AWAY)
-
-
- iMMEDIATE ADDRESSING
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH VALUE, INCREMENT pc
-
-
- aBSOLUTE ADDRESSING
-
- jmp
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- -------------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH LOW ADDRESS BYTE, INCREMENT pc
- 3 pc r COPY LOW ADDRESS BYTE TO pcl, FETCH HIGH ADDRESS
- BYTE TO pch
-
-
- rEAD INSTRUCTIONS (lda, ldx, ldy, eor, and, ora, adc, sbc, cmp, bit,
- lax, nop)
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH LOW BYTE OF ADDRESS, INCREMENT pc
- 3 pc r FETCH HIGH BYTE OF ADDRESS, INCREMENT pc
- 4 ADDRESS r READ FROM EFFECTIVE ADDRESS
-
-
- rEAD-mODIFY-wRITE INSTRUCTIONS (asl, lsr, rol, ror, inc, dec,
- slo, sre, rla, rra, isb, dcp)
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH LOW BYTE OF ADDRESS, INCREMENT pc
- 3 pc r FETCH HIGH BYTE OF ADDRESS, INCREMENT pc
- 4 ADDRESS r READ FROM EFFECTIVE ADDRESS
- 5 ADDRESS w WRITE THE VALUE BACK TO EFFECTIVE ADDRESS,
- AND DO THE OPERATION ON IT
- 6 ADDRESS w WRITE THE NEW VALUE TO EFFECTIVE ADDRESS
-
-
- wRITE INSTRUCTIONS (sta, stx, sty, sax)
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH LOW BYTE OF ADDRESS, INCREMENT pc
- 3 pc r FETCH HIGH BYTE OF ADDRESS, INCREMENT pc
- 4 ADDRESS w WRITE REGISTER TO EFFECTIVE ADDRESS
-
-
- zERO PAGE ADDRESSING
-
- rEAD INSTRUCTIONS (lda, ldx, ldy, eor, and, ora, adc, sbc, cmp, bit,
- lax, nop)
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH ADDRESS, INCREMENT pc
- 3 ADDRESS r READ FROM EFFECTIVE ADDRESS
-
-
- rEAD-mODIFY-wRITE INSTRUCTIONS (asl, lsr, rol, ror, inc, dec,
- slo, sre, rla, rra, isb, dcp)
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH ADDRESS, INCREMENT pc
- 3 ADDRESS r READ FROM EFFECTIVE ADDRESS
- 4 ADDRESS w WRITE THE VALUE BACK TO EFFECTIVE ADDRESS,
- AND DO THE OPERATION ON IT
- 5 ADDRESS w WRITE THE NEW VALUE TO EFFECTIVE ADDRESS
-
-
- wRITE INSTRUCTIONS (sta, stx, sty, sax)
-
- # ADDRESS r/w DESCRIPTION
- --- ------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH ADDRESS, INCREMENT pc
- 3 ADDRESS w WRITE REGISTER TO EFFECTIVE ADDRESS
-
- zERO PAGE INDEXED ADDRESSING
-
- rEAD INSTRUCTIONS (lda, ldx, ldy, eor, and, ora, adc, sbc, cmp, bit,
- lax, nop)
-
- # ADDRESS r/w DESCRIPTION
- --- --------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH ADDRESS, INCREMENT pc
- 3 ADDRESS r READ FROM ADDRESS, ADD INDEX REGISTER TO IT
- 4 ADDRESS+i* r READ FROM EFFECTIVE ADDRESS
-
- nOTES: i DENOTES EITHER INDEX REGISTER (x OR y).
-
- * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS IS ALWAYS ZERO,
- I.E. PAGE BOUNDARY CROSSINGS ARE NOT HANDLED.
-
-
- rEAD-mODIFY-wRITE INSTRUCTIONS (asl, lsr, rol, ror, inc, dec,
- slo, sre, rla, rra, isb, dcp)
-
- # ADDRESS r/w DESCRIPTION
- --- --------- --- ---------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH ADDRESS, INCREMENT pc
- 3 ADDRESS r READ FROM ADDRESS, ADD INDEX REGISTER x TO IT
- 4 ADDRESS+x* r READ FROM EFFECTIVE ADDRESS
- 5 ADDRESS+x* w WRITE THE VALUE BACK TO EFFECTIVE ADDRESS,
- AND DO THE OPERATION ON IT
- 6 ADDRESS+x* w WRITE THE NEW VALUE TO EFFECTIVE ADDRESS
-
- nOTE: * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS IS ALWAYS ZERO,
- I.E. PAGE BOUNDARY CROSSINGS ARE NOT HANDLED.
-
-
- wRITE INSTRUCTIONS (sta, stx, sty, sax)
-
- # ADDRESS r/w DESCRIPTION
- --- --------- --- -------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH ADDRESS, INCREMENT pc
- 3 ADDRESS r READ FROM ADDRESS, ADD INDEX REGISTER TO IT
- 4 ADDRESS+i* w WRITE TO EFFECTIVE ADDRESS
-
- nOTES: i DENOTES EITHER INDEX REGISTER (x OR y).
-
- * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS IS ALWAYS ZERO,
- I.E. PAGE BOUNDARY CROSSINGS ARE NOT HANDLED.
-
-
- aBSOLUTE INDEXED ADDRESSING
-
- rEAD INSTRUCTIONS (lda, ldx, ldy, eor, and, ora, adc, sbc, cmp, bit,
- lax, lae, shs, nop)
-
- # ADDRESS r/w DESCRIPTION
- --- --------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH LOW BYTE OF ADDRESS, INCREMENT pc
- 3 pc r FETCH HIGH BYTE OF ADDRESS,
- ADD INDEX REGISTER TO LOW ADDRESS BYTE,
- INCREMENT pc
- 4 ADDRESS+i* r READ FROM EFFECTIVE ADDRESS,
- FIX THE HIGH BYTE OF EFFECTIVE ADDRESS
- 5+ ADDRESS+i r RE-READ FROM EFFECTIVE ADDRESS
-
- nOTES: i DENOTES EITHER INDEX REGISTER (x OR y).
-
- * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS MAY BE INVALID
- AT THIS TIME, I.E. IT MAY BE SMALLER BY $100.
-
- + tHIS CYCLE WILL BE EXECUTED ONLY IF THE EFFECTIVE ADDRESS
- WAS INVALID DURING CYCLE #4, I.E. PAGE BOUNDARY WAS CROSSED.
-
-
- rEAD-mODIFY-wRITE INSTRUCTIONS (asl, lsr, rol, ror, inc, dec,
- slo, sre, rla, rra, isb, dcp)
-
- # ADDRESS r/w DESCRIPTION
- --- --------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH LOW BYTE OF ADDRESS, INCREMENT pc
- 3 pc r FETCH HIGH BYTE OF ADDRESS,
- ADD INDEX REGISTER x TO LOW ADDRESS BYTE,
- INCREMENT pc
- 4 ADDRESS+x* r READ FROM EFFECTIVE ADDRESS,
- FIX THE HIGH BYTE OF EFFECTIVE ADDRESS
- 5 ADDRESS+x r RE-READ FROM EFFECTIVE ADDRESS
- 6 ADDRESS+x w WRITE THE VALUE BACK TO EFFECTIVE ADDRESS,
- AND DO THE OPERATION ON IT
- 7 ADDRESS+x w WRITE THE NEW VALUE TO EFFECTIVE ADDRESS
-
- nOTES: * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS MAY BE INVALID
- AT THIS TIME, I.E. IT MAY BE SMALLER BY $100.
-
-
- wRITE INSTRUCTIONS (sta, stx, sty, sha, shx, shy)
-
- # ADDRESS r/w DESCRIPTION
- --- --------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH LOW BYTE OF ADDRESS, INCREMENT pc
- 3 pc r FETCH HIGH BYTE OF ADDRESS,
- ADD INDEX REGISTER TO LOW ADDRESS BYTE,
- INCREMENT pc
- 4 ADDRESS+i* r READ FROM EFFECTIVE ADDRESS,
- FIX THE HIGH BYTE OF EFFECTIVE ADDRESS
- 5 ADDRESS+i w WRITE TO EFFECTIVE ADDRESS
-
- nOTES: i DENOTES EITHER INDEX REGISTER (x OR y).
-
- * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS MAY BE INVALID
- AT THIS TIME, I.E. IT MAY BE SMALLER BY $100. bECAUSE
- THE PROCESSOR CANNOT UNDO A WRITE TO AN INVALID
- ADDRESS, IT ALWAYS READS FROM THE ADDRESS FIRST.
-
-
- rELATIVE ADDRESSING (bcc, bcs, bne, beq, bpl, bmi, bvc, bvs)
-
- # ADDRESS r/w DESCRIPTION
- --- --------- --- ---------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH OPERAND, INCREMENT pc
- 3 pc r fETCH OPCODE OF NEXT INSTRUCTION,
- iF BRANCH IS TAKEN, ADD OPERAND TO pcl.
- oTHERWISE INCREMENT pc.
- 4+ pc* r fETCH OPCODE OF NEXT INSTRUCTION.
- fIX pch. iF IT DID NOT CHANGE, INCREMENT pc.
- 5! pc r fETCH OPCODE OF NEXT INSTRUCTION,
- INCREMENT pc.
-
- nOTES: tHE OPCODE FETCH OF THE NEXT INSTRUCTION IS INCLUDED TO
- THIS DIAGRAM FOR ILLUSTRATION PURPOSES. wHEN DETERMINING
- REAL EXECUTION TIMES, REMEMBER TO SUBTRACT THE LAST
- CYCLE.
-
- * tHE HIGH BYTE OF pROGRAM cOUNTER (pch) MAY BE INVALID
- AT THIS TIME, I.E. IT MAY BE SMALLER OR BIGGER BY $100.
-
- + iF BRANCH IS TAKEN, THIS CYCLE WILL BE EXECUTED.
-
- ! iF BRANCH OCCURS TO DIFFERENT PAGE, THIS CYCLE WILL BE
- EXECUTED.
-
-
- iNDEXED INDIRECT ADDRESSING
-
- rEAD INSTRUCTIONS (lda, ora, eor, and, adc, cmp, sbc, lax)
-
- # ADDRESS r/w DESCRIPTION
- --- ----------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH POINTER ADDRESS, INCREMENT pc
- 3 POINTER r READ FROM THE ADDRESS, ADD x TO IT
- 4 POINTER+x r FETCH EFFECTIVE ADDRESS LOW
- 5 POINTER+x+1 r FETCH EFFECTIVE ADDRESS HIGH
- 6 ADDRESS r READ FROM EFFECTIVE ADDRESS
-
- nOTE: tHE EFFECTIVE ADDRESS IS ALWAYS FETCHED FROM ZERO PAGE,
- I.E. THE ZERO PAGE BOUNDARY CROSSING IS NOT HANDLED.
-
- rEAD-mODIFY-wRITE INSTRUCTIONS (slo, sre, rla, rra, isb, dcp)
-
- # ADDRESS r/w DESCRIPTION
- --- ----------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH POINTER ADDRESS, INCREMENT pc
- 3 POINTER r READ FROM THE ADDRESS, ADD x TO IT
- 4 POINTER+x r FETCH EFFECTIVE ADDRESS LOW
- 5 POINTER+x+1 r FETCH EFFECTIVE ADDRESS HIGH
- 6 ADDRESS r READ FROM EFFECTIVE ADDRESS
- 7 ADDRESS w WRITE THE VALUE BACK TO EFFECTIVE ADDRESS,
- AND DO THE OPERATION ON IT
- 8 ADDRESS w WRITE THE NEW VALUE TO EFFECTIVE ADDRESS
-
- nOTE: tHE EFFECTIVE ADDRESS IS ALWAYS FETCHED FROM ZERO PAGE,
- I.E. THE ZERO PAGE BOUNDARY CROSSING IS NOT HANDLED.
-
- wRITE INSTRUCTIONS (sta, sax)
-
- # ADDRESS r/w DESCRIPTION
- --- ----------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH POINTER ADDRESS, INCREMENT pc
- 3 POINTER r READ FROM THE ADDRESS, ADD x TO IT
- 4 POINTER+x r FETCH EFFECTIVE ADDRESS LOW
- 5 POINTER+x+1 r FETCH EFFECTIVE ADDRESS HIGH
- 6 ADDRESS w WRITE TO EFFECTIVE ADDRESS
-
- nOTE: tHE EFFECTIVE ADDRESS IS ALWAYS FETCHED FROM ZERO PAGE,
- I.E. THE ZERO PAGE BOUNDARY CROSSING IS NOT HANDLED.
-
- iNDIRECT INDEXED ADDRESSING
-
- rEAD INSTRUCTIONS (lda, eor, and, ora, adc, sbc, cmp)
-
- # ADDRESS r/w DESCRIPTION
- --- ----------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH POINTER ADDRESS, INCREMENT pc
- 3 POINTER r FETCH EFFECTIVE ADDRESS LOW
- 4 POINTER+1 r FETCH EFFECTIVE ADDRESS HIGH,
- ADD y TO LOW BYTE OF EFFECTIVE ADDRESS
- 5 ADDRESS+y* r READ FROM EFFECTIVE ADDRESS,
- FIX HIGH BYTE OF EFFECTIVE ADDRESS
- 6+ ADDRESS+y r READ FROM EFFECTIVE ADDRESS
-
- nOTES: tHE EFFECTIVE ADDRESS IS ALWAYS FETCHED FROM ZERO PAGE,
- I.E. THE ZERO PAGE BOUNDARY CROSSING IS NOT HANDLED.
-
- * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS MAY BE INVALID
- AT THIS TIME, I.E. IT MAY BE SMALLER BY $100.
-
- + tHIS CYCLE WILL BE EXECUTED ONLY IF THE EFFECTIVE ADDRESS
- WAS INVALID DURING CYCLE #5, I.E. PAGE BOUNDARY WAS CROSSED.
-
-
- rEAD-mODIFY-wRITE INSTRUCTIONS (slo, sre, rla, rra, isb, dcp)
-
- # ADDRESS r/w DESCRIPTION
- --- ----------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH POINTER ADDRESS, INCREMENT pc
- 3 POINTER r FETCH EFFECTIVE ADDRESS LOW
- 4 POINTER+1 r FETCH EFFECTIVE ADDRESS HIGH,
- ADD y TO LOW BYTE OF EFFECTIVE ADDRESS
- 5 ADDRESS+y* r READ FROM EFFECTIVE ADDRESS,
- FIX HIGH BYTE OF EFFECTIVE ADDRESS
- 6 ADDRESS+y r READ FROM EFFECTIVE ADDRESS
- 7 ADDRESS+y w WRITE THE VALUE BACK TO EFFECTIVE ADDRESS,
- AND DO THE OPERATION ON IT
- 8 ADDRESS+y w WRITE THE NEW VALUE TO EFFECTIVE ADDRESS
-
- nOTES: tHE EFFECTIVE ADDRESS IS ALWAYS FETCHED FROM ZERO PAGE,
- I.E. THE ZERO PAGE BOUNDARY CROSSING IS NOT HANDLED.
-
- * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS MAY BE INVALID
- AT THIS TIME, I.E. IT MAY BE SMALLER BY $100.
-
-
- wRITE INSTRUCTIONS (sta, sha)
-
- # ADDRESS r/w DESCRIPTION
- --- ----------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH POINTER ADDRESS, INCREMENT pc
- 3 POINTER r FETCH EFFECTIVE ADDRESS LOW
- 4 POINTER+1 r FETCH EFFECTIVE ADDRESS HIGH,
- ADD y TO LOW BYTE OF EFFECTIVE ADDRESS
- 5 ADDRESS+y* r READ FROM EFFECTIVE ADDRESS,
- FIX HIGH BYTE OF EFFECTIVE ADDRESS
- 6 ADDRESS+y w WRITE TO EFFECTIVE ADDRESS
-
- nOTES: tHE EFFECTIVE ADDRESS IS ALWAYS FETCHED FROM ZERO PAGE,
- I.E. THE ZERO PAGE BOUNDARY CROSSING IS NOT HANDLED.
-
- * tHE HIGH BYTE OF THE EFFECTIVE ADDRESS MAY BE INVALID
- AT THIS TIME, I.E. IT MAY BE SMALLER BY $100.
-
-
- aBSOLUTE INDIRECT ADDRESSING (jmp)
-
- # ADDRESS r/w DESCRIPTION
- --- --------- --- ------------------------------------------
- 1 pc r FETCH OPCODE, INCREMENT pc
- 2 pc r FETCH POINTER ADDRESS LOW, INCREMENT pc
- 3 pc r FETCH POINTER ADDRESS HIGH, INCREMENT pc
- 4 POINTER r FETCH LOW ADDRESS TO LATCH
- 5 POINTER+1* r FETCH pch, COPY LATCH TO pcl
-
- nOTE: * tHE pch WILL ALWAYS BE FETCHED FROM THE SAME PAGE
- THAN pcl, I.E. PAGE BOUNDARY CROSSING IS NOT HANDLED.
-
-
-
- hOW rEAL pROGRAMMERS aCKNOWLEDGE iNTERRUPTS
-
- wITH rmw INSTRUCTIONS:
-
- ; BEGINNING OF COMBINED RASTER/TIMER INTERRUPT ROUTINE
- lsr $d019 ; CLEAR vic INTERRUPTS, READ RASTER INTERRUPT FLAG TO c
- bcs RASTER ; JUMP IF vic CAUSED AN INTERRUPT
- ... ; TIMER INTERRUPT ROUTINE
-
- oPERATIONAL DIAGRAM OF lsr $d019:
-
- # DATA ADDRESS r/w
- --- ---- ------- --- ---------------------------------
- 1 4e pc r FETCH OPCODE
- 2 19 pc+1 r FETCH ADDRESS LOW
- 3 d0 pc+2 r FETCH ADDRESS HIGH
- 4 XX $d019 r READ MEMORY
- 5 XX $d019 w WRITE THE VALUE BACK, ROTATE RIGHT
- 6 XX/2 $d019 w WRITE THE NEW VALUE BACK
-
- tHE 5TH CYCLE ACKNOWLEDGES THE INTERRUPT BY WRITING THE SAME
- VALUE BACK. iF ONLY RASTER INTERRUPTS ARE USED, THE 6TH CYCLE
- HAS NO EFFECT ON THE vic. (iT MIGHT ACKNOWLEDGE ALSO SOME
- OTHER INTERRUPTS.)
-
-
-
- wITH INDEXED ADDRESSING:
-
- ; ACKNOWLEDGE INTERRUPTS TO BOTH ciaS
- ldx #$10
- lda $dcfd,x
-
- oPERATIONAL DIAGRAM OF lda $dcfd,x:
-
- # DATA ADDRESS r/w DESCRIPTION
- --- ---- ------- --- ---------------------------------
- 1 bd pc r FETCH OPCODE
- 2 fd pc+1 r FETCH ADDRESS LOW
- 3 dc pc+2 r FETCH ADDRESS HIGH, ADD x TO ADDRESS LOW
- 4 XX $dc0d r READ FROM ADDRESS, FIX HIGH BYTE OF ADDRESS
- 5 YY $dd0d r READ FROM RIGHT ADDRESS
-
-
- ; ACKNOWLEDGE INTERRUPTS TO cia 2
- ldx #$10
- sta $ddfd,x
-
- oPERATIONAL DIAGRAM OF sta $ddfd,x:
-
- # DATA ADDRESS r/w DESCRIPTION
- --- ---- ------- --- ---------------------------------
- 1 9d pc r FETCH OPCODE
- 2 fd pc+1 r FETCH ADDRESS LOW
- 3 dc pc+2 r FETCH ADDRESS HIGH, ADD x TO ADDRESS LOW
- 4 XX $dd0d r READ FROM ADDRESS, FIX HIGH BYTE OF ADDRESS
- 5 AC $de0d w WRITE TO RIGHT ADDRESS
-
-
- wITH BRANCH INSTRUCTIONS:
-
- ; ACKNOWLEDGE INTERRUPTS TO cia 2
- lda #$00 ; CLEAR n FLAG
- jmp $dd0a
- dd0a bpl $dc9d ; BRANCH
- dc9d brk ; RETURN
-
- yOU NEED THE FOLLOWING PREPARATIONS TO INITIALIZE THE cia REGISTERS:
-
- lda #$91 ; ARGUMENT OF bpl
- sta $dd0b
- lda #$10 ; bpl
- sta $dd0a
- sta $dd08 ; LOAD THE tOd VALUES FROM THE LATCHES
- lda $dd0b ; FREEZE THE tOd DISPLAY
- lda #$7f
- sta $dc0d ; ASSURE THAT $dc0d IS $00
-
- oPERATIONAL DIAGRAM OF bpl $dc9d:
-
- # DATA ADDRESS r/w DESCRIPTION
- --- ---- ------- --- ---------------------------------
- 1 10 $dd0a r FETCH OPCODE
- 2 91 $dd0b r FETCH ARGUMENT
- 3 XX $dd0c r FETCH OPCODE, ADD ARGUMENT TO pcl
- 4 YY $dd9d r FETCH OPCODE, FIX pch
- ( 5 00 $dc9d r FETCH OPCODE )
-
-
- ; ACKNOWLEDGE INTERRUPTS TO cia 1
- lsr ; CLEAR n FLAG
- jmp $dcfa
- dcfa bpl $dd0d
- dd0d brk
-
- ; aGAIN YOU NEED TO SET THE tOd REGISTERS OF cia 1 AND THE
- ; iNTERRUPT cONTROL rEGISTER OF cia 2 FIRST.
-
- oPERATIONAL DIAGRAM OF bpl $dd0d:
-
- # DATA ADDRESS r/w DESCRIPTION
- --- ---- ------- --- ---------------------------------
- 1 10 $dcfa r FETCH OPCODE
- 2 11 $dcfb r FETCH ARGUMENT
- 3 XX $dcfc r FETCH OPCODE, ADD ARGUMENT TO pcl
- 4 YY $dc0d r FETCH OPCODE, FIX pch
- ( 5 00 $dd0d r FETCH OPCODE )
-
-
- ; ACKNOWLEDGE INTERRUPTS TO cia 2 AUTOMAGICALLY
- ; PREPARATIONS
- lda #$7f
- sta $dd0d ; DISABLE ALL INTERRUPT SOURCES OF cia2
- lda $dd0e
- and #$be ; ENSURE THAT $dd0c REMAINS CONSTANT
- sta $dd0e ; AND STOP THE TIMER
- lda #$fd
- sta $dd0c ; PARAMETER OF bpl
- lda #$10
- sta $dd0b ; bpl
- lda #$40
- sta $dd0a ; rti/PARAMETER OF lsr
- lda #$46
- sta $dd09 ; lsr
- sta $dd08 ; LOAD THE tOd VALUES FROM THE LATCHES
- lda $dd0b ; FREEZE THE tOd DISPLAY
- lda #$09
- sta $0318
- lda #$dd
- sta $0319 ; CHANGE nmi VECTOR TO $dd09
- lda #$ff ; tRY CHANGING THIS INSTRUCTION'S OPERAND
- sta $dd05 ; (SEE COMMENT BELOW).
- lda #$ff
- sta $dd04 ; SET INTERRUPT FREQUENCY TO 1/65536 CYCLES
- lda $dd0e
- and #$80
- ora #$11
- ldx #$81
- stx $dd0d ; ENABLE TIMER INTERRUPT
- sta $dd0e ; START TIMER
-
- lda #$00 ; tO SEE THAT THE INTERRUPTS REALLY OCCUR,
- sta $d011 ; USE SOMETHING LIKE THIS AND SEE HOW
- loop dec $d020 ; CHANGING THE BYTE LOADED TO $dd05 FROM
- bne loop ; #$ff TO #$0f CHANGES THE IMAGE.
-
- wHEN AN nmi OCCURS, THE PROCESSOR JUMPS TO kERNAL CODE, WHICH JUMPS TO
- ($0318), WHICH POINTS TO THE FOLLOWING ROUTINE:
-
- dd09 lsr $40 ; CLEAR n FLAG
- bpl $dd0a ; nOTE: $dd0a CONTAINS rti.
-
- oPERATIONAL DIAGRAM OF bpl $dd0a:
-
- # DATA ADDRESS r/w DESCRIPTION
- --- ---- ------- --- ---------------------------------
- 1 10 $dd0b r FETCH OPCODE
- 2 11 $dd0c r FETCH ARGUMENT
- 3 XX $dd0d r FETCH OPCODE, ADD ARGUMENT TO pcl
- 4 40 $dd0a r FETCH OPCODE, (FIX pch)
-
-
- wITH rti:
-
- ; THE FASTEST POSSIBLE INTERRUPT HANDLER IN THE 6500 FAMILY
- ; PREPARATIONS
- sei
- lda $01 ; DISABLE rom AND ENABLE i/o
- and #$fd
- ora #$05
- sta $01
- lda #$7f
- sta $dd0d ; DISABLE cia 2'S ALL INTERRUPT SOURCES
- lda $dd0e
- and #$be ; ENSURE THAT $dd0c REMAINS CONSTANT
- sta $dd0e ; AND STOP THE TIMER
- lda #$40
- sta $dd0c ; STORE rti TO $dd0c
- lda #$0c
- sta $fffa
- lda #$dd
- sta $fffb ; CHANGE nmi VECTOR TO $dd0c
- lda #$ff ; tRY CHANGING THIS INSTRUCTION'S OPERAND
- sta $dd05 ; (SEE COMMENT BELOW).
- lda #$ff
- sta $dd04 ; SET INTERRUPT FREQUENCY TO 1/65536 CYCLES
- lda $dd0e
- and #$80
- ora #$11
- ldx #$81
- stx $dd0d ; ENABLE TIMER INTERRUPT
- sta $dd0e ; START TIMER
-
- lda #$00 ; tO SEE THAT THE INTERRUPTS REALLY OCCUR,
- sta $d011 ; USE SOMETHING LIKE THIS AND SEE HOW
- loop dec $d020 ; CHANGING THE BYTE LOADED TO $dd05 FROM
- bne loop ; #$ff TO #$0f CHANGES THE IMAGE.
-
- wHEN AN nmi OCCURS, THE PROCESSOR JUMPS TO kERNAL CODE, WHICH
- JUMPS TO ($0318), WHICH POINTS TO THE FOLLOWING ROUTINE:
-
- dd0c rti
-
- hOW ON EARTH CAN THIS CLEAR THE INTERRUPTS? rEMEMBER, THE
- PROCESSOR ALWAYS FETCHES TWO SUCCESSIVE BYTES FOR EACH
- INSTRUCTION.
-
- a LITTLE MORE PRACTICAL VERSION OF THIS IS REDIRECTING THE nmi
- (OR irq) TO YOUR OWN ROUTINE, WHOSE LAST INSTRUCTION IS jmp
- $dd0c OR jmp $dc0c. iF YOU WANT TO CONFUSE MORE, CHANGE THE 0
- IN THE ADDRESS TO A HEXADECIMAL DIGIT DIFFERENT FROM THE ONE
- YOU USED WHEN WRITING THE rti.
-
- oR YOU CAN COMBINE THE LATTER TWO METHODS:
-
- dd09 lsr $XX ; XX IS ANY APPROPRIATE bcd VALUE 00-59.
- bpl $dcfc
- dcfc rti
-
- tHIS EXAMPLE ACKNOWLEDGES INTERRUPTS TO BOTH ciaS.
-
-
- iF YOU WANT TO CONFUSE THE EXAMINERS OF YOUR CODE, YOU CAN USE ANY
- OF THESE TECHNIQUES. aLTHOUGH THESE EXAMPLES USE NO UNDEFINED OPCODES,
- THEY DO NOT NECESSARILY RUN CORRECTLY ON cmos PROCESSORS. hOWEVER, THE
- rti EXAMPLE SHOULD RUN ON 65c02 AND 65c816, AND THE LATTER BRANCH
- INSTRUCTION EXAMPLE MIGHT WORK AS WELL.
-
- tHE rmw INSTRUCTION METHOD HAS BEEN USED IN SOME DEMOS, OTHERS WERE
- DEVELOPED BY mARKO m{$e4}KEL{$e4}. hIS FAVOURITE IS THE AUTOMAGICAL rti
- METHOD, ALTHOUGH IT DOES NOT HAVE ANY PRACTICAL APPLICATIONS, EXCEPT
- FOR SOME TIME DEPENDENT DATA DECRYPTION ROUTINES FOR VERY COMPLICATED
- COPY PROTECTIONS.
-
-
-
- mEMORY mANAGEMENT
-
-
- tHE PROCESSOR'S POINT OF VIEW
-
- tHE cOMMODORE 64 HAS ACCESS TO MORE MEMORY THAN ITS PROCESSOR CAN
- DIRECTLY HANDLE. tHIS IS POSSIBLE BY BANKING THE MEMORY. tHERE ARE
- FIVE USER CONFIGURABLE INPUTS THAT AFFECT THE BANKING. tHREE OF THEM
- CAN BE CONTROLLED BY PROGRAM, AND THE REST TWO SERVE AS CONTROL LINES
- ON THE MEMORY EXPANSION PORT.
-
- tHE 6510 mpu HAS AN INTEGRATED i/o PORT WITH SIX i/o LINES. tHIS
- PORT IS ACCESSED THROUGH THE MEMORY LOCATIONS 0 AND 1. tHE LOCATION 0
- IS THE dATA dIRECTION rEGISTER FOR THE pERIPHERAL DATA rEGISTER, WHICH
- IS MAPPED TO THE OTHER LOCATION. wHEN A BIT IN THE ddr IS SET, THE
- CORRESPONDING pr BIT CONTROLS THE STATE OF A CORRESPONDING pERIPHERAL
- LINE AS AN OUTPUT. wHEN IT IS CLEAR, THE STATE OF THE pERIPHERAL LINE
- IS REFLECTED BY THE pERIPHERAL REGISTER. tHE pERIPHERAL LINES ARE
- NUMBERED FROM 0 TO 5, AND THEY ARE MAPPED TO THE ddr AND pr BITS 0 - 5,
- RESPECTIVELY. tHE 8502 PROCESSOR, WHICH IS USED IN THE cOMMODORE 128,
- HAS SEVEN pERIPHERAL LINES IN ITS i/o PORT. tHE PIN p6 IS CONNECTED TO
- THE asc/cc KEY (cAPS LOCK IN eNGLISH VERSIONS).
-
- tHE i/o LINES HAVE THE FOLLOWING FUNCTIONS:
-
- dIRECTION lINE fUNCTION
- --------- ---- --------
- OUT p5 cASSETTE MOTOR CONTROL. (0 = MOTOR SPINS)
- IN p4 cASSETTE SENSE. (0 = play BUTTON DEPRESSED)
- OUT p3 cASSETTE WRITE DATA.
- OUT p2 charen
- OUT p1 hiram
- OUT p0 loram
-
- tHE DEFAULT VALUE OF THE ddr REGISTER IS $2f, SO ALL LINES EXCEPT
- cASSETTE SENSE ARE OUTPUTS. tHE DEFAULT pr VALUE IS $37 (dATASSETTE
- MOTOR STOPPED, AND ALL THREE MEMORY MANAGEMENT LINES HIGH).
- iF YOU TURN ANY MEMORY MANAGEMENT LINE TO INPUT, THE EXTERNAL PULL-UP
- RESISTORS MAKE IT TO LOOK LIKE IT IS OUTPUTTING LOGICAL "1". tHIS
- IS ACTUALLY WHY THE COMPUTER ALWAYS SWITCHES THE romS IN UPON STARTUP:
- pULLING THE -reset LINE LOW RESETS ALL pERIPHERAL LINES TO INPUTS,
- THUS SETTING ALL THREE PROCESSOR-DRIVEN MEMORY MANAGEMENT LINES TO
- LOGICAL "1" LEVEL.
-
- tHE TWO REMAINING MEMORY MANAGEMENT LINES ARE -exrom AND -game ON
- THE CARTRIDGE PORT. eACH LINE HAS A PULL-UP RESISTOR, SO THE LINES
- ARE "1" BY DEFAULT.
-
- eVEN THOUGH THE MEMORY BANKING HAS BEEN IMPLEMENTED WITH A 82s100
- pROGRAMMABLE _lOGIC_ aRRAY, THERE IS ONLY ONE CONTROL LINE THAT SEEMS
- TO BEHAVE LOGICALLY AT FIRST SIGHT, THE -charen LINE. iT IS MOSTLY
- USED TO CHOOSE BETWEEN i/o ADDRESS SPACE AND THE CHARACTER GENERATOR
- rom. tHE FOLLOWING MEMORY MAP INTRODUCES THE ODDITIES OF -charen AND
- THE OTHER MEMORY MANAGEMENT LINES. iT IS BASED ON THE MEMORY MAPS IN
- THE cOMMODORE 64 pROGRAMMER'S rEFERENCE gUIDE, PP. 263 - 267, AND SOME
- ERRORS AND INACCURACIES HAVE BEEN CORRECTED.
-
- tHE LEFTMOST COLUMN OF THE TABLE CONTAINS ADDRESSES IN HEXADECIMAL
- NOTATION. tHE COLUMNS ASIDE IT INTRODUCE ALL POSSIBLE MEMORY
- CONFIGURATIONS. tHE DEFAULT MODE IS ON THE LEFT, AND THE ABSOLUTELY
- MOST RARELY USED uLTIMAX GAME CONSOLE CONFIGURATION IS ON THE RIGHT.
- (hAS ANYBODY EVER SEEN ANY uLTIMAX GAMES?) eACH MEMORY CONFIGURATION
- COLUMN HAS ONE OR MORE FOUR-DIGIT BINARY NUMBERS AS A TITLE. tHE BITS,
- FROM LEFT TO RIGHT, REPRESENT THE STATE OF THE -loram, -hiram, -game
- AND -exrom LINES, RESPECTIVELY. tHE BITS WHOSE STATE DOES NOT MATTER
- ARE MARKED WITH "X". fOR INSTANCE, WHEN THE uLTIMAX VIDEO GAME
- CONFIGURATION IS ACTIVE (THE -game LINE IS SHORTED TO GROUND), THE
- -loram AND -hiram LINES HAVE NO EFFECT.
-
-
- DEFAULT 001X uLTIMAX
- 1111 101X 1000 011X 00X0 1110 0100 1100 XX01
- 10000
- ----------------------------------------------------------------------
- f000
- kERNAL ram ram kERNAL ram kERNAL kERNAL kERNAL romh(*
- e000
- ----------------------------------------------------------------------
- d000 io/c io/c io/ram io/c ram io/c io/c io/c i/o
- ----------------------------------------------------------------------
- c000 ram ram ram ram ram ram ram ram -
- ----------------------------------------------------------------------
- b000
- basic ram ram ram ram basic romh romh -
- a000
- ----------------------------------------------------------------------
- 9000
- ram ram ram ram ram roml ram roml roml(*
- 8000
- ----------------------------------------------------------------------
- 7000
-
- 6000
- ram ram ram ram ram ram ram ram -
- 5000
-
- 4000
- ----------------------------------------------------------------------
- 3000
-
- 2000 ram ram ram ram ram ram ram ram -
-
- 1000
- ----------------------------------------------------------------------
- 0000 ram ram ram ram ram ram ram ram ram
- ----------------------------------------------------------------------
-
- *) iNTERNAL MEMORY DOES NOT RESPOND TO WRITE ACCESSES TO THESE
- AREAS.
-
-
- lEGEND: kERNAL e000-ffff kERNAL rom.
-
- io/c d000-dfff i/o ADDRESS SPACE OR cHARACTER
- GENERATOR rom, SELECTED BY
- -charen. iF THE charen BIT IS
- CLEAR, THE CHARACTER GENERATOR
- rom WILL BE SELECTED. iF IT IS
- SET, THE i/o CHIPS ARE
- ACCESSIBLE.
-
- io/ram d000-dfff i/o ADDRESS SPACE OR ram,
- SELECTED BY -charen. iF THE
- charen BIT IS CLEAR, THE
- CHARACTER GENERATOR rom WILL
- BE SELECTED. iF IT IS SET, THE
- INTERNAL ram IS ACCESSIBLE.
-
- i/o d000-dfff i/o ADDRESS SPACE.
- tHE -charen LINE HAS NO EFFECT.
-
- basic a000-bfff basic rom.
-
- romh a000-bfff OR eXTERNAL rom WITH THE -romh LINE
- e000-ffff CONNECTED TO ITS -cs LINE.
-
- roml 8000-9fff eXTERNAL rom WITH THE -roml LINE
- CONNECTED TO ITS -cs LINE.
-
- ram VARIOUS RANGES cOMMODORE 64'S INTERNAL ram.
-
- - 1000-7fff AND oPEN ADDRESS SPACE.
- a000-cfff tHE cOMMODORE 64'S MEMORY CHIPS
- DO NOT DETECT ANY MEMORY ACCESSES
- TO THIS AREA EXCEPT THE vic-ii'S
- dma AND MEMORY REFRESHES.
-
- note: wHENEVER THE PROCESSOR TRIES TO WRITE TO ANY rom AREA
- (kERNAL, basic, charom, roml, romh), THE DATA WILL GET
- "THROUGH THE rom" TO THE c64'S INTERNAL ram.
-
- fOR THIS REASON, YOU CAN EASILY COPY DATA FROM rom TO ram,
- WITHOUT ANY BANK SWITCHING. bUT IMPLEMENTING EXTERNAL
- MEMORY EXPANSIONS WITHOUT dma IS VERY HARD, AS YOU HAVE TO
- USE A 256 BYTE WINDOW ON THE i/o1 OR i/o2 AREA, LIKE
- georam, OR THE uLTIMAX MEMORY CONFIGURATION, IF YOU DO NOT
- WANT THE DATA TO BE WRITTEN BOTH TO INTERNAL AND EXTERNAL
- ram.
-
- hOWEVER, THIS IS NOT TRUE FOR THE uLTIMAX VIDEO GAME
- CONFIGURATION. iN THAT MODE, THE INTERNAL ram IGNORES ALL
- MEMORY ACCESSES OUTSIDE THE AREA $0000-$0fff, UNLESS THEY
- ARE PERFORMED BY THE vic, AND YOU CAN WRITE TO EXTERNAL
- MEMORY AT $1000-$cfff AND $e000-$ffff, IF ANY, WITHOUT
- CHANGING THE CONTENTS OF THE INTERNAL ram.
-
-
- a NOTE CONCERNING THE i/o AREA
-
- tHE i/o AREA OF THE cOMMODORE 64 IS DIVIDED AS FOLLOWS:
-
- aDDRESS RANGE oWNER
- ------------- -----
- d000-d3ff mos 6567/6569 vic-ii vIDEO iNTERFACE cONTROLLER
- d400-d7ff mos 6581 sid sOUND iNTERFACE dEVICE
- d800-dbff cOLOR ram (ONLY LOWER NYBBLES ARE CONNECTED)
- dc00-dcff mos 6526 cia cOMPLEX iNTERFACE aDAPTER #1
- dd00-ddff mos 6526 cia cOMPLEX iNTERFACE aDAPTER #2
- de00-deff uSER EXPANSION #1 (-i/o1 ON eXPANSION pORT)
- df00-dfff uSER EXPANSION #2 (-i/o2 ON eXPANSION pORT)
-
- aS YOU CAN SEE, THE ADDRESS RANGES FOR THE CHIPS ARE MUCH LARGER
- THAN REQUIRED. bECAUSE OF THIS, YOU CAN ACCESS THE CHIPS THROUGH
- MULTIPLE MEMORY AREAS. tHE vic-ii APPEARS IN ITS WINDOW EVERY $40
- ADDRESSES. fOR INSTANCE, THE ADDRESSES $d040 AND $d080 ARE BOTH MAPPED
- TO THE sPRITE 0 x CO-ORDINATE REGISTER. tHE sid HAS ONE REGISTER
- SELECTION LINE LESS, THUS IT APPEARS AT EVERY $20 BYTES. tHE cia CHIPS
- HAVE ONLY 16 REGISTERS, SO THERE ARE 16 COPIES OF EACH IN THEIR MEMORY
- AREA.
-
- hOWEVER, YOU SHOULD NOT USE OTHER ADDRESSES THAN THOSE SPECIFIED BY
- cOMMODORE. fOR INSTANCE, THE cOMMODORE 128 MAPPED ITS ADDITIONAL i/o
- CHIPS TO THIS SAME MEMORY AREA, AND THE sid RESPONDS ONLY TO THE
- ADDRESSES d400-d4ff, ALSO WHEN IN c64 MODE. aND THE cOMMODORE 65, OR
- THE c64dx, WHICH UNFORTUNATELY DID NOT MAKE ITS WAY TO THE MARKET,
- COULD NARROW THE MEMORY WINDOW RESERVED FOR ITS csg 4567 vic-iii.
-
-
- tHE VIDEO CHIP
-
- tHE mos 6567/6569 vic-ii vIDEO iNTERFACE cONTROLLER HAS ACCESS TO
- ONLY 16 KILOBYTES AT A TIME. tO ENABLE THE vic-ii TO ACCESS THE WHOLE
- 64 Kb MEMORY SPACE, THE MAIN MEMORY IS DIVIDED TO FOUR BANKS OF 16 Kb
- EACH. tHE LINES pa0 AND pa1 OF THE SECOND cia ARE THE INVERSE OF THE
- VIRTUAL vic-ii ADDRESS LINES va14 AND va15, RESPECTIVELY. tO SELECT A
- vic-ii BANK OTHER THAN THE DEFAULT, YOU MUST PROGRAM THE cia LINES TO
- OUTPUT THE DESIRED BIT PAIR. fOR INSTANCE, THE FOLLOWING CODE SELECTS
- THE MEMORY AREA $4000-$7fff (BANK 1) FOR THE VIDEO CONTROLLER:
-
- lda $dd02 ; dATA dIRECTION rEGISTER a
- ora #$03 ; sET PINS pa0 AND pa1 TO OUTPUTS
- sta $dd02
- lda $dd00
- and #$fc ; mASK THE LOWMOST BIT PAIR OFF
- ora #$02 ; sELECT vic-ii BANK 1 (THE INVERSE OF BINARY 01 IS 10)
- sta $dd00
-
- wHY SHOULD YOU SET THE PINS TO OUTPUTS? hARDWARE reset RESETS ALL
- i/o LINES TO INPUTS, AND THANKS TO THE cia'S INTERNAL PULL-UP
- RESISTORS, THE INPUTS ACTUALLY OUTPUT LOGICAL HIGH VOLTAGE LEVEL. sO,
- UPON -reset, THE VIDEO BANK 0 IS SELECTED AUTOMATICALLY, AND OLDER
- kERNALS COULD LEAVE IT UNINITIALIZED.
-
- nOTE THAT THE vic-ii ALWAYS FETCHES ITS INFORMATION FROM THE
- INTERNAL ram, TOTALLY IGNORING THE MEMORY CONFIGURATION LINES. tHERE
- IS ONLY ONE EXCEPTION TO THIS RULE: tHE CHARACTER GENERATOR rom.
- uNLESS THE uLTIMAX MODE IS SELECTED, vic-ii "SEES" CHARACTER GENERATOR
- rom IN THE MEMORY AREAS 1000-1fff AND 9000-9fff. iF THE uLTIMAX
- CONFIGURATION IS ACTIVE, THE vic-ii FETCHES ALL DATA FROM THE INTERNAL
- ram.
-
-
- aCCESSING THE MEMORY PLACES 0 AND 1
-
- aLTHOUGH THE ADDRESSES 0 AND 1 OF THE PROCESSOR ARE HARD-WIRED TO
- ITS ON-CHIP i/o PORT REGISTERS, YOU CAN ACCESS THE MEMORY PLACES 0 AND
- 1. tHE VIDEO CHIP ALWAYS READS FROM ram (OR CHARACTER GENERATOR rom),
- SO YOU CAN USE IT TO READ ALSO FROM 0 AND 1. eNABLE THE BIT-MAP SCREEN
- AND SET THE START ADDRESS OF THE GRAPHICS SCREEN TO 0. nOW YOU CAN SEE
- THESE TWO MEMORY LOCATIONS IN THE UPPER LEFT CORNER. aLTERNATIVELY,
- YOU COULD SET THE CHARACTER GENERATOR START ADDRESS TO 0, IN WHICH
- CASE YOU WOULD SEE THESE LOCATIONS IN @ CHARACTERS (CODE 0). oR, YOU
- CAN ACTIVATE A SPRITE WITH START ADDRESS 0. wHICHEVER METHOD YOU
- CHOOSE, YOU CAN READ THESE LOCATIONS WITH SPRITE COLLISION REGISTERS.
- dEFINE A SPRITE CONSISTING OF ONLY ONE DOT, AND MOVE IT TO READ THE 8
- BITS OF EACH BYTE WITH THE SPRITE TO SPRITE OR SPRITE TO BACKGROUND
- COLLISION REGISTERS.
-
- bUT HOW CAN YOU WRITE TO THESE LOCATIONS? iF YOU EXECUTE THE COMMAND
- poke 53265,59, YOU WILL SEE THAT THE MEMORY PLACE 1 CHANGES ITS VALUE
- WILDLY. iF YOU DISABLE THE INTERRUPTS (poke53664,127), IT WILL REMAIN
- STABLE. hOW IS THIS POSSIBLE? wHEN THE PROCESSOR WRITES TO 0 OR 1, IT
- WILL PUT THE ADDRESS ON THE ADDRESS BUS AND SET THE r/-w LINE TO INDICATE
- A WRITE CYCLE, BUT IT DOES NOT PUT THE DATA ON THE DATA BUS. tHUS, IT
- WRITES "RANDOM" DATA. oF COURSE THIS DATA IS NOT TRULY RANDOM. aCTUALLY
- IT IS SOMETHING THAT THE VIDEO CHIP LEFT ON THE BUS ON ITS CLOCK HALF.
- sO, IF YOU WANT TO WRITE A CERTAIN VALUE ON 0 OR 1, YOU HAVE TO MAKE THE
- VIDEO CHIP TO READ THAT VALUE JUST BEFORE THE STORE CYCLE. tHIS REQUIRES
- VERY ACCURATE TIMING, BUT IT CAN BE ACHIEVED EVEN WITH A CAREFULLY
- WRITTEN basic PROGRAM. jUST WAIT THE VIDEO CHIP TO BE IN THE TOP OR
- BOTTOM BORDER AND THE BEAM TO BE IN THE MIDDLE OF THE SCREEN (NOT IN THE
- SIDE BORDERS). aT THIS AREA, THE VIDEO CHIP WILL ALWAYS READ THE LAST
- BYTE OF THE VIDEO BANK (BY DEFAULT $3fff). nOW, IF YOU STORE ANYTHING TO
- THE i/o PORT REGISTERS 0 OR 1 WHILE THE VIDEO CHIP IS REFRESHING THIS
- SCREEN AREA, THE CONTENTS OF THE MEMORY PLACE $3fff WILL BE WRITTEN TO
- THE RESPECTIVE MEMORY PLACE (0 OR 1). nOTE THAT THIS TRICK DOES NOT WORK
- RELIABLY ON ALL COMPUTERS. yOU NEED GOOD rf PROTECTION, AS THE DATA BUS
- WILL NOT BE DRIVEN AT ALL WHEN THE VALUE REMAINS ON IT.
-
- oN THE c128 IN ITS 2 mhZ MODE, YOU CAN WRITE TO THE MEMORY PLACES
- WITH AN EASIER KLUDGE. jUST MAKE SURE THAT THE VIDEO CHIP IS NOT
- PERFORMING THE MEMORY REFRESH (AS IT WOULD SLOW DOWN TO 1 mhZ IN THAT
- CASE), AND USE SOME INSTRUCTION THAT READS FROM A PROPER MEMORY LOCATION
- BEFORE WRITING TO 0 OR 1. iNDEXED ZERO-PAGE ADDRESSING MODES ARE GOOD
- FOR IT. i TESTED THIS TRICK WITH ldx#1 FOLLOWED BY sta $ff,x. aS YOU
- CAN READ FROM THE INSTRUCTION TIMING SECTION OF THIS DOCUMENT, THE
- INSTRUCTION FIRST READS FROM $ff (THE BASE ADDRESS) AND THEN WRITES TO 0.
- tHE TIMING CAN BE DONE WITH A SIMPLE lda$d012:cmp$d012:beq *-3 LOOP.
- bUT IN THE c128 MODE YOU CAN RELOCATE THE STACK PAGE TO ZERO PAGE, SO
- THIS TRICK IS NOT REALLY USEFUL.
-
- yOU CAN ALSO READ THE MEMORY PLACES 0 AND 1 MUCH FASTER THAN WITH
- SPRITE COLLISIONS. jUST MAKE THE VIDEO CHIP TO READ FROM 0 OR 1, AND
- THEN READ FROM NON-CONNECTED ADDRESS SPACE ($de00-$dfff ON A STOCK c64;
- ALSO $d700-$d7ff ON c128'S). aCTUALLY, YOU CAN PRODUCE A COMPLETE MAP
- OF THE VIDEO TIMING ON YOUR COMPUTER BY MAKING A LOOP THAT READS FROM
- OPEN ADDRESS SPACE, PAUSING ONE FRAME AND ONE CYCLE IN BETWEEN. aND IF
- YOU ARE INTO COPY PROTECTIONS, YOU COULD WRITE A PROGRAM ON THE OPEN
- ADDRESS SPACE. jUST REMEMBER THAT THERE MUST BE A BYTE ON THE BUS FOR
- EACH CLOCK CYCLE.
-
- tHESE TRICKS UNFORTUNATELY DO NOT WORK RELIABLY ON ALL UNITS. sO FAR
- i HAVE HAD THE OPPORTUNITY TO TRY IT ON THREE COMPUTERS, TWO OF WHICH
- WERE cOMMODORE 128 dcr'S (c128'S HOUSED IN METAL CASE WITH A 1571 FLOPPY
- DISK DRIVE, WHOSE CONTROLLER IS INTEGRATED ON THE MOTHER BOARD). oNE
- c128dcr DROVE SOME OF ITS DATA BITS TOO HEAVILY TO HIGH STATE. nO WONDER,
- SINCE ITS HOUSING CONSISTED OF SOME NEWSPAPERS SPREAD ON THE FLOOR.
-
-
-
- aUTOSTART cODE
-
- aLTHOUGH THIS DOCUMENT CONCENTRATES ON HARDWARE, THERE IS ONE THING
- THAT YOU MUST KNOW ABOUT THE FIRMWARE TO GET COMPLETE CONTROL OVER
- YOUR COMPUTER. aS THE cOMMODORE 64 ALWAYS SWITCHES THE romS ON UPON
- -reset, YOU CANNOT RELOCATE THE reset VECTOR BY WRITING SOMETHING IN
- ram. iNSTEAD, YOU HAVE TO USE THE aUTOSTART CODE THAT WILL BE
- RECOGNIZED BY THE kernal rom. iF THE MEMORY PLACES FROM $8004 THROUGH
- $8008 CONTAIN THE petscii STRING 'cbm80' (c3 c2 cd 38 30), THE reset
- ROUTINE JUMPS TO ($8000) AND THE DEFAULT nmi HANDLER JUMPS TO ($8002).
-
- sOME PROGRAMS THAT LOAD INTO ram TAKE ADVANTAGE OF THIS AND DON'T
- LET THE MACHINE TO BE RESET. yOU DON'T HAVE TO MODIFY THE rom TO GET
- RID OF THIS ANNOYING BEHAVIOUR. sIMPLY GROUND THE -exrom LINE FOR THE
- BEGINNING OF THE reset SEQUENCE.
-
-
-
- nOTES
-
- sEE THE mcs 6500 mICROCOMPUTER fAMILY pROGRAMMING mANUAL FOR LESS
- INFORMATION.
-
-
- rEFERENCES:
- c64 mEMORY mAPS c64 pROGRAMMER'S rEFERENCE gUIDE, PP. 262-267
- c64 sCHEMATIC dIAGRAM
- 6510 bLOCK dIAGRAM c64 pROGRAMMER'S rEFERENCE gUIDE, P. 404
- iNSTRUCTION sET c64 pROGRAMMER'S rEFERENCE gUIDE, PP. 254-255, 416-417
- c64/128 rEAL pROGRAMMER'S rEVENGE gUIDE
- c=lEHTI MAGAZINE 4/87
-