เอาท์พุทรายการโน้ตดนตรี


27

งานนี้ง่าย: เขียนโปรแกรมหรือฟังก์ชั่นที่ส่งออกรายการโน้ตดนตรีทั้งหมด (ใช้ชื่อโน้ตภาษาอังกฤษ) จาก A ♭ถึงG♯

บันทึกย่อทั้งหมดที่ไม่มีชื่อประกอบด้วยตัวอักษรตัวเดียว (เช่นตัวโน้ตสีดำบนคีย์บอร์ดดนตรี) ควรพิมพ์ชื่อของพวกเขาสองครั้งหนึ่งครั้งเมื่อคมชัดของโน้ตหนึ่งครั้งเมื่อแบนของหนึ่ง โน้ตที่คมหรือแบนที่สามารถอธิบายได้ด้วยตัวอักษรเดียวเช่นB♯ (C) หรือ F ♭ (E) ไม่ควรเอาท์พุท

นี่คือตัวอย่างของผลลัพธ์:

Ab, A, A#, Bb, B, C, C#, Db, D, D#, Eb, E, F, F#, Gb, G, G#

ข้อมูลจำเพาะ

  • โปรแกรมหรือฟังก์ชั่นจะต้องไม่นำเข้าใด ๆ

  • หมายเหตุอาจพิมพ์ในลำดับใด ๆ และในรายการผลลัพธ์ใด ๆ ที่อนุญาตโดยกฎ I / O มาตรฐานของเรา

  • สัญลักษณ์ Unicode ที่คมและแบน (♯ / ♭) อาจถูกแทนที่ด้วยb และ#

  • เช่นเคยห้ามช่องโหว่มาตรฐาน

  • เช่นนี้คือโปรแกรมที่เล็กที่สุดเป็นไบต์ชนะ



1
เราจะเอาท์พุท"C "แทน"C"?
Arnauld

1
@Arnauld ใช่คุณอาจ
TheOnlyMrCat

7
โดยวิธีการที่ B # มีอยู่ในโน้ตดนตรี; มันเป็นตัวอย่างในลายเซ็นคีย์สำหรับคีย์ของ C # ซึ่งทำหน้าที่เป็นเสียงนำ
Kaz

2
ฉันไม่รู้มันรู้สึกเหมือน Cb หายไปที่นี่;)
AJFaraday

คำตอบ:


13

Malbolge , 482 370 353 ไบต์

R1: ลบเครื่องหมายจุลภาคออกระหว่าง (ตามที่ท้าทายโดยไม่จำเป็น)

R2: โกนออกสองสามไบต์

