diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 94ad71a..dbc4bbb 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -18,7 +18,7 @@ https://github.com/inexorabletash/a2d/issues * Add Special > Check Drive command to refresh a single drive. (#97) * Show Text File DA: Keyboard support. Escape quits, arrows scroll. (#4) * Reorganized/renamed several menu items. (#13) -* New icons for graphics, AppleWorks, relocatable, command, IIgs-specific file types, and DAs. (#105) +* New file type icons: graphics, AppleWorks, relocatable, command, IIgs-specific, and DAs. (#105) * Desktop icon shown for AppleTalk file shares. (#88) * Improvements to several existing icon bitmaps. (#74) * Desk accessory files with high bit in aux-type set are hidden in Apple menu. (#102) @@ -50,7 +50,8 @@ functionality (see below). Text and Graphics files with the correct file types can be previewed without leaving DeskTop; select the file icon then select File > Open, or double-click the file icon. Text files must be type TXT ($04). -Graphics files must be type FOT ($08). +Graphics files must be type FOT ($08), or BIN ($06) with an aux type +of $2000 (hi-res/double hi-res) or $5800 (Minipix a.k.a. Print Shop). To preview files of other types, you can copy the preview handlers named `SHOW.TEXT.FILE` and `SHOW.IMAGE.FILE` from the `PREVIEW` folder diff --git a/desktop/desktop_main.s b/desktop/desktop_main.s index 256cbad..c360ff3 100644 --- a/desktop/desktop_main.s +++ b/desktop/desktop_main.s @@ -912,6 +912,9 @@ begin: ;; Check file type. : lda get_file_info_params::file_type + ldxy get_file_info_params::aux_type + jsr check_file_type_overrides + cmp #FT_BASIC bne :+ jsr check_basic_system ; Only launch if BASIC.SYSTEM is found @@ -6640,21 +6643,20 @@ L7767: .byte $14 cmp #FT_BAD ; T$01 is overloaded below for "apps", so beq is_generic ; treat as generic - ;; DA_FILE_TYPE also requires correct AUX type - cmp #DA_FILE_TYPE ; Apple Menu item? - bne :+ + ;; Handle several classes of overrides + pha ; Load auxtype into X,Y ldy #FileRecord::aux_type - lda (file_entry),y ; Must have correct aux type, otherwise - cmp #DA_AUX_TYPE - bne is_generic - lda #DA_FILE_TYPE + lda (file_entry),y ; hi + tay ; hi + pla + tax ; lo + pla + jsr check_file_type_overrides -: cmp #FT_SYSTEM ; Other system? + cmp #FT_SYSTEM ; Other system? bne got_type ; nope ;; Distinguish *.SYSTEM files as apps (use $01) from other @@ -6763,9 +6765,6 @@ L7870: lda cached_window_id jsr icon_window_to_screen add16 file_entry, #icon_y_spacing, file_entry rts - - .byte 0 - .byte 0 .endproc ;;; ============================================================ @@ -6817,6 +6816,60 @@ file_type: create_file_icon_ep2 := create_file_icon::ep1::ep2 create_file_icon_ep1 := create_file_icon::ep1 + +;;; ============================================================ +;;; Check file type for possible overrides +;;; TODO: Make this data driven + +;;; Input: A is filetype, X,Y is auxtype +;;; Output: A is filetype to use + +.proc check_file_type_overrides + stxy auxtype + + ;; Binary - treat certain auxtypes as Graphics + cmp #FT_BINARY + bne :+ + ldxy #$5800 ; minipix + jsr check_aux + beq is_graphics + ldxy #$2000 ; hires + jsr check_aux + beq is_graphics + + ;; DA - treat as generic *unless* auxtypes are correct +: cmp #DA_FILE_TYPE + bne :+ + ldxy #DA_AUX_TYPE + jsr check_aux + beq :+ + ldxy #DA_AUX_TYPE | $8000 + jsr check_aux + bne is_generic + +: rts + +is_generic: + lda #FT_TYPELESS + rts + +is_graphics: + lda #FT_GRAPHICS + rts + +auxtype: + .word 0 + +.proc check_aux + cpx auxtype + bne :+ + cpy auxtype+1 +: rts +.endproc + +.endproc + + ;;; ============================================================ ;;; Draw header (items/k in disk/k available/lines) diff --git a/docs/Tips_And_Tricks.md b/docs/Tips_And_Tricks.md index 44d8546..0699ec1 100644 --- a/docs/Tips_And_Tricks.md +++ b/docs/Tips_And_Tricks.md @@ -2,17 +2,24 @@ ▲ = Solid Apple - # Undiscoverable Features * When dragging a selection of files to a destination on the same volume, the files will be moved by default. Hold down **△** before letting go of the mouse button to force a copy instead. Files dragged to a different volume will always be copied. * Hold down **△** when launching `DESKTOP.SYSTEM` to prevent DeskTop from being copied to a RAM card. -* Desk Accessory files with high bit set in the aux type field will not appear in the Apple menu. +* Desk Accessory files with high bit set in the aux type field ($8640) will not appear in the Apple menu. * You can't run a Binary file by double-clicking, but you can run it with the **△O** shortcut or holding down **△** or **▲** while selecting **File > Open**. * The Sort Directory desk accessory has two modes: * If any files are selected, these are moved to the start of the directory listing, in selection order; other files appear after, order unchanged. * If no files are selected, all files are sorted by type: DIR, then TXT, then SYS, then others in descending numeric order. + +# File Types + +* Binary files (type $06) with aux type $2000 are treated as Graphics files (HR/DHR) +* Binary files (type $06) with aux type $5800 are treated as Graphics files (Minipix/Print Shop) +* Desk Accessory files have type $F1, and auxtype $640 or $8640 + + # Secrets and Mysteries * The Calculator desk accessory has a tiny monogram resembling "JB" drawn in the title bar - possibly "J. Bernard" thanked in the credits? diff --git a/preview/show.image.file.s b/preview/show.image.file.s index 2fb2d87..c98fab6 100644 --- a/preview/show.image.file.s +++ b/preview/show.image.file.s @@ -7,44 +7,95 @@ .include "../desktop.inc" .include "../macros.inc" +;;; ============================================================ +;;; Memory map +;;; +;;; Main Aux +;;; : : : : +;;; | | | | +;;; | DHR | | DHR | +;;; $2000 +-----------+ +-----------+ +;;; | IO Buffer | |Win Tables | +;;; $1C00 +-----------+ | | +;;; $1B00 | | +-----------+ +;;; | | | | +;;; | | | | +;;; | MP Dst | | MP Dst | +;;; $1580 +-----------+ +-----------+ +;;; | | | | +;;; | MP Src | | Menu Save | +;;; $1100 +-----------+ +-----------+ +;;; | | | | +;;; | DA | | DA (Copy) | +;;; $800 +-----------+ +-----------+ +;;; : : : : +;;; + + hires := $2000 ; HR/DHR images are loaded directly into screen buffer + hires_size = $2000 + + ;; Menu bits saved/restored + menu_rows = 13 + menu_cols = 40 + menu_save_area := $1100 ; Past DA code (need $410 bytes) + menu_save_size = menu_cols * 2 * menu_rows ; 5 pages + + ;; Minipix/Print Shop images are loaded/converted + minipix_src_buf = $1200 ; Load address + minipix_src_size = 576 + minipix_dst_buf = $1580 ; Convert address + minipix_dst_size = 26*52 + + .assert (minipix_src_buf + minipix_src_size) < minipix_dst_buf, error, "Not enough room for Minipix load buffer" + .assert (menu_save_area + menu_save_size) < minipix_dst_buf, error, "Not enough room for menu save area" + .assert (minipix_dst_buf + minipix_dst_size) < WINDOW_ICON_TABLES, error, "Not enough room for Minipix convert buffer" + ;;; ============================================================ .org $800 -start: jmp copy2aux +da_start: + jmp start save_stack:.byte 0 -;;; Copy $800 through $13FF (the DA) to aux -.proc copy2aux +.proc start tsx stx save_stack + + ;; Copy DA to AUX + copy16 #da_start, STARTLO + copy16 #da_start, DESTINATIONLO + copy16 #da_end, ENDLO + sec ; main>aux + jsr AUXMOVE + + ;; Transfer control to aux sta RAMWRTON - ldy #0 -src: lda start,y ; self-modified -dst: sta start,y ; self-modified - dey - bne src + sta RAMRDON + + ;; Copy "call_main_template" routine to zero page + COPY_BYTES sizeof_routine+1, routine, call_main_trampoline + + ;; run the DA + jsr init + + ;; tear down/exit + sta ALTZPON + lda LCBANK1 + lda LCBANK1 + sta RAMRDOFF sta RAMWRTOFF - inc src+2 - inc dst+2 - sta RAMWRTON - lda dst+2 - cmp #$14 - bne src + + ldx save_stack + txs + + rts .endproc call_main_trampoline := $20 ; installed on ZP, turns off auxmem and calls... call_main_addr := call_main_trampoline+7 ; address patched in here -;;; Copy the following "call_main_template" routine to $20 -.scope - sta RAMWRTON - sta RAMRDON - COPY_BYTES sizeof_routine+1, routine, call_main_trampoline - jmp call_init -.endscope - .proc routine sta RAMRDOFF sta RAMWRTOFF @@ -56,21 +107,6 @@ call_main_addr := call_main_trampoline+7 ; address patched in here sizeof_routine = * - routine ; can't .sizeof(proc) before declaration ;; https://github.com/cc65/cc -.proc call_init - ;; run the DA - jsr init - - ;; tear down/exit - sta ALTZPON - lda LCBANK1 - lda LCBANK1 - sta RAMRDOFF - sta RAMWRTOFF - ldx save_stack - txs - rts -.endproc - ;;; ============================================================ ;;; ProDOS MLI calls @@ -101,6 +137,15 @@ call_main_addr := call_main_trampoline+7 ; address patched in here rts .endproc +.proc read_minipix_file + jsr copy_params_aux_to_main + sta ALTZPOFF + MLI_CALL READ, read_minipix_params + sta ALTZPON + jsr copy_params_main_to_aux + rts +.endproc + .proc close_file jsr copy_params_aux_to_main sta ALTZPOFF @@ -140,19 +185,17 @@ loop: lda params_start - 1,y rts .endproc -;;; ---------------------------------------- - params_start: ;;; This block gets copied between main/aux ;;; ProDOS MLI param blocks - hires := $2000 - hires_size = $2000 - - DEFINE_OPEN_PARAMS open_params, pathbuff, $C00 + DEFINE_OPEN_PARAMS open_params, pathbuff, DA_IO_BUFFER DEFINE_GET_EOF_PARAMS get_eof_params + DEFINE_READ_PARAMS read_params, hires, hires_size + DEFINE_READ_PARAMS read_minipix_params, minipix_src_buf, minipix_src_size + DEFINE_CLOSE_PARAMS close_params .proc pathbuff ; 1st byte is length, rest is full path @@ -224,7 +267,7 @@ colormasks: .byte MGTK::colormask_and, MGTK::colormask_or penloc: DEFINE_POINT 0, 0 penwidth: .byte 1 penheight: .byte 1 -penmode: .byte 0 +penmode: .byte MGTK::notpencopy textback: .byte $7F textfont: .addr DEFAULT_FONT nextwinfo: .addr 0 @@ -329,6 +372,7 @@ end: rts lda open_params::ref_num sta get_eof_params::ref_num sta read_params::ref_num + sta read_minipix_params::ref_num sta close_params::ref_num MGTK_CALL MGTK::HideCursor @@ -390,15 +434,21 @@ exit: sbc #>(hires_size+1) lda get_eof_params::eof+2 sbc #^(hires_size+1) - bcs dhr + bcc :+ + jmp show_dhr_file - jsr show_hr_file - jmp close + ;; If bigger than 576, assume HR -dhr: jsr show_dhr_file +: lda get_eof_params::eof + cmp #<(minipix_src_size+1) + lda get_eof_params::eof+1 + sbc #>(minipix_src_size+1) + bcc :+ + jmp show_hr_file -close: jsr close_file - rts + ;; Otherwise, assume Minipix + +: jmp show_minipix_file .endproc .proc show_hr_file @@ -452,6 +502,48 @@ close: jsr close_file rts .endproc + +.proc show_minipix_file + jsr set_bw_mode + + ;; Load file at minipix_src_buf (MAIN $1800) + jsr read_minipix_file + jsr close_file + + ;; Convert (in main) + sta RAMWRTOFF + sta RAMRDOFF + jsr convert_minipix_to_bitmap + sta RAMWRTON + sta RAMRDON + + ;; Copy main>aux + copy16 #minipix_dst_buf, STARTLO + copy16 #minipix_dst_buf, DESTINATIONLO + copy16 #(minipix_dst_buf+minipix_dst_size), ENDLO + sec ; main>aux + jsr AUXMOVE + + ;; Draw + MGTK_CALL MGTK::PaintBits, paintbits_params + + rts + + minipix_width = 88 * 2 + minipix_height = 52 + +.proc paintbits_params +viewloc: DEFINE_POINT (screen_width - minipix_width)/2, (screen_height - minipix_height)/2 +mapbits: .addr minipix_dst_buf +mapwidth: .byte 26 +reserved: .byte 0 +maprect: DEFINE_RECT 0,0,minipix_width-1,minipix_height-1 +.endproc + +.endproc + + + ;;; ============================================================ ;;; Convert single hires to double hires @@ -527,14 +619,10 @@ done: sta PAGE2OFF ;;; screen to a scratch buffer and restore after ;;; destroying the window. - stash := $1200 ; Past DA code - rows = 13 - cols = 40 - .proc stash_menu src := $08 dst := $06 - copy16 #stash, dst + copy16 #menu_save_area, dst sta PAGE2ON jsr inner @@ -547,17 +635,17 @@ rloop: pha tax copy hires_table_lo,x, src copy hires_table_hi,x, src+1 - ldy #cols-1 + ldy #menu_cols-1 cloop: lda (src),y sta (dst),y dey bpl cloop - add16 dst, #cols, dst + add16 dst, #menu_cols, dst pla inc - cmp #rows + cmp #menu_rows bcc rloop rts .endproc @@ -565,7 +653,7 @@ cloop: lda (src),y .proc unstash_menu src := $08 dst := $06 - copy16 #stash, src + copy16 #menu_save_area, src sta PAGE2ON jsr inner @@ -578,21 +666,113 @@ rloop: pha tax copy hires_table_lo,x, dst copy hires_table_hi,x, dst+1 - ldy #cols-1 + ldy #menu_cols-1 cloop: lda (src),y sta (dst),y dey bpl cloop - add16 src, #cols, src + add16 src, #menu_cols, src pla inc - cmp #rows + cmp #menu_rows bcc rloop rts .endproc +;;; ============================================================ +;;; Minipix images + +.proc convert_minipix_to_bitmap + rows = 52 + cols = 88 ; pixels + + src := $06 + dst := $08 + + copy16 #minipix_src_buf, src + copy16 #minipix_dst_buf, dst + + ;; c/o Kent Dickey on comp.sys.apple2.programmer + ;; https://groups.google.com/d/msg/comp.sys.apple2.programmer/XB0jUEvrAhE/loRorS5fBwAJ + + ldx #rows + stx row + ldy #0 ; Y remains unchanged throughout + + ;; For each row... +dorow: ldx #8 + stx srcbit + ldx #7 + stx dstbit + ldx #cols + + ;; Process each bit +: jsr getbit + jsr putbit2 + dex + bne :- + + ;; We've written out 88*2 bits = 176 bits. This means 1 bit was shifted into + ;; the last bit. We need to get it from the MSB to the LSB, so it needs + ;; to be shifted down 7 bits +: clc + jsr putbit1 + dex + cpx #AS_BYTE(-7) ; do 7 times == 7 bits + bne :- + + dec row + bne dorow + rts + +.proc getbit + lda (src),y + rol + sta (src),y + dec srcbit + bne done + + inc src + bne :+ + inc src+1 +: lda #8 + sta srcbit + +done: rts +.endproc + +.proc putbit2 + php + jsr putbit1 + plp + ;; fall through +.endproc +.proc putbit1 + lda (dst),y + ror + sta (dst),y + dec dstbit + bne done + + ror ; shift once more to get bits in right place + sta (dst),y + inc dst + bne :+ + inc dst+1 +: lda #7 + sta dstbit + +done: rts +.endproc + +srcbit: .byte 0 +dstbit: .byte 0 +row: .byte 0 + +.endproc + ;;; ============================================================ ;;; Color/B&W Toggle @@ -626,5 +806,13 @@ done: rts done: rts .endproc +;;; ============================================================ + .include "inc/hires_table.inc" .include "inc/hr_to_dhr.inc" + +;;; ============================================================ + +da_end: + + .assert * <= menu_save_area, error, "DA overlapping menu save area"