Mode 2 Tile Editor (0.35) Copyright (c) 2007 Andrew Owen Description ----------- This program enables you to create up to 256 tiles of 16x16 pixels for use in the Timex hi-color mode (mode 2). A set of sample tiles, converted from NetHack using GIMP and Mac2Spec, is included. Instructions ------------ There are two modes, Editor and Storage. You start in Editor mode. Editor ------ 5 - left 6 - down 7 - up 8 - right 0 - plot I - rotate INK bit P - rotate PAPER bit B - toggle BRIGHT bit F - toggle FLASH bit M - horizontal mirror V - vertical mirror N - invert T - switch to Storage mode Storage ------- The screen will switch to normal mode in order to display the cursor. A line of text will tell you if you are 'viewing bank 1' (tiles 0-127) or 2 (128-255). 5 - left 6 - down 7 - up 8 - right P - put a tile into the current bank G - get a tile from the current bank B - switch bank S - save tiles (0-255) in a 16K file L - load tiles X - switch to Editor mode File Format ----------- Tiles are saved as 32 bytes of bitmap data followed by 32 bytes of attribute data. The file saved is a 16K file containing 256 tiles. If you want N tiles, just LOAD it in at address A and SAVE it as f$ CODE A,(N*64). Source ------ For the BASIC just BREAK into the program. The machine code follows. You should be able to adapt the code to write your own game display routines. It's not pretty, but it works. ; ------------------------ ; TIMEX MODE 2 TILE EDITOR ; ------------------------ ; Copyright (c) 2007 Andrew Owen ; Last update: Friday 12 January 2007 ; TM2TE is a collection of routines to be used for displaying and editing 16x16 ; pixel tiles for use with TS2068 display compatible computers ; ; RANDOMIZE USR 46000 ; copy tiles 0-127 to screen ; 46003 ; copy tiles 128-255 to screen ; 46010 ; copy screen to tiles 0-127 ; 46006 ; copy screen to tiles 128-255 ; 46128 ; copy working tile bitmap to zoom view ; 46608 ; copy working tile attributes to zoom view ; 48000 ; mode 2 cls ; 48100 ; move start of basic past 2nd screen area (use once) ; ---------------- ; COPY TILE BLOCKS ; ---------------- ; ; This routine copies the contents of the screen to one of the two block areas ; or the contents of one of the two block areas to the screen. ; four entry points org 46000 scr_to_bl1: xor a ; copying to the screen jr _1st_128 ; first 128 tiles scr_to_bl2: xor a ; copying to the screen jr _2nd_128 ; second 128 tiles bl2_to_scr: ld a,1 ; copying from the screen jr _2nd_128 ; second 128 tiles bl1_to_scr: ld a,1 ; copying from the screen _1st_128: ld de,49152 ; first 128 tiles jr cpstart ; to start _2nd_128: ld de,57344 ; second 128 tiles cpstart: ld hl,18432 ; 18432 (start on screen) ; // copy 8K of data // cp8k: call cp4k ; copy first screen third ld bc,$0700 ; offset add hl,bc ; point to second screen third call cp4k ; copy second screen third ret ; return ; // copy 4K of data // cp4k: call cp4ka ; copy 4k of data cp4ka: ; without using the call cp1k ; alternate register call cp1k ; set as a counter ret ; return ; // copy 1K of data // cp1k: call cp1ka ; 16 nested calls to cp64bytes ld bc,$0020 ; offset add hl,bc ; ret ; return cp1ka: call cp1kb ; 16 nested calls cp1kb: ; to cp64bytes call cp1kc ; avoids the use of cp1kc: ; the alternate register call cp1kd ; set cp1kd: ; call cp64bytes ; call cp64bytes ; ret ; return ; // copy 64 bytes // cp64bytes: call cp32bytes ; copy bitmap ld bc,$17e0 ; offset add hl,bc ; call cp32bytes ; copy attributes ld bc,$281e ; offset sbc hl,bc ; point to next bitmap ret ; return ; // copy 32 bytes // cp32bytes: call cp16bytes ; copy first character row ld bc,$07e0 ; subtract 1761 from hl sbc hl,bc ; point hl at next character row call cp16bytes ; copy second character row ret ; return ; // copy 16 bytes // cp16bytes: call cp16bytes_a ; eight nested calls cp16bytes_a: ; to cp2bytes avoids call cp16bytes_b ; the use of the cp16bytes_b: ; alternate register call cp2bytes ; set call cp2bytes ; ret ; return ; // copy 2 bytes // cp2bytes: cp 0 ; test for copying to the screen jr nz,cp2b_a ; ex de,hl ; used to copy block to screen ; (skip for screen to block) cp2b_a: ldi ; copy contents of hl to (de) ; increment both pointers ldi ; copy contents of hl to (de) ; increment both pointers cp 0 ; test for copying to the screen jr nz,cp2b_b ; ex de,hl ; used to copy block to screen ; (skip for screen to block) cp2b_b: dec hl ; increment hl by 254 dec hl ; inc h ; ret ; return ; ----------- ; ZOOM BITMAP ; ----------- ; ; perform a 4x zoom on a tile bitmap org 46128 zoom_bitmap: ld hl,$4008 ; 1st byte call expand_byte ; ld hl,$4000 ; call plot_row ; ld l,$4009 ; 2nd byte call expand_byte ; ld hl,$4004 ; call plot_row ; ld hl,$4108 ; 3rd byte call expand_byte ; ld hl,$4400 ; call plot_row ; ld hl,$4109 ; 4th byte call expand_byte ; ld hl,$4404 ; call plot_row ; ld hl,$4208 ; 5th byte call expand_byte ; ld hl,$4020 ; call plot_row ; ld hl,$4209 ; 6th byte call expand_byte ; ld hl,$4024 ; call plot_row ; ld hl,$4308 ; 7th byte call expand_byte ; ld hl,$4420 ; call plot_row ; ld hl,$4309 ; 8th byte call expand_byte ; ld hl,$4424 ; call plot_row ; ld hl,$4408 ; 9th byte call expand_byte ; ld hl,$4040 ; call plot_row ; ld hl,$4409 ; 10th byte call expand_byte ; ld hl,$4044 ; call plot_row ; ld hl,$4508 ; 11th byte call expand_byte ; ld hl,$4440 ; call plot_row ; ld hl,$4509 ; 12th byte call expand_byte ; ld hl,$4444 ; call plot_row ; ld hl,$4608 ; 13th byte call expand_byte ; ld hl,$4060 ; call plot_row ; ld hl,$4609 ; 14th byte call expand_byte ; ld hl,$4064 ; call plot_row ; ld hl,$4708 ; 15th byte call expand_byte ; ld hl,$4460 ; call plot_row ; ld hl,$4709 ; 16th byte call expand_byte ; ld hl,$4464 ; call plot_row ; ld hl,$4028 ; 17th byte call expand_byte ; ld hl,$4080 ; call plot_row ; ld hl,$4029 ; 18th byte call expand_byte ; ld hl,$4084 ; call plot_row ; ld hl,$4128 ; 19th byte call expand_byte ; ld hl,$4480 ; call plot_row ; ld hl,$4129 ; 20th byte call expand_byte ; ld hl,$4484 ; call plot_row ; ld hl,$4228 ; 21st byte call expand_byte ; ld hl,$40A0 ; call plot_row ; ld hl,$4229 ; 22nd byte call expand_byte ; ld hl,$40A4 ; call plot_row ; ld hl,$4328 ; 23rd byte call expand_byte ; ld hl,$44A0 ; call plot_row ; ld hl,$4329 ; 24th byte call expand_byte ; ld hl,$44A4 ; call plot_row ; ld hl,$4428 ; 25th byte call expand_byte ; ld hl,$40C0 ; call plot_row ; ld hl,$4429 ; 26th byte call expand_byte ; ld hl,$40C4 ; call plot_row ; ld hl,$4528 ; 27th byte call expand_byte ; ld hl,$44C0 ; call plot_row ; ld hl,$4529 ; 28th byte call expand_byte ; ld hl,$44C4 ; call plot_row ; ld hl,$4628 ; 29th byte call expand_byte ; ld hl,$40E0 ; call plot_row ; ld hl,$4629 ; 30th byte call expand_byte ; ld hl,$40E4 ; call plot_row ; ld hl,$4728 ; 31st byte call expand_byte ; ld hl,$44E0 ; call plot_row ; ld hl,$4729 ; 32nd byte call expand_byte ; ld hl,$44E4 ; call plot_row ; ret ; return expand_byte: ld b,(hl) ; expand the contents of a single byte xor a ; to fill the b, c, d, and e registers bit_0: bit 0,b ; jr z,bit_1 ; e.g. %10110100 = $F0 $FF $0F $00 add a,$0F ; bit_1: bit 1,b ; jr z,bit_2 ; add a,$F0 ; bit_2: ld e,a ; xor a ; bit 2,b ; jr z,bit_3 ; add a,$0F ; bit_3: bit 3,b ; jr z,bit_4 ; add a,$F0 ; bit_4: ld d,a ; xor a ; bit 4,b ; jr z,bit_5 ; add a,$0F ; bit_5: bit 5,b ; jr z,bit_6 ; add a,$F0 ; bit_6: ld c,a ; xor a ; bit 6,b ; jr z,bit_7 ; add a,$0F ; bit_7: bit 7,b ; jr z,bit_x ; add a,$F0 ; bit_x: ld b,a ; ret ; return plot_row: ld (hl),b ; write the contents of the expanded inc h ; byte held in the b, c, d, and e ld (hl),b ; registers to four screen rows inc h ; ld (hl),b ; inc h ; ld (hl),b ; inc l ; ld (hl),c ; dec h ; ld (hl),c ; dec h ; ld (hl),c ; dec h ; ld (hl),c ; inc l ; ld (hl),d ; inc h ; ld (hl),d ; inc h ; ld (hl),d ; inc h ; ld (hl),d ; inc l ; ld (hl),e ; dec h ; ld (hl),e ; dec h ; ld (hl),e ; dec h ; ld (hl),e ; ret ; return ; --------------- ; ZOOM ATTRIBUTES ; --------------- ; ; perform a 4x zoom on a tile's attributes org 46608 zoom_attributes: ld a,($6008) ; 1st byte ld hl,$6000 ; call colour_row ; ld a,($6009) ; 2nd byte ld hl,$6004 ; call colour_row ; ld a,($6108) ; 3rd byte ld hl,$6400 ; call colour_row ; ld a,($6109) ; 4th byte ld hl,$6404 ; call colour_row ; ld a,($6208) ; 5th byte ld hl,$6020 ; call colour_row ; ld a,($6209) ; 6th byte ld hl,$6024 ; call colour_row ; ld a,($6308) ; 7th byte ld hl,$6420 ; call colour_row ; ld a,($6309) ; 8th byte ld hl,$6424 ; call colour_row ; ld a,($6408) ; 9th byte ld hl,$6040 ; call colour_row ; ld a,($6409) ; 10th byte ld hl,$6044 ; call colour_row ; ld a,($6508) ; 11th byte ld hl,$6440 ; call colour_row ; ld a,($6509) ; 12th byte ld hl,$6444 ; call colour_row ; ld a,($6608) ; 13th byte ld hl,$6060 ; call colour_row ; ld a,($6609) ; 14th byte ld hl,$6064 ; call colour_row ; ld a,($6708) ; 15th byte ld hl,$6460 ; call colour_row ; ld a,($6709) ; 16th byte ld hl,$6464 ; call colour_row ; ld a,($6028) ; 17th byte ld hl,$6080 ; call colour_row ; ld a,($6029) ; 18th byte ld hl,$6084 ; call colour_row ; ld a,($6128) ; 19th byte ld hl,$6480 ; call colour_row ; ld a,($6129) ; 20th byte ld hl,$6484 ; call colour_row ; ld a,($6228) ; 21st byte ld hl,$60A0 ; call colour_row ; ld a,($6229) ; 22nd byte ld hl,$60A4 ; call colour_row ; ld a,($6328) ; 23rd byte ld hl,$64A0 ; call colour_row ; ld a,($6329) ; 24th byte ld hl,$64A4 ; call colour_row ; ld a,($6428) ; 25th byte ld hl,$60C0 ; call colour_row ; ld a,($6429) ; 26th byte ld hl,$60C4 ; call colour_row ; ld a,($6528) ; 27th byte ld hl,$64C0 ; call colour_row ; ld a,($6529) ; 28th byte ld hl,$64C4 ; call colour_row ; ld a,($6628) ; 29th byte ld hl,$60E0 ; call colour_row ; ld a,($6629) ; 30th byte ld hl,$60E4 ; call colour_row ; ld a,($6728) ; 31st byte ld hl,$64E0 ; call colour_row ; ld a,($6729) ; 32nd byte ld hl,$64E4 ; call colour_row ; ret ; return colour_row: ld (hl),a ; write the contents of the inc h ; attribute byte held in the a ld (hl),a ; register to four screen rows inc h ; ld (hl),a ; inc h ; ld (hl),a ; inc l ; ld (hl),a ; dec h ; ld (hl),a ; dec h ; ld (hl),a ; dec h ; ld (hl),a ; inc l ; ld (hl),a ; inc h ; ld (hl),a ; inc h ; ld (hl),a ; inc h ; ld (hl),a ; inc l ; ld (hl),a ; dec h ; ld (hl),a ; dec h ; ld (hl),a ; dec h ; ld (hl),a ; ret ; return ; ----------- ; MIRROR TILE ; ----------- ; ; mirror a tile org 47500 mirror_bitmap: ld a,($4008) ; 1st pair call mirror_byte ; ld b,a ; ld a,($4009) ; call mirror_byte ; ld c,a ; ld ($4008),bc ; ld a,($4108) ; 2nd pair call mirror_byte ; ld b,a ; ld a,($4109) ; call mirror_byte ; ld c,a ; ld ($4108),bc ; ld a,($4208) ; 3rd pair call mirror_byte ; ld b,a ; ld a,($4209) ; call mirror_byte ; ld c,a ; ld ($4208),bc ; ld a,($4308) ; 4th pair call mirror_byte ; ld b,a ; ld a,($4309) ; call mirror_byte ; ld c,a ; ld ($4308),bc ; ld a,($4408) ; 5th pair call mirror_byte ; ld b,a ; ld a,($4409) ; call mirror_byte ; ld c,a ; ld ($4408),bc ; ld a,($4508) ; 6th pair call mirror_byte ; ld b,a ; ld a,($4509) ; call mirror_byte ; ld c,a ; ld ($4508),bc ; ld a,($4608) ; 7th pair call mirror_byte ; ld b,a ; ld a,($4609) ; call mirror_byte ; ld c,a ; ld ($4608),bc ; ld a,($4708) ; 8th pair call mirror_byte ; ld b,a ; ld a,($4709) ; call mirror_byte ; ld c,a ; ld ($4708),bc ; ld a,($4028) ; 9th pair call mirror_byte ; ld b,a ; ld a,($4029) ; call mirror_byte ; ld c,a ; ld ($4028),bc ; ld a,($4128) ; 10th pair call mirror_byte ; ld b,a ; ld a,($4129) ; call mirror_byte ; ld c,a ; ld ($4128),bc ; ld a,($4228) ; 11th pair call mirror_byte ; ld b,a ; ld a,($4229) ; call mirror_byte ; ld c,a ; ld ($4228),bc ; ld a,($4328) ; 12th pair call mirror_byte ; ld b,a ; ld a,($4329) ; call mirror_byte ; ld c,a ; ld ($4328),bc ; ld a,($4428) ; 13th pair call mirror_byte ; ld b,a ; ld a,($4429) ; call mirror_byte ; ld c,a ; ld ($4428),bc ; ld a,($4528) ; 14th pair call mirror_byte ; ld b,a ; ld a,($4529) ; call mirror_byte ; ld c,a ; ld ($4528),bc ; ld a,($4628) ; 15th pair call mirror_byte ; ld b,a ; ld a,($4629) ; call mirror_byte ; ld c,a ; ld ($4628),bc ; ld a,($4728) ; 16th pair call mirror_byte ; ld b,a ; ld a,($4729) ; call mirror_byte ; ld c,a ; ld ($4728),bc ; mirror_attributes: ld a,($6008) ; 1st pair ld b,a ; ld a,($6009) ; ld c,a ; ld ($6008),bc ; ld a,($6108) ; 2nd pair ld b,a ; ld a,($6109) ; ld c,a ; ld ($6108),bc ; ld a,($6208) ; 3rd pair ld b,a ; ld a,($6209) ; ld c,a ; ld ($6208),bc ; ld a,($6308) ; 4th pair ld b,a ; ld a,($6309) ; ld c,a ; ld ($6308),bc ; ld a,($6408) ; 5th pair ld b,a ; ld a,($6409) ; ld c,a ; ld ($6408),bc ; ld a,($6508) ; 6th pair ld b,a ; ld a,($6509) ; ld c,a ; ld ($6508),bc ; ld a,($6608) ; 7th pair ld b,a ; ld a,($6609) ; ld c,a ; ld ($6608),bc ; ld a,($6708) ; 8th pair ld b,a ; ld a,($6709) ; ld c,a ; ld ($6708),bc ; ld a,($6028) ; 9th pair ld b,a ; ld a,($6029) ; ld c,a ; ld ($6028),bc ; ld a,($6128) ; 10th pair ld b,a ; ld a,($6129) ; ld c,a ; ld ($6128),bc ; ld a,($6228) ; 11th pair ld b,a ; ld a,($6229) ; ld c,a ; ld ($6228),bc ; ld a,($6328) ; 12th pair ld b,a ; ld a,($6329) ; ld c,a ; ld ($6328),bc ; ld a,($6428) ; 13th pair ld b,a ; ld a,($6429) ; ld c,a ; ld ($6428),bc ; ld a,($6528) ; 14th pair ld b,a ; ld a,($6529) ; ld c,a ; ld ($6528),bc ; ld a,($6628) ; 15th pair ld b,a ; ld a,($6629) ; ld c,a ; ld ($6628),bc ; ld a,($6728) ; 16th pair ld b,a ; ld a,($6729) ; ld c,a ; ld ($6728),bc ; call zoom_bitmap ; call zoom_attributes ; ret ; return mirror_byte: ld de,$0000 ; ld e,a ; ld hl,mirror_tbl ; add hl,de ; ld a,(hl) ; ret ; ; ---------- ; MODE 2 CLS ; ---------- ; ; Clear both screen areas in mode 2 without altering low res attribute area org 48000 m2cls: xor a ; set a to zero ld hl,$4000 ; first byte of screen one ld de,$4001 ; second byte of screen one call m2cls_2 ; repeated bytes ld a,$07 ; set attributes to white on black ld hl,$6000 ; first byte of screen two ld de,$6001 ; second byte of screen two m2cls_2: ld (hl),a ; clear first byte ld bc,$17FF ; 6133 remaining bytes to clear ldir ; wipe screen ret ; done ; ------------- ; MOVE CHANNELS ; ------------- ; ; This routine ensures that BASIC and channels are not competing with the second ; screen area. org 48100 m_chan: ld hl,$7800 ; first address after second screen area ld de,($5C4F) ; current start of channel data (chans) sbc hl,de ; calculate how much to add ld b,h ; transfer result to BC ld c,l ; ex de,hl ; start of channel data to HL jp $1655 ; exit via make_room routine ; ------------------------------------------------------------------------------ ; DATA follows after CODE defm "**end of code**" ; ------------ ; MIRROR TABLE ; ------------ ; ; A 256 byte lookup table to mirror the bitmap contained in a single byte org 48896 mirror_tbl: defb $00,$80,$40,$C0,$20,$A0,$60,$E0,$10,$90,$50,$D0,$30,$B0,$70,$F0 defb $08,$88,$48,$C8,$28,$A8,$68,$E8,$18,$98,$58,$D8,$38,$B8,$78,$F8 defb $04,$84,$44,$C4,$24,$A4,$64,$E4,$14,$94,$54,$D4,$34,$B4,$74,$F4 defb $0C,$8C,$4C,$CC,$2C,$AC,$6C,$EC,$1C,$9C,$5C,$DC,$3C,$BC,$7C,$FC defb $02,$82,$42,$C2,$22,$A2,$62,$E2,$12,$92,$52,$D2,$32,$B2,$72,$F2 defb $0A,$8A,$4A,$CA,$2A,$AA,$6A,$EA,$1A,$9A,$5A,$DA,$3A,$BA,$7A,$FA defb $06,$86,$46,$C6,$26,$A6,$66,$E6,$16,$96,$56,$D6,$36,$B6,$76,$F6 defb $0E,$8E,$4E,$CE,$2E,$AE,$6E,$EE,$1E,$9E,$5E,$DE,$3E,$BE,$7E,$FE defb $01,$81,$41,$C1,$21,$A1,$61,$E1,$11,$91,$51,$D1,$31,$B1,$71,$F1 defb $09,$89,$49,$C9,$29,$A9,$69,$E9,$19,$99,$59,$D9,$39,$B9,$79,$F9 defb $05,$85,$45,$C5,$25,$A5,$65,$81,$15,$95,$55,$D5,$35,$B5,$75,$F5 defb $0D,$8D,$4D,$CD,$2D,$AD,$6D,$ED,$1D,$9D,$5D,$DD,$3D,$BD,$7D,$FD defb $03,$83,$43,$C3,$23,$A3,$63,$E3,$13,$93,$53,$D3,$33,$B3,$73,$F3 defb $0B,$8B,$4B,$CB,$2B,$AB,$6B,$EB,$1B,$9B,$5B,$DB,$3B,$BB,$7B,$FB defb $07,$87,$47,$C7,$27,$A7,$67,$E7,$17,$97,$57,$D7,$37,$B7,$77,$F7 defb $0F,$8F,$4F,$CF,$2F,$AF,$6F,$EF,$1F,$9F,$5F,$DF,$3F,$BF,$7F,$FF