('<;_#!=6Z|{8xUwvt,PrqonKmk)"FhCUTdb?`+<;:[Z7YtVU2T|/g-O+i(gJrHc#EC~B{@zZxw:tt'r5Qo"!l/K-hUfe?bP``_Lo~[}|X2VCTR3Q+N`_^9+7Hji3ffdAc~w|u;]\wpon4VUSSQ.PONcb(JI^]#DCYX|@?>=<:u9NMRKo32MFj.C,Ae)>'<%:^"!~5:3WxwwuRts0q(Lnml)"Fhgfe"y?a`_zyxq7YXWlUj0RgfkjMb(JI^c\[Z~BAV?T=Rv987Mq44310FEi-,G@)>b&%#"8=6Z{{yyw/Sut1*)('Km$k(!Efe{zyx>`uz]r8ZXnm3TTih.PkNchg`&HFF[DY}Az

ลองออนไลน์!


12

ชุดประกอบCP-1610 ( Intellivision ), 31 DECLEs 1 = 39 ไบต์

รูทีนการรับเอาท์พอยน์เตอร์ในR4และเขียนบันทึกตรงนั้นคั่นด้วยช่องว่าง ในโค้ดตัวอย่างเราเขียนไปที่หน้าจอโดยตรง

Hex dump (รูทีนเท่านั้น)

275 001 2BD 03C 048 1DB 2B8 012 044 2A9 2BA 108 078 201 003 262
261 263 2FA 008 37A 140 225 00B 089 22C 011 2B7 018 210 000

แหล่งข้อมูลเต็มรูปแบบ

                ROMW    10              ; use 10-bit ROM width
                ORG     $4800           ; map this program at $4800

                ;; ------------------------------------------------------------- ;;
                ;;  test code                                                    ;;
                ;; ------------------------------------------------------------- ;;
4800            SDBD                    ; set up an interrupt service routine
4801            MVII    #isr,     R0    ; to do some minimal STIC initialization
4804            MVO     R0,       $100
4806            SWAP    R0
4807            MVO     R0,       $101

4809            EIS                     ; enable interrupts

480A            MVII    #$200,    R4    ; R4 = backtab pointer
480C            CALL    notes           ; invoke our routine

480F            DECR    R7              ; loop forever

                ;; ------------------------------------------------------------- ;;
                ;;  ISR                                                          ;;
                ;; ------------------------------------------------------------- ;;
      isr       PROC

4810            MVO     R0,       $0020 ; enable display

4812            CLRR    R0
4813            MVO     R0,       $0030 ; no horizontal delay
4815            MVO     R0,       $0031 ; no vertical delay
4817            MVO     R0,       $0032 ; no border extension
4819            MVII    #$D,      R0
481B            MVO     R0,       $0028 ; light-blue background
481D            MVO     R0,       $002C ; light-blue border

481F            JR      R5              ; return from ISR

                ENDP

                ;; ------------------------------------------------------------- ;;
                ;;  routine                                                      ;;
                ;; ------------------------------------------------------------- ;;
      notes     PROC

4820            PSHR    R5              ; save return address

4821            SDBD                    ; R5 = pointer to @@chr
4822            MVII    #@@chr,   R5
4825            CLRR    R3              ; R3 = 0 (space)
4826            MVII    #$12,     R0    ; R0 = bitmask = $12
4828            SWAP    R0,       2     ; extend it to $1212

4829  @@loop    MVI@    R5,       R1    ; R1 = next symbol
482A            MVII    #('A'-32)*8, R2 ; R2 = 'A' character

482C  @@note    SARC    R0              ; right shift the bitmask
482D            BC      @@next          ; skip this note if the carry is set

482F            MVO@    R2,       R4    ; append the note
4830            MVO@    R1,       R4    ; append the symbol
4831            MVO@    R3,       R4    ; append a space

4832  @@next    ADDI    #8,       R2    ; advance to the next note
4834            CMPI    #('H'-32)*8, R2 ; is it now a 'H'?
4836            BLT     @@note          ; if not, process the inner loop

4838            TSTR    R1              ; was the symbol a space?
4839            BNEQ    @@loop          ; if not, process the outer loop

483B            PULR    R7              ; return

483C  @@chr     DECLE   ('#'-32)*8      ; '#'
483D            DECLE   ('b'-32)*8      ; 'b'
483E            DECLE   0               ; space

                ENDP

เอาท์พุต

เอาท์พุต

ภาพหน้าจอจากjzIntv


1. CP-1610 opcode ถูกเข้ารหัสด้วยค่า 10 บิตหรือที่เรียกว่า 'DECLE' รูทีนนี้มีความยาว 31 DECLE เริ่มต้นที่ $ 4820 และสิ้นสุดที่ $ 483E (รวมอยู่ด้วย)


9

Python 3 , 50 ไบต์

print(*map(''.join,zip(3*'ADGBCEF',7*' '+5*'#b')))

ลองออนไลน์!

Python 2: 48 ไบต์

รหัสนี้สามารถปรับได้ตามการรวม B # และ Cb โดยไม่มีค่าใช้จ่ายเพิ่มเติมไบต์ นี้สามารถทำได้โดยการแทนที่ด้วย56


นอกจากนี้มันคือ (ในที่สุด) สั้นกว่าเพียงแค่แสดงผลสตริงธรรมดา:

Python 3 , 51 ไบต์

exit('Ab A A# Bb B C C# Db D D# Eb E F F# Gb G G#')

ลองออนไลน์!

Python 2: 50 ไบต์


2
นี่เป็นทางออกที่สร้างสรรค์มาก
TheOnlyMrCat

7

05AB1E , 16 15 13 ไบต์

Au…b #âŽ7×bûÏ

-2 ไบต์ขอบคุณที่@maxb

ลองออนไลน์

ส่งออกเป็นรายการโดยที่โน้ตแบบตัวเดียวจะมีช่องว่างต่อท้าย

คำอธิบาย:

Au             # Push the lowercase alphabet, and uppercase it
  b #         # Push string "b #"
      â        # Take the cartesian product of both strings to create all possible pairs:
               #  ["Ab","A ","A#","Bb","B ","B#",...,"Zb","Z ","Z#"]
       Ž7×     # Push compressed integer 1999
          b    # Convert it to a binary string "11111001111"
           û   # Palindromize it to "111110011111110011111"
            Ï  # Only leave the notes in the list at the truthy values (1), (the trailing
               # items beyond the length of this binary string are also discarded)
               # (after which the result is output implicitly)

ดู 05AB1E นี้เคล็ดลับของฉัน (ส่วนวิธีการบีบอัดจำนวนเต็มขนาดใหญ่? )จะเข้าใจว่าทำไมเป็นŽ7×1999

Ž7×อาจจะเป็น₄·<(1,000, double, ลด 1) สำหรับจำนวนไบต์เดียวกัน


3
เป็นสิ่งที่จำเป็นจริงๆ? ดูเหมือนว่าจะทำงานได้ดีโดยไม่มีมัน
maxb

6

เยลลี่ , 18? * 20 ไบต์

ØAḣ7µp⁾b#Żs6ḣ€4ẎḊ;W€

ลิงก์แบบ monadic ส่งคืนรายการของอักขระ

* หากรายการผสมของ (a) รายการอักขระและ (b) เป็นอักขระที่ยอมรับได้ให้ลบส่วนท้ายW€สำหรับ 18

ลองออนไลน์!

อย่างไร?

ØAḣ7µp⁾b#Żs6ḣ€4ẎḊ;W€ - Link: no argument
ØA                   - list of characters     [A-Z]
  ḣ7                 - head to 7              "ABCDEFG"
    µ                - new monadic link (call that X)
      ⁾b#            - list of characters     "b#"
     p               - Cartesian product      ["Ab","A#","Bb","B#","Cb","C#","Db","D#","Eb","E#","Fb","F#","Gb","G#"]
         Ż           - prepend a zero       [0,"Ab","A#","Bb","B#","Cb","C#","Db","D#","Eb","E#","Fb","F#","Gb","G#"]
          s6         - split into sixes    [[0,"Ab","A#","Bb","B#","Cb"],["C#","Db","D#","Eb","E#","Fb"],["F#","Gb","G#"]]
            ḣ€4      - head each to 4      [[0,"Ab","A#","Bb"],["C#","Db","D#","Eb"],["F#","Gb","G#"]]
               Ẏ     - tighten              [0,"Ab","A#","Bb","C#","Db","D#","Eb","F#","Gb","G#"]
                Ḋ    - dequeue                ["Ab","A#","Bb","C#","Db","D#","Eb","F#","Gb","G#"]
                  W€ - wrap each (of X)       ["A","B","C","D","E","F","G"]
                 ;   - concatenate            ["Ab","A#","Bb","C#","Db","D#","Eb","F#","Gb","G#","A","B","C","D","E","F","G"]

@ mirabilos นี้เป็นรหัสแหล่งที่มา 20 ไบต์อักขระ Unicode แต่ละตัวจะแทนไบต์ของซอร์สโค้ด - ดูหน้ารหัสที่เชื่อมโยงกันด้วยคำbytesในส่วนหัว
Jonathan Allan

5

เรติน่า 0.8.2 , 33 ไบต์


ABCDEFG
.
 $&b $& $&#
 [BE]#...

ลองออนไลน์! คำอธิบาย:


ABCDEFG

ใส่ชื่อโน้ตฐาน

.
 $&b $& $&#

ขยายแต่ละบันทึกย่อเพื่อรวมรุ่นที่แบนและคมชัด

 [BE]#...

ลบB#, E#และยังตั้งข้อสังเกตดังต่อไปนี้พวกเขา ( CbและEb)


5

Perl 6 , 41 ไบต์

{S:g/[E|B]\#...//}o{'A'..'G'X~'b #'.comb}

ลองออนไลน์!

ผลิตภัณฑ์ตัดขวางอย่างง่ายของโน้ตย่อและชาร์ป / แฟลตตามด้วยการลบบันทึกย่อที่ไม่ถูกต้องออกเป็นพิเศษ นี่คือบล็อกรหัสที่ไม่ระบุชื่อที่สร้างสตริง:

Ab A  A# Bb B   C  C# Db D  D# Eb E   F  F# Gb G  G#

4

R , 50 ไบต์

cat("Ab,A,A#,Bb,B,C,C#,Db,D,D#,Eb,E,F,F#,Gb,G,G#")

ลองออนไลน์!

คำตอบที่น่าเบื่อ

R , 60 ไบต์

cat(outer(LETTERS[1:7],c("#","","b"),paste0)[-c(2,5,17,20)])

ลองออนไลน์!


1
ผมคิดว่ารายการตัวอย่างของการบันทึกซ้ำซ้อนไม่ได้หมายถึงจะหมดแรง - ส่งออกตัวอย่างยังละเว้นและCb E#
สตริงที่ไม่เกี่ยวข้อง

4

ถ่าน 21 ไบต์

Φ⪪⭆…α⁷⭆b #⁺ι벧↨⊖⊘φ²κ

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด คำอธิบาย:

    α                   Predefined variable uppercase alphabet
   … ⁷                  First 7 letters i.e. `ABCEDFG`
  ⭆                     Map over characters and join
       b #              Literal string `b #`
      ⭆                 Map over characters and join
          ⁺ιλ           Concatenate outer and inner characters
 ⪪           ²          Split back into substrings of length 2
