diff --git a/chiptune_debug/Makefile b/chiptune_debug/Makefile new file mode 100644 index 00000000..f4a51d18 --- /dev/null +++ b/chiptune_debug/Makefile @@ -0,0 +1,36 @@ +include ../Makefile.inc + +DOS33 = ../dos33fs-utils/dos33 +PNG2GR = ../gr-utils/png2gr + +all: chiptune_debug.dsk + +chiptune_debug.dsk: CHIPTUNE_IRQ CHIPTUNE_NOIRQ ./sdemo.raw + cp chiptune_empty.dsk chiptune_debug.dsk + $(DOS33) -y chiptune_debug.dsk BSAVE -a 0x0C00 CHIPTUNE_IRQ + $(DOS33) -y chiptune_debug.dsk BSAVE -a 0x0C00 CHIPTUNE_NOIRQ + + +CHIPTUNE_IRQ: chiptune_irq.o + ld65 -o CHIPTUNE_IRQ chiptune_irq.o -C ../linker_scripts/apple2_c00.inc + +chiptune_irq.o: chiptune_player.s \ + mockingboard_a.s \ + interrupt_handler.s \ + zp.inc + ca65 -o chiptune_irq.o chiptune_player.s -l chiptune_irq.lst + +CHIPTUNE_NOIRQ: chiptune_noirq.o + ld65 -o CHIPTUNE_NOIRQ chiptune_noirq.o -C ../linker_scripts/apple2_c00.inc + +chiptune_noirq.o: chiptune_player.s \ + mockingboard_a.s \ + interrupt_handler.s \ + zp.inc + ca65 -D NOIRQ=1 -o chiptune_noirq.o chiptune_player.s -l chiptune_noirq.lst + + +clean: + rm -f *~ TITLE.GR *.o *.lst \ + CHIPTUNE_PLAYER CHIPTUNE_IRQ CHIPTUNE_NOIRQ + diff --git a/chiptune_debug/NOTES b/chiptune_debug/NOTES new file mode 100644 index 00000000..dee528be --- /dev/null +++ b/chiptune_debug/NOTES @@ -0,0 +1,19 @@ +note: pausing writes out zeros, doesn't restore previous values + which is noticable + + +doubling length of writes: still issue +removing rasterbars: still issue +removing volume bars: still issue +remove time update: still issue +remove dead code: still issue +remove title screen: still issue +remove all graphics calls: still issue +remove memory shuffling in back:still issue +remove keyboard: still issue +remove all non-irq code: still issue +remove all text print code still issue +remove multi file (down to 973) still issue +remove dos33 code still issue +remove lz4 code still issue +remove interrupt driven still issue!? diff --git a/chiptune_debug/chiptune_empty.dsk b/chiptune_debug/chiptune_empty.dsk new file mode 100644 index 00000000..e3e24182 Binary files /dev/null and b/chiptune_debug/chiptune_empty.dsk differ diff --git a/chiptune_debug/chiptune_player.s b/chiptune_debug/chiptune_player.s new file mode 100644 index 00000000..61d6f90d --- /dev/null +++ b/chiptune_debug/chiptune_player.s @@ -0,0 +1,134 @@ +; VMW Chiptune Player + +.include "zp.inc" + + ;============================= + ; Setup + ;============================= + + ; init variables + + lda #0 + sta DONE_PLAYING + sta MB_CHUNK_OFFSET + + jsr mockingboard_detect_slot4 ; call detection routine + + ;============================ + ; Init the Mockingboard + ;============================ + + jsr mockingboard_init + jsr reset_ay_both + jsr clear_ay_both + + ;========================= + ; Setup Interrupt Handler + ;========================= + ; Vector address goes to 0x3fe/0x3ff + ; FIXME: should chain any existing handler + +.ifdef NOIRQ +.else + lda #interrupt_handler + sta $03ff +.endif + + ;============================ + ; Enable 50Hz clock on 6522 + ;============================ +.ifdef NOIRQ +.else + sei ; disable interrupts just in case + + lda #$40 ; Continuous interrupts, don't touch PB7 + sta $C40B ; ACR register + lda #$7F ; clear all interrupt flags + sta $C40E ; IER register (interrupt enable) + + lda #$C0 + sta $C40D ; IFR: 1100, enable interrupt on timer one oflow + sta $C40E ; IER: 1100, enable timer one interrupt + + lda #$E7 + sta $C404 ; write into low-order latch + lda #$4f + sta $C405 ; write into high-order latch, + ; load both values into counter + ; clear interrupt and start counting + + ; 4fe7 / 1e6 = .020s, 50Hz +.endif + + ;================== + ; load first song + ;================== + + jsr new_song + + ;============================ + ; Enable 6502 interrupts + ;============================ + +.ifdef NOIRQ +.else + cli ; clear interrupt mask +.endif + + ;============================ + ; Loop forever + ;============================ +main_loop: + +.ifdef NOIRQ + jsr interrupt_handler + + lda #85 + jsr WAIT ; wait 20ms-xms +.else +.endif + jmp main_loop + + + ;================= + ; load a new song + ;================= + +new_song: + + ;========================= + ; Init Variables + ;========================= + + lda #$0 + sta MB_CHUNK_OFFSET + lda #3 + sta CHUNKSIZE + + ;=========================== + ; Load in KRW file + ;=========================== + + lda #UNPACK_BUFFER + sta INH + + ; Decompress first chunks + + lda #$3 + sta CHUNKSIZE + + rts + +;========= +;routines +;========= +.include "mockingboard_a.s" +.include "interrupt_handler.s" + +.align 256 +UNPACK_BUFFER: +.incbin "sdemo.raw" diff --git a/chiptune_debug/interrupt_handler.s b/chiptune_debug/interrupt_handler.s new file mode 100644 index 00000000..8c30f67d --- /dev/null +++ b/chiptune_debug/interrupt_handler.s @@ -0,0 +1,164 @@ + ;================================ + ;================================ + ; mockingboard interrupt handler + ;================================ + ;================================ + +interrupt_handler: + pha ; save A ; 3 + ; Should we save X and Y too? + +.ifdef NOIRQ +.else + bit $C404 ; clear 6522 interrupt by reading T1C-L ; 4 +.endif + +mb_play_music: + + + ;====================================== + ; Write frames to Mockingboard + ;====================================== + ; actually plays frame loaded at end of + ; last interrupt, so 20ms behind? + +mb_write_frame: + + + ldx #0 ; set up reg count ; 2 + ;============ + ; 2 + + ;================================== + ; loop through the 14 registers + ; reading the value, then write out + ;================================== + ; inlined "write_ay_both" to save up to 156 (12*13) cycles + ; unrolled + +mb_write_loop: + lda REGISTER_DUMP,X ; load register value ; 4 + cmp REGISTER_OLD,X ; compare with old values ; 4 + beq mb_no_write ; 3/2nt + ;============= + ; typ 11 + + ; special case R13. If it is 0xff, then don't update + ; otherwise might spuriously reset the envelope settings + + cpx #13 ; 2 + bne mb_not_13 ; 3/2nt + cmp #$ff ; 2 + beq mb_skip_13 ; 3/2nt + ;============ + ; typ 5 +mb_not_13: + + + ; address + stx MOCK_6522_ORA1 ; put address on PA1 ; 4 + stx MOCK_6522_ORA2 ; put address on PA2 ; 4 + lda #MOCK_AY_LATCH_ADDR ; latch_address for PB1 ; 2 + sta MOCK_6522_ORB1 ; latch_address on PB1 ; 4 + sta MOCK_6522_ORB2 ; latch_address on PB2 ; 4 + lda #MOCK_AY_INACTIVE ; go inactive ; 2 + sta MOCK_6522_ORB1 ; 4 + sta MOCK_6522_ORB2 ; 4 + + ; value + lda REGISTER_DUMP,X ; load register value ; 4 + sta MOCK_6522_ORA1 ; put value on PA1 ; 4 + sta MOCK_6522_ORA2 ; put value on PA2 ; 4 + lda #MOCK_AY_WRITE ; ; 2 + sta MOCK_6522_ORB1 ; write on PB1 ; 4 + sta MOCK_6522_ORB2 ; write on PB2 ; 4 + lda #MOCK_AY_INACTIVE ; go inactive ; 2 + sta MOCK_6522_ORB1 ; 4 + sta MOCK_6522_ORB2 ; 4 + ;=========== + ; 62 +mb_no_write: + inx ; point to next register ; 2 + cpx #14 ; if 14 we're done ; 2 + bmi mb_write_loop ; otherwise, loop ; 3/2nt + ;============ + ; 7 +mb_skip_13: + + + ;===================================== + ; Copy registers to old + ;===================================== + ldx #13 ; 2 +mb_reg_copy: + lda REGISTER_DUMP,X ; load register value ; 4 + sta REGISTER_OLD,X ; compare with old values ; 4 + dex ; 2 + bpl mb_reg_copy ; 2nt/3 + ;============= + ; 171 + + ;=================================== + ; Load all 14 registers in advance + ;=================================== + ; note, assuming not cross page boundary, not any slower + ; then loading from zero page? + +mb_load_values: + + ldx #0 ; set up reg count ; 2 + ldy MB_CHUNK_OFFSET ; get chunk offset ; 3 + ;============= + ; 5 + +mb_load_loop: + lda (INL),y ; load register value ; 5 + sta REGISTER_DUMP,X ; 4 + ;============ + ; 9 + ;==================== + ; point to next page + ;==================== + + clc ; point to next interleaved ; 2 + lda INH ; page by adding CHUNKSIZE (3/1); 3 + adc CHUNKSIZE ; 3 + sta INH ; 3 + + inx ; point to next register ; 2 + cpx #14 ; if 14 we're done ; 2 + bmi mb_load_loop ; otherwise, loop ; 3/2nt + ;============ + ; 18 + + + + ;============================================== + ; incremement offset. If 0 move to next chunk + ;============================================== + +increment_offset: + + inc MB_CHUNK_OFFSET ; increment offset ; 5 + + lda #0 ; 2 + clc ; 2 + adc #>UNPACK_BUFFER ; in proper chunk 1 or 2 ; 2 + sta INH ; update r0 pointer ; 3 + + + + ;================================= + ; Finally done with this interrupt + ;================================= + +done_interrupt: + pla ; restore a ; 4 +.ifdef NOIRQ + rts +.else + rti ; return from interrupt ; 6 +.endif + +REGISTER_OLD: + .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0 diff --git a/chiptune_debug/mockingboard_a.s b/chiptune_debug/mockingboard_a.s new file mode 100644 index 00000000..926bb29c --- /dev/null +++ b/chiptune_debug/mockingboard_a.s @@ -0,0 +1,144 @@ +; left speaker +MOCK_6522_ORB1 EQU $C400 ; 6522 #1 port b data +MOCK_6522_ORA1 EQU $C401 ; 6522 #1 port a data +MOCK_6522_DDRB1 EQU $C402 ; 6522 #1 data direction port B +MOCK_6522_DDRA1 EQU $C403 ; 6522 #1 data direction port A + +; right speaker +MOCK_6522_ORB2 EQU $C480 ; 6522 #2 port b data +MOCK_6522_ORA2 EQU $C481 ; 6522 #2 port a data +MOCK_6522_DDRB2 EQU $C482 ; 6522 #2 data direction port B +MOCK_6522_DDRA2 EQU $C483 ; 6522 #2 data direction port A + +; AY-3-8910 commands on port B +; RESET BDIR BC1 +MOCK_AY_RESET EQU $0 ; 0 0 0 +MOCK_AY_INACTIVE EQU $4 ; 1 0 0 +MOCK_AY_READ EQU $5 ; 1 0 1 +MOCK_AY_WRITE EQU $6 ; 1 1 0 +MOCK_AY_LATCH_ADDR EQU $7 ; 1 1 1 + + + ;======================== + ; Mockingboard Init + ;======================== + ; Initialize the 6522s + ; set the data direction for all pins of PortA/PortB to be output + +mockingboard_init: + lda #$ff ; all output (1) + sta MOCK_6522_DDRB1 + sta MOCK_6522_DDRA1 + sta MOCK_6522_DDRB2 + sta MOCK_6522_DDRA2 + rts + + ;====================== + ; Reset Left AY-3-8910 + ;====================== +reset_ay_both: + lda #MOCK_AY_RESET + sta MOCK_6522_ORB1 + lda #MOCK_AY_INACTIVE + sta MOCK_6522_ORB1 + + ;====================== + ; Reset Right AY-3-8910 + ;====================== +;reset_ay_right: + lda #MOCK_AY_RESET + sta MOCK_6522_ORB2 + lda #MOCK_AY_INACTIVE + sta MOCK_6522_ORB2 + rts + + +; Write sequence +; Inactive -> Latch Address -> Inactive -> Write Data -> Inactive + + ;========================================= + ; Write Right/Left to save value AY-3-8910 + ;========================================= + ; register in X + ; value in MB_VALUE + +write_ay_both: + ; address + stx MOCK_6522_ORA1 ; put address on PA1 ; 3 + stx MOCK_6522_ORA2 ; put address on PA2 ; 3 + lda #MOCK_AY_LATCH_ADDR ; latch_address on PB1 ; 2 + sta MOCK_6522_ORB1 ; latch_address on PB1 ; 3 + sta MOCK_6522_ORB2 ; latch_address on PB2 ; 3 + lda #MOCK_AY_INACTIVE ; go inactive ; 2 + sta MOCK_6522_ORB1 ; 3 + sta MOCK_6522_ORB2 ; 3 + + ; value + lda MB_VALUE ; 3 + sta MOCK_6522_ORA1 ; put value on PA1 ; 3 + sta MOCK_6522_ORA2 ; put value on PA2 ; 3 + lda #MOCK_AY_WRITE ; ; 2 + sta MOCK_6522_ORB1 ; write on PB1 ; 3 + sta MOCK_6522_ORB2 ; write on PB2 ; 3 + lda #MOCK_AY_INACTIVE ; go inactive ; 2 + sta MOCK_6522_ORB1 ; 3 + sta MOCK_6522_ORB2 ; 3 + + rts ; 6 + ;=========== + ; 53 + ;======================================= + ; clear ay -- clear all 14 AY registers + ; should silence the card + ;======================================= +clear_ay_both: + ldx #14 + lda #0 + sta MB_VALUE +clear_ay_left_loop: + jsr write_ay_both + dex + bpl clear_ay_left_loop + rts + + + + ;======================================= + ; Detect a Mockingboard card in Slot4 + ;======================================= + ; Based on code from the French Touch "Pure Noise" Demo + ; Attempts to time an instruction sequence with a 6522 + ; + ; MB_ADDRL:MB_ADDRH has address of Mockingboard + ; returns X=0 if not found, X=1 if found + +mockingboard_detect_slot4: + lda #0 + sta MB_ADDRL + +mb4_detect_loop: ; self-modifying + lda #$04 ; we're only looking in Slot 4 + ora #$C0 ; make it start with C + sta MB_ADDRH + ldy #04 ; $CX04 + ldx #02 ; 2 tries? +mb4_check_cycle_loop: + lda (MB_ADDRL),Y ; timer 6522 (Low Order Counter) + ; count down + sta TEMP ; 3 cycles + lda (MB_ADDRL),Y ; + 5 cycles = 8 cycles + ; between the two accesses to the timer + sec + sbc TEMP ; subtract to see if we had 8 cycles + cmp #$f8 ; -8 + bne mb4_not_in_this_slot + dex ; decrement, try one more time + bne mb4_check_cycle_loop ; loop detection + inx ; Mockingboard found (X=1) +done_mb4_detect: + rts ; return + +mb4_not_in_this_slot: + ldx #00 + beq done_mb4_detect + diff --git a/chiptune_debug/sdemo.raw b/chiptune_debug/sdemo.raw new file mode 100644 index 00000000..dafe9856 Binary files /dev/null and b/chiptune_debug/sdemo.raw differ diff --git a/chiptune_debug/zp.inc b/chiptune_debug/zp.inc new file mode 100644 index 00000000..fff64073 --- /dev/null +++ b/chiptune_debug/zp.inc @@ -0,0 +1,251 @@ +.define EQU = + +LZ4_SRC EQU $00 +LZ4_DST EQU $02 +LZ4_END EQU $04 +COUNT EQU $06 +DELTA EQU $08 + +;; Zero page monitor routines addresses + +WNDLFT EQU $20 +WNDWDTH EQU $21 +WNDTOP EQU $22 +WNDBTM EQU $23 +CH EQU $24 +CV EQU $25 +GBASL EQU $26 +GBASH EQU $27 +BASL EQU $28 +BASH EQU $29 +H2 EQU $2C +V2 EQU $2D +MASK EQU $2E +COLOR EQU $30 + ;INVFLG EQU $32 + +; dos33 zero page = 26-2f, 35-38, 3e 3f 40-4d +; overlap applesoft 67-6a,6f,70,af,b0,ca-cd,d8 + + +; DOS33: Confirmed kills $68 + +RWTSL EQU $60 +RWTSH EQU $61 +DOSBUFL EQU $62 +DOSBUFH EQU $63 +FILEML EQU $64 +FILEMH EQU $65 + ;TURNING EQU $60 + ;SCREEN_X EQU $61 ; not used? + ;SCREEN_Y EQU $62 + + + ;ANGLE EQU $63 + ;HORIZ_SCALE_I EQU $64 + ;HORIZ_SCALE_F EQU $65 + ;FACTOR_I EQU $66 + ;FACTOR_F EQU $67 + ;DX_I EQU $68 + ;DX_F EQU $69 + ;SPACEX_I EQU $6A + ;SPACEX_F EQU $6B + ;CX_I EQU $6C + ;CX_F EQU $6D + ;DY_I EQU $6E + ;DY_F EQU $6F + +REGISTER_DUMP EQU $70 +A_FINE_TONE EQU $70 +A_COARSE_TONE EQU $71 +B_FINE_TONE EQU $72 +B_COARSE_TONE EQU $73 +C_FINE_TONE EQU $74 +C_COARSE_TONE EQU $75 +NOISE EQU $76 +ENABLE EQU $77 +A_VOLUME EQU $78 +B_VOLUME EQU $79 +C_VOLUME EQU $7A +ENVELOPE_FINE EQU $7B +ENVELOPE_COARSE EQU $7C +ENVELOPE_SHAPE EQU $7D +COPY_OFFSET EQU $7E +DECODER_STATE EQU $7F + ;SPACEY_I EQU $70 + ;SPACEY_F EQU $71 + ;CY_I EQU $72 + ;CY_F EQU $73 + ;TEMP_I EQU $74 + ;TEMP_F EQU $75 + ;DISTANCE_I EQU $76 + ;DISTANCE_F EQU $77 + ;SPACEZ_I EQU $78 + ;SPACEZ_F EQU $79 + ;DRAW_SPLASH EQU $7A + ;SPEED EQU $7B + ;SPLASH_COUNT EQU $7C + ;OVER_LAND EQU $7D + ;NUM1L EQU $7E + ;NUM1H EQU $7F +CHUNKSIZE EQU $80 +LZ4_DONE EQU $81 +DECODE_ERROR EQU $82 + +A_COLOR EQU $83 +B_COLOR EQU $84 +C_COLOR EQU $85 +COPY_TIME EQU $86 +DECOMPRESS_TIME EQU $87 +TIME_TAKEN EQU $88 +SCREEN_Y EQU $89 +WHICH_FILE EQU $8A + ;NUM2L EQU $80 + ;NUM2H EQU $81 + ;RESULT EQU $82 ; 83,84,85 + ;NEGATE EQU $86 ; UNUSED? + ;LAST_SPACEX_I EQU $87 + ;LAST_SPACEY_I EQU $88 + ;LAST_MAP_COLOR EQU $89 + ;DRAW_SKY EQU $8A +COLOR_MASK EQU $8B +RASTERBARS_ON EQU $8C + ;KEY_COUNT EQU $8C + ;KEY_OFFSET EQU $8D + ;DRAW_BLUE_SKY EQU $8E +RANDOM_POINTER EQU $8F +FRAME_COUNT EQU $90 +MB_VALUE EQU $91 +;MB_CHUNK EQU $92 +MB_ADDRL EQU $91 +MB_ADDRH EQU $92 +DONE_PLAYING EQU $93 +;MB_FRAME_DIFF EQU $94 +MB_CHUNK_OFFSET EQU $94 + ;LZSS_RL EQU $95 + ;LZSS_RH EQU $96 + ;LZSS_COUNT EQU $97 + ;LZSS_MASK EQU $98 + ;LZSS_ENDL EQU $99 + ;LZSS_ENDH EQU $9A + ;MB_FRAME_DIFF2 EQU $9F + +; More zero-page addresses +; we try not to conflict with anything DOS, MONITOR or BASIC related + + ;COLOR1 EQU $E0 +COLOR2 EQU $E1 + ;MATCH EQU $E2 +XX EQU $E3 + ;YY EQU $E4 + ;SHIPY EQU $E4 + ;YADD EQU $E5 + ;LOOP EQU $E6 + ;MEMPTRL EQU $E7 + ;MEMPTRH EQU $E8 + ;NAMEL EQU $E9 + ;NAMEH EQU $EA + ;NAMEX EQU $EB + ;CHAR EQU $EC +DISP_PAGE EQU $ED +DRAW_PAGE EQU $EE + + ;FIRST EQU $F0 +LASTKEY EQU $F1 + ;PADDLE_STATUS EQU $F2 +XPOS EQU $F3 +YPOS EQU $F4 +TEMP EQU $FA + ;RUN EQU $FA + ;TEMP2 EQU $FB +TEMPY EQU $FB +INL EQU $FC +INH EQU $FD +OUTL EQU $FE +OUTH EQU $FF + + + +KEYPRESS EQU $C000 +KEYRESET EQU $C010 + +;; SOFT SWITCHES +CLR80COL EQU $C000 ; PAGE0/PAGE1 normal +SET80COL EQU $C001 ; PAGE0/PAGE1 switches PAGE0 in Aux instead +EIGHTYCOL EQU $C00D +SPEAKER EQU $C030 +SET_GR EQU $C050 +SET_TEXT EQU $C051 +FULLGR EQU $C052 +TEXTGR EQU $C053 +PAGE0 EQU $C054 +PAGE1 EQU $C055 +LORES EQU $C056 ; Enable LORES graphics +HIRES EQU $C057 ; Enable HIRES graphics +AN3 EQU $C05E ; Annunciator 3 + +PADDLE_BUTTON0 EQU $C061 +PADDL0 EQU $C064 +PTRIG EQU $C070 + +;; BASIC ROUTINES + +NORMAL EQU $F273 + +;; MONITOR ROUTINES + +HLINE EQU $F819 ;; HLINE Y,$2C at A +VLINE EQU $F828 ;; VLINE A,$2D at Y +CLRSCR EQU $F832 ;; Clear low-res screen +CLRTOP EQU $F836 ;; clear only top of low-res screen +SETCOL EQU $F864 ;; COLOR=A +TEXT EQU $FB36 +TABV EQU $FB5B ;; VTAB to A +BASCALC EQU $FBC1 ;; +VTAB EQU $FC22 ;; VTAB to CV +HOME EQU $FC58 ;; Clear the text screen +WAIT EQU $FCA8 ;; delay 1/2(26+27A+5A^2) us +SETINV EQU $FE80 ;; INVERSE +SETNORM EQU $FE84 ;; NORMAL +COUT EQU $FDED ;; output A to screen +COUT1 EQU $FDF0 ;; output A to screen + + + + + + +COLOR_BLACK EQU 0 +COLOR_RED EQU 1 +COLOR_DARKBLUE EQU 2 +COLOR_PURPLE EQU 3 +COLOR_DARKGREEN EQU 4 +COLOR_GREY EQU 5 +COLOR_MEDIUMBLUE EQU 6 +COLOR_LIGHTBLUE EQU 7 +COLOR_BROWN EQU 8 +COLOR_ORANGE EQU 9 +COLOR_GREY2 EQU 10 +COLOR_PINK EQU 11 +COLOR_LIGHTGREEN EQU 12 +COLOR_YELLOW EQU 13 +COLOR_AQUA EQU 14 +COLOR_WHITE EQU 15 + +COLOR_BOTH_BLACK EQU $00 +COLOR_BOTH_RED EQU $11 +COLOR_BOTH_DARKBLUE EQU $22 +COLOR_BOTH_DARKGREEN EQU $44 +COLOR_BOTH_GREY EQU $55 +COLOR_BOTH_MEDIUMBLUE EQU $66 +COLOR_BOTH_LIGHTBLUE EQU $77 +COLOR_BOTH_BROWN EQU $88 +COLOR_BOTH_ORANGE EQU $99 +COLOR_BOTH_PINK EQU $BB +COLOR_BOTH_LIGHTGREEN EQU $CC +COLOR_BOTH_YELLOW EQU $DD +COLOR_BOTH_AQUA EQU $EE +COLOR_BOTH_WHITE EQU $FF + +AUX_BOTH_MEDIUMBLUE EQU $33 ; 0011 0011 +AUX_BOTH_GREY EQU $AA ; 1010 1010