Φ                       Filter where nonzero
                  φ     Predefined variable 1000
                 ⊘      Halved i.e. 500
                ⊖       Decremented i.e 499
               ↨   ²    Converted to base 2 i.e. [1, 1, 1, 1, 1, 0, 0, 1, 1]
              §     κ   Cyclically indexed by outer index
                        Implicitly print matching values on separate lines

3

Japt , 23 22 ไบต์

;B¯7
ï"b #" fÏÄ %9%8<6

ลองมัน

;B          Alphabet
  ¯7        First seven characters ("ABCDEFG")
            Assign to U
ï"b #"       Cartesian product with "b #" ("Ab,A ,A#,Bb,B ,B#,Cb,C ,C#,Db,D ,D#,Eb,E ,E#,Fb,F ,F#,Gb,G ,G#")
f           Filter:
 ÏÄ           Is index + 1
   %9%8       Mod 9 Mod 8
     <6       Less than 6
            End filter ("Ab,A ,A#,Bb,B ,C ,C#,Db,D ,D#,Eb,E ,F ,F#,Gb,G ,G#")

รหัสของคุณมี<6แต่มัน<5อยู่ในคำอธิบาย
TheOnlyMrCat




2

Ruby , 43 ไบต์

p (2..18).map{|i|"FCGDAEB"[i%7]+"b #"[i/7]}

ลองออนไลน์!

ด้วยช่วง0..20นี้จะพิมพ์อาเรย์ที่มีแฟลตทั้งหมด, เนเชอรัลและชาร์ปทั้งหมด สิ่งที่ไม่พึงประสงค์Fb Cb E# B#ถูกตัดออกโดยใช้ช่วง2..18

บันทึกจะถูกพิมพ์ออกมาตามhttps://en.wikipedia.org/wiki/Circle_of_fifthsหรือกล่าวอีกนัยหนึ่งโดยเพิ่มขึ้น 7 เซมิโคลอน (อัตราส่วนความถี่เกือบ 1.5 เท่า) ในแต่ละครั้ง

สิ่งนี้นำไปสู่การสั่งซื้อจดหมายหมายเหตุซึ่งในแต่ละครั้งจะมีการรวมห้าองศา (เรียกว่า "ห้า") เหนือระดับก่อนหน้า ยกตัวอย่างF->CคือFGABC


ฉันชอบที่คุณปีนขึ้นไปโดยที่ห้า ดี
Wayne Conrad


2

Zsh , 36 ไบต์

<<<${${(F):-{A..G}{b,,#}}//[BE]#???}

วิธีแก้ปัญหาขี้เหร่ แต่มันช่วยตัวละครสองตัว (F)เข้าร่วมรายการในการขึ้นบรรทัดใหม่และ//[BE]#???ลบส่วนของสตริงที่เราต้องการ

ลองออนไลน์!


Zsh , 38 ไบต์

<<<${${:-{A..G}{b,,#}}:#([BE]#|[CF]b)}

ฉันมักจะสนุกเมื่อ Zsh เต้น Perl (หวังว่าฉันจะไม่พูดเร็วเกินไป ... )

<<<${${:-{A..G}{b,,#}}:#([BE]#|[CF]b)}
     ${:-             }                 # empty-fallback, basically an anonymous parameter expansion
         {A..G}{b,,#}                   # Cross product range A-G with b,(nothing),#
   ${                 :#             }  # Remove matching elements
                        ([BE]#|[CF]b)   # B#, E#, Cb, Fb
<<<                                     # Print to stdout

ลองออนไลน์!



1

Brachylogขนาด 36 ไบต์

"#b"ẹ,Ẹ↺;Ṇh₇ᵗ↔{∋ᵐc}ᶠ⟨h₅ct₁₄⟩⟨h₁₂ct₅⟩

ลองออนไลน์!

ขณะนี้ฉันอยู่ในขั้นตอนการบังคับเดรัจฉานดัชนี powerset ที่จะให้ฉันกำจัด⟨h₅ct₁₄⟩⟨h₁₂ct₅⟩(และโดยการขยายเนื่องจากการส่งออกไม่จำเป็นต้องอยู่ในลำดับเดียวกับตัวอย่างผลลัพธ์) แต่มันค่อนข้าง ในขณะที่ ... บางทีฉันควรใช้เวลาสักครู่เพื่อคิดออกว่ารายการย่อยของคำสั่งซื้อใดที่สร้างขึ้นและคำนวณดัชนีด้วยวิธีนี้ ...



1

PHP , 65 ไบต์

สร้างรายการด้วยการวนซ้ำ รายการจะถูกคั่น_ด้วยตัวคั่นต่อท้าย

for(;$l=ABCDEFG[$i++];)echo$l._.[$a="$l#_",$a.$b=$l.b_,$b][$i%3];

ลองออนไลน์!


PHP , 43 ไบต์

PHP แสดงผลทุกอย่างที่เป็นอยู่เมื่อไม่ได้อยู่ภายใน<?phpและ?>แท็ก

Ab,A,A#,Bb,B,C,C#,Db,D,D#,Eb,E,F,F#,Gb,G,G#

ลองออนไลน์!


1

Pyth , 23 21 ไบต์

s<R7c.>*<r1G7"b #"2 9

ลองออนไลน์!

s<R7c.>*<r1G7"b #"2 9   Implicit: G=lowercase alphabet
         r1G            Convert G to upper case
        <   7           First 7 characters
       *     "b #"      Cartesian product with "b #"
     .>           2     Rotate the above 2 places to the right
    c               9   Chop into pieces of length 9
 <R7                    Trim each to length 7
s                       Flatten, implicit print

แก้ไข: เขียนใหม่บางส่วนเพื่อบันทึก 2 ไบต์, เวอร์ชันก่อนหน้า: s%2c*<r1G7"b #"xLG"fhoq ลองออนไลน์!


1

พลเรือจัตวา C64 / TheC64 Mini (อาจเป็นรุ่นพื้นฐาน 8 บิตแบบ Commodore อื่น ๆ ) - 52 ไบต์พื้นฐานโทเค็น

 0?"{CTRL+N}Ab A A# Bb B C C# Db D D# Eb E F F# Gb GG#

การกดปุ่มCTRLบวกNบนแป้นพิมพ์ C64 จะเข้าสู่ 'โหมดธุรกิจ' บนชุดอักขระสำหรับอักขระตัวพิมพ์ใหญ่ / ตัวพิมพ์เล็ก เราอาจพิมพ์ออกมาเป็นสตริงในหนึ่งไบต์ / โทเค็น; และเนื่องจากเรามี 40 คอลัมน์จึงไม่จำเป็นต้องเว้นวรรคจาก G ถึง G #

เราไม่จำเป็นต้องปิดสตริงในกรณีนี้เนื่องจากไม่ใช่บรรทัดที่มีหลายบรรทัดพร้อม:ตัวคั่น

ลักษณะนี้มีลักษณะอย่างไรบนหน้าจอ Commodore C64 (และ compatibles) ที่แสดงด้านล่าง

พลเรือจัตวาโน้ตดนตรี 64



0

APL (Dyalog Unicode)ขนาด 45 ไบต์

2↓(,¨⎕A)⎕R', &''AbAA#BbBCC#DbDD#EbEFF#GbGG#'

ลองออนไลน์!

ง่าย⎕Rการดำเนินงาน eplace, prepending ,กับองค์ประกอบในสตริงที่ตรงกับตัวอักษรแต่ละตัวในแต่ละ⎕Alphabet แล้ววาง 2 ,ตัวอักษรแรกซึ่งเป็น



0

JavaScript (Node.js) , 84 ไบต์

_=>[...'ABCDEFG'].map((n,i)=>`${i%3!=2?n+'b,':''}${n}${i%3!=1?`,${n}#`:''}`).join`,`

ลองออนไลน์!

เพียงแค่คืนค่าสตริง (ดังที่แสดงด้านล่าง) จะสั้นลง 36 ไบต์ แต่ความสนุกในนั้นอยู่ที่ไหน

_=>'Ab,A,A#,Bb,B,C,C#,Db,D,D#,Eb,E,F,F#,Gb,G,G#'

0

brainfuck , 255 115 ไบต์

--[----->+<]>-----[<+>>+>+<<-]>>+<<<-[->+++<]>+++[->>>+>+<
<<<]>>>>--->+++++++[-<<<<.>.>>.<<<.>>>.<<<.>>.>.<<<+>>>>]

ลองออนไลน์!


1
ฉันต้องการโหวตเรื่องนี้ แต่มันผิด ไม่มีโน้ตดำระหว่าง B และ C หรือระหว่าง E และ F ดังนั้นคุณไม่ควรส่งออก B #, Cb, E # หรือ Fb นอกจากนี้ฉันไม่เห็นอะไรเลยในสเป็คเกี่ยวกับการใช้ตัวพิมพ์เล็ก
Level River St

@ LevelRiverSt ความท้าทายไม่ได้ระบุไว้ทุกที่ที่เราไม่มีบันทึกระหว่าง B และ C & E และ F
Krzysztof Szewczyk

All notes without a name consisting of a single letter (i.e. black notes on a musical keyboard) should have their name printed twice, once as the sharp of a note, once as the flat of one. Sharp or flat notes that can be described with a single letter, like B♯ (C) or F♭ (E) should not be outputted.ดูเหมือนว่าจะค่อนข้างชัดเจนสำหรับฉันและฉันไม่เห็นประวัติการแก้ไขบน OP บนหน้าจอของฉัน
เลเวลริเวอร์เซนต์



0

T-SQL, 124 ไบต์

SELECT value+a
FROM STRING_SPLIT('A-B-C-D-E-F-G','-')
    ,(VALUES('b'),(''),('#'))b(a)
WHERE value+a NOT IN ('B#','E#','Cb','Fb')

การขึ้นบรรทัดใหม่มีไว้เพื่อการแสดงผลเท่านั้น

ยาวกว่า แต่น่าสนใจกว่าเวอร์ชั่นเล็กน้อย (50 ไบต์) :

PRINT'Ab,A,A#,Bb,B,C,C#,Db,D,D#,Eb,E,F,F#,Gb,G,G#'

0

Z80Golf , 31 29 ไบต์

00000000: 9d5b dc6d df7f 0603 3e40 d13c cb3a 3008  .[.m....>@.<.:0.
00000010: fff5 7b2f ffaf fff1 20f1 10ec 76         ..{/.... ...v

ลองออนไลน์!

คำอธิบาย :

Z80Golf เป็นเพียงเครื่องแฟนตาซีที่ใช้ Z80 8-bit CPU โปรแกรมถูกโหลดที่ตำแหน่งหน่วยความจำ0x0000และส่วนที่เหลือของหน่วยความจำเต็มไปด้วยเลขศูนย์ การส่งออกจะกระทำโดยการโทร0x8000ซึ่งจะส่งออกค่าของการลงทะเบียน A เป็นตัวละคร

โปรแกรมเริ่มต้นด้วยข้อมูลที่จะถูกประมวลผลรวม 6 ไบต์ แต่ละคู่ของไบต์ระบุคำต่อท้ายบันทึกย่อและ bitmask ควบคุมตัวอักษรที่สามารถรวมกับบันทึกย่อนี้ ในการบันทึกไบต์ตัวอักษรต่อท้ายจะกลับด้าน ( xor 0xff) - อนุญาตให้ข้อมูลดำเนินการตามคำแนะนำที่มีผลข้างเคียงน้อยทำให้สามารถลบกระโดดที่ข้ามข้อมูลนี้ได้:

               ;    GFEDCBA
    db 0xff^'b', 0b01011011 ; Ab Bb Db Eb Gb
    db 0xff^'#', 0b01101101 ; A# C# D# F# G#
    db 0xff^' ', 0b01111111 ; A  B  C  D  E  F  G
skip_data:

นี่คือวิธีที่ CPU ถอดรหัสสิ่งนี้:

    sbc a, l  ; a subtraction with carry on registers we don't care about
    ld e, e   ; put the E register back into itself. This instruction is useless
              ; but still exists to make the encoding regular.
    call c, 0xdf6d ; if the carry flag is set, call a function. The carry flag isn't set
              ; because of the initial register values (all zeroes) when the sbc above
              ; was executed
    ld a, a   ; as above, put A back into itself.

ข้อมูลนี้อ่านครั้งละสองไบต์ในคู่ DE DE register ตัวชี้สแต็กจะใช้เพื่อชี้ไปที่องค์ประกอบถัดไป มันเริ่มต้นที่ 0 และเนื่องจาก Z80 ใช้สแต็คแบบเต็มและจากน้อยไปมากป๊อปใด ๆ จะอ่านคู่ข้อมูลถัดไป - การดำเนินการสแต็กทั้งหมดเป็นแบบ 16 บิต

วนรอบนอกถูกนำไปใช้กับตัวนับการลดลงในการลงทะเบียน B ซึ่ง Z80 ให้การสนับสนุนพิเศษในรูปแบบของdjnzคำสั่ง:

    ld b, 3
process_pair:
    ...
    djnz process_pair
    halt

จดหมายปัจจุบันจัดขึ้นในทะเบียน A เนื่องจากการเพิ่มขึ้นนั้นเหมาะกับตอนเริ่มของลูปเราจึงโหลดน้อยกว่าค่าเริ่มต้นจริงของA:

process_pair:
    ld a, 'A'-1
    pop de ; D = bitmask, E = suffix character
process_note:
    inc a
    srl d ; put the current bitmask bit in the carry flag
          ; also sets the zero flag if this is the last note in the pair
    jr nc, skip
    ; Print the note. Note that we need to preserve the zero flag to check it in the
    ; loop condition later.
    rst $38 ; Short encoding of call $0038.
            ; Because the program is so short, the memory in the 0038..8000 range
            ; is filled with zeroes, which happens to be the encoding for a no-op.
            ; The execution will therefore fall-through to the character-print hook.
    push af ; Save the letter on the stack (which will be just to the left of the
            ; unprocessed data) to free up A for printing other characters.
            ; (only 16-bit register pairs can be saved, so we also push the flags)
    ld a, e
    cpl     ; Undo the inversion used to make the execution fall-through the data.
            ; Done again each iteration because it takes less bytes to operate
            ; on the A register.
    rst $38 ; Print the suffix.
    xor a   ; Standard assembly practice of setting a register to zero by XORing it
            ; with itself. Saves a byte over a simple `ld a, 0`.
    rst $38 ; Print a null byte as a separator.
    pop af  ; Restore the current letter from the stack.
skip:
    jr nz, process_note ; If the zero flag (last changed at the srl d) is not set,
                        ; loop once again
    djnz process_pair
    halt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.