From 1855f5130246cabbb71ff17a9f4067e82cea3e19 Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Mon, 4 Sep 2017 19:44:55 -0700 Subject: [PATCH] Combine HGR/DHR viewers --- desk.acc/Makefile | 2 +- desk.acc/go.sh | 5 +- desk.acc/res/hgr2dhr.pl | 56 ++ desk.acc/show_dhr_file.s | 524 ------------------ .../{show_hgr_file.s => show_image_file.s} | 65 ++- 5 files changed, 122 insertions(+), 530 deletions(-) create mode 100755 desk.acc/res/hgr2dhr.pl delete mode 100644 desk.acc/show_dhr_file.s rename desk.acc/{show_hgr_file.s => show_image_file.s} (89%) diff --git a/desk.acc/Makefile b/desk.acc/Makefile index 7aba714..fc816ab 100644 --- a/desk.acc/Makefile +++ b/desk.acc/Makefile @@ -4,7 +4,7 @@ CAFLAGS = --target apple2enh --list-bytes 0 CCFLAGS = --config apple2-asm.cfg # ProDOS file type is $F1 ($ is pesky) -TARGETS = show_text_file.F1 show_dhr_file.F1 show_hgr_file.F1 +TARGETS = show_text_file.F1 show_image_file.F1 .PHONY: clean all all: $(TARGETS) diff --git a/desk.acc/go.sh b/desk.acc/go.sh index 6bbe09e..921e0a2 100755 --- a/desk.acc/go.sh +++ b/desk.acc/go.sh @@ -9,10 +9,7 @@ make all diff show_text_file.bin show_text_file.F1 \ && echo "Files match" -cat show_dhr_file.F1 > mount/SHOW.DHR.FILE.\$F1 \ - && echo "Updated mounted file" - -cat show_hgr_file.F1 > mount/SHOW.HGR.FILE.\$F1 \ +cat show_image_file.F1 > mount/SHOW.IMAGE.FILE.\$F1 \ && echo "Updated mounted file" # Show output for review diff --git a/desk.acc/res/hgr2dhr.pl b/desk.acc/res/hgr2dhr.pl new file mode 100755 index 0000000..32597b9 --- /dev/null +++ b/desk.acc/res/hgr2dhr.pl @@ -0,0 +1,56 @@ +#!/usr/bin/env perl + +use strict; +use warnings; + +my @lo; +my @hi; + +for (my $i = 0; $i < 256; ++$i) { + my $bits = $i; + my $accum = 0; + for (my $b = 0; $b < 7; ++$b) { + if ($bits & 1) { + $accum = $accum | (0b11 << ($b * 2)); + } + $bits = $bits >> 1; + } + my $lo; + my $hi; + if ($bits & 1) { + # palette bit set is easy case + $lo = ($accum & 0x7f); + $hi = (($accum >> 7) & 0xff); + } else { + # otherwise, encode spill bit into hi bit of main mem (hi) + my $spill = $accum & 1; + $accum = $accum >> 1; + $lo = ($accum & 0x7f); + $hi = (($accum >> 7) & 0xff) | ($spill << 7); # encode spill bit + } + push @lo, $lo; + push @hi, $hi; +} + +print "\n"; +print ";;; HGR to DHR - Aux Mem Bytes\n"; +print "hgr_to_dhr_aux:\n"; +for (my $i = 0; $i < 256; $i += 8) { + print " .byte "; + for (my $j = 0; $j < 8; ++$j) { + print sprintf("\$%02x", $lo[$i + $j]); + print ", " unless $j == 7; + } + print "\n"; +} +print "\n"; +print ";;; HGR to DHR - Main Mem Bytes\n"; +print "hgr_to_dhr_main:\n"; +for (my $i = 0; $i < 256; $i += 8) { + print " .byte "; + for (my $j = 0; $j < 8; ++$j) { + print sprintf("\$%02x", $hi[$i + $j]); + print ", " unless $j == 7; + } + print "\n"; +} diff --git a/desk.acc/show_dhr_file.s b/desk.acc/show_dhr_file.s deleted file mode 100644 index fc4b92a..0000000 --- a/desk.acc/show_dhr_file.s +++ /dev/null @@ -1,524 +0,0 @@ - .setcpu "65C02" - .org $800 - - .include "../inc/prodos.inc" - .include "../inc/auxmem.inc" - .include "a2d.inc" - - ;; Big questions: - ;; * How can we hide/show the cursor on demand? - ;; * Can we trigger menu redraw? (if not, need to preserve for fullscreen) - -start: jmp copy2aux - -save_stack:.byte 0 - -;;; Copy $800 through $13FF (the DA) to aux -.proc copy2aux - tsx - stx save_stack - sta RAMWRTON - ldy #0 -src: lda start,y ; self-modified -dst: sta start,y ; self-modified - dey - bne src - sta RAMWRTOFF - inc src+2 - inc dst+2 - sta RAMWRTON - lda dst+2 - cmp #$14 - bne src -.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 - ldx #(call_main_template_end - call_main_template) -loop: lda call_main_template,x - sta call_main_trampoline,x - dex - bpl loop - jmp call_init -.endscope - -.proc call_main_template - sta RAMRDOFF - sta RAMWRTOFF - jsr $1000 ; overwritten (in zp version) - sta RAMRDON - sta RAMWRTON - rts -.endproc -call_main_template_end: ; can't .sizeof(proc) before declaration - ;; https://github.com/cc65/cc65/issues/478 - -.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 - -.proc open_file - jsr copy_params_aux_to_main - sta ALTZPOFF - MLI_CALL OPEN, open_params - sta ALTZPON - jsr copy_params_main_to_aux - rts -.endproc - - -.proc read_file - jsr copy_params_aux_to_main - sta ALTZPOFF - MLI_CALL READ, read_params - sta ALTZPON - jsr copy_params_main_to_aux - rts -.endproc - - -.proc close_file - jsr copy_params_aux_to_main - sta ALTZPOFF - MLI_CALL CLOSE, close_params - sta ALTZPON - jsr copy_params_main_to_aux - rts -.endproc - -;;; ================================================== - -;;; Copies param blocks from Aux to Main -.proc copy_params_aux_to_main - ldy #(params_end - params_start + 1) - sta RAMWRTOFF -loop: lda params_start - 1,y - sta params_start - 1,y - dey - bne loop - sta RAMRDOFF - rts -.endproc - -;;; Copies param blocks from Main to Aux -.proc copy_params_main_to_aux - pha - php - sta RAMWRTON - ldy #(params_end - params_start + 1) -loop: lda params_start - 1,y - sta params_start - 1,y - dey - bne loop - sta RAMRDON - plp - pla - rts -.endproc - -;;; ---------------------------------------- - -params_start: -;;; This block gets copied between main/aux - -;;; ProDOS MLI param blocks - -.proc open_params - .byte 3 ; param_count - .addr pathname ; pathname - .addr $0C00 ; io_buffer -ref_num:.byte 0 ; ref_num -.endproc - - hires := $2000 - hires_size := $2000 - -.proc read_params - .byte 4 ; param_count -ref_num:.byte 0 ; ref_num -buffer: .addr hires ; data_buffer -request:.word hires_size ; request_count - .word 0 ; trans_count -.endproc - -.proc close_params - .byte 1 ; param_count -ref_num:.byte 0 ; ref_num -.endproc - -.proc pathname ; 1st byte is length, rest is full path -length: .byte $00 -data: .byte $00,$00,$00,$00,$00,$00,$00,$00 - .byte $00,$00,$00,$00,$00,$00,$00,$00 - .byte $00,$00,$00,$00,$00,$00,$00,$00 - .byte $00,$00,$00,$00,$00,$00,$00,$00 - .byte $00,$00,$00,$00,$00,$00,$00,$00 - .byte $00,$00,$00,$00,$00,$00,$00,$00 - .byte $00,$00,$00,$00,$00,$00,$00,$00 - .byte $00,$00,$00,$00,$00,$00,$00,$00 -.endproc - - -params_end: -;;; ---------------------------------------- - - window_id := $64 - -.proc line_pos -left: .word 0 -base: .word 0 -.endproc - - -.proc button_params ; queried to track mouse-up -state: .byte $00 -.endproc - - default_width := 560 - default_height := 192 - default_left := 0 - default_top := 0 - -.proc window_title - .byte 0 ; length -.endproc - -.proc window_params -id: .byte window_id ; window identifier -flags: .byte A2D_CWF_NOTITLE -title: .addr window_title - -hscroll:.byte A2D_CWS_NOSCROLL -vscroll:.byte A2D_CWS_NOSCROLL -hscroll_max: - .byte 32 -hscroll_pos: - .byte 0 -vscroll_max: - .byte 32 -vscroll_pos: - .byte 0 - - ;; ??? - .byte $00,$00,$C8,$00,$33,$00 - -width: .word default_width -height: .word default_height - -.proc text_box -left: .word default_left -top: .word default_top - .word $2000 ; ??? never changed - .word $80 ; ??? never changed -hoffset:.word 0 ; Also used for A2D_CLEAR_BOX -voffset:.word 0 -width: .word default_width -height: .word default_height -.endproc -.endproc - - ;; unused? - .byte $00,$00,$00,$00,$00,$00,$00 - .byte $00,$FF,$00,$00,$00,$00,$00,$01 - .byte $01,$00,$7F,$00,$88,$00,$00 - - -.proc init - sta ALTZPON - lda LCBANK1 - lda LCBANK1 - - ;; Get filename by checking DeskTop selected window/icon - - ;; Check that an icon is selected - lda #0 - sta pathname::length - lda file_selected - beq abort ; some file properties? - lda path_index ; prefix index in table - bne :+ -abort: rts - - ;; Copy path (prefix) into pathname buffer. -: src := $06 - dst := $08 - - asl a ; (since address table is 2 bytes wide) - tax - lda path_table,x ; pathname ??? - sta src - lda path_table+1,x - sta src+1 - ldy #0 - lda (src),y - tax - inc src - bne :+ - inc src+1 -: lda #<(pathname::data) - sta dst - lda #>(pathname::data) - sta dst+1 - jsr copy_pathname ; copy x bytes (src) to (dst) - - ;; Append separator. - lda #'/' - ldy #0 - sta (dst),y - inc pathname::length - inc dst - bne :+ - inc dst+1 - - ;; Get file entry. -: lda file_index ; file index in table - asl a ; (since table is 2 bytes wide) - tax - lda file_table,x - sta src - lda file_table+1,x - sta src+1 - - ;; Exit if a directory. - ldy #2 ; 2nd byte of entry - lda (src),y - and #$70 ; check that one of bits 4,5,6 is set ??? - ;; some vague patterns, but unclear - ;; basic = $32,$33, text = $52, sys = $11,$14,??, bin = $23,$24,$33 - ;; dir = $01 (so not shown) - bne :+ - rts ; abort ??? - - ;; Append filename to path. -: ldy #9 - lda (src),y ; grab length - tax ; name has spaces before/after - dex ; so subtract 2 to get actual length - dex - clc - lda src - adc #11 ; 9 = length, 10 = space, 11 = name - sta src - bcc :+ - inc src+1 -: jsr copy_pathname ; copy x bytes (src) to (dst) - - jmp open_file_and_init_window - -.proc copy_pathname ; copy x bytes from src to dst - ldy #0 ; incrementing path length and dst -loop: lda (src),y - sta (dst),y - iny - inc pathname::length - dex - bne loop - tya - clc - adc dst - sta dst - bcc end - inc dst+1 -end: rts -.endproc - -.endproc - -.proc open_file_and_init_window - jsr open_file - lda open_params::ref_num - sta read_params::ref_num - sta close_params::ref_num - - jsr stash_menu - - ;; create window - A2D_CALL A2D_CREATE_WINDOW, window_params - A2D_CALL A2D_TEXT_BOX1, window_params::text_box - - jsr show_file - - A2D_CALL $2B, 0 ; ??? - ;; fall through -.endproc - -;;; ================================================== -;;; Main Input Loop - -.proc input_loop - A2D_CALL A2D_GET_BUTTON, button_params - lda button_params::state - cmp #1 ; was clicked? - bne input_loop ; nope, keep waiting - - A2D_CALL A2D_DESTROY_WINDOW, window_params - - jsr unstash_menu - - jsr UNKNOWN_CALL ; ??? - .byte $0C - .addr 0 - - rts ; exits input loop -.endproc - -.proc show_file - ;; AUX memory half - sta PAGE2ON - jsr read_file - - ;; MAIN memory half - sta PAGE2OFF - jsr read_file - - ;; TODO: Restore PAGE2 state? - - jsr close_file - rts -.endproc - - ;; TODO: Stash menu bar pixels - 13 rows * 2 banks * 40 bytes - -hires_table: - .addr $2000 ; row 0 - .addr $2400 ; 1 - .addr $2800 ; 2 - .addr $2c00 ; 3 - .addr $3000 ; 4 - .addr $3400 ; 5 - .addr $3800 ; 6 - .addr $3c00 ; 7 - .addr $2080 ; 8 - .addr $2480 ; 9 - .addr $2880 ; 10 - .addr $2c80 ; 11 - .addr $3080 ; 12 - .addr $3480 ; 13 - .addr $3880 ; just in case - .addr $3c80 - - - stash := $1200 ; Past DA code - rows = 13 - cols = 40 - -.proc stash_menu - src := $08 - dst := $06 - lda #stash - sta dst+1 - - sta PAGE2ON - jsr inner - sta PAGE2OFF - -inner: - - lda #0 ; row # -rloop: pha - asl a - tax - lda hires_table,x - sta src - lda hires_table+1,x - sta src+1 - ldy #cols-1 -cloop: lda (src),y - sta (dst),y - dey - bpl cloop - - clc ; src += cols - lda src - adc #cols - sta src+1 - - clc ; dst += cols - lda dst - adc #cols - sta dst+1 - - pla - inc - cmp #rows - bcc rloop - rts -.endproc - -.proc unstash_menu - src := $08 - dst := $06 - lda #stash - sta src+1 - - sta PAGE2ON - jsr inner - sta PAGE2OFF - -inner: - - lda #0 ; row # -rloop: pha - asl a - tax - lda hires_table,x - sta dst - lda hires_table+1,x - sta dst+1 - ldy #cols-1 -cloop: lda (src),y - sta (dst),y - dey - bpl cloop - - clc ; src += cols - lda src - adc #cols - sta src+1 - - clc ; dst += cols - lda dst - adc #cols - sta dst+1 - - pla - inc - cmp #rows - bcc rloop - rts -.endproc diff --git a/desk.acc/show_hgr_file.s b/desk.acc/show_image_file.s similarity index 89% rename from desk.acc/show_hgr_file.s rename to desk.acc/show_image_file.s index 4ff4867..72fdc31 100644 --- a/desk.acc/show_hgr_file.s +++ b/desk.acc/show_image_file.s @@ -85,6 +85,14 @@ call_main_template_end: ; can't .sizeof(proc) before declaration rts .endproc +.proc get_file_eof + jsr copy_params_aux_to_main + sta ALTZPOFF + MLI_CALL GET_EOF, get_eof_params + sta ALTZPON + jsr copy_params_main_to_aux + rts +.endproc .proc read_file jsr copy_params_aux_to_main @@ -95,7 +103,6 @@ call_main_template_end: ; can't .sizeof(proc) before declaration rts .endproc - .proc close_file jsr copy_params_aux_to_main sta ALTZPOFF @@ -147,6 +154,12 @@ params_start: .addr pathname ; pathname .addr $0C00 ; io_buffer ref_num:.byte 0 ; ref_num +.endproc + +.proc get_eof_params + .byte 2 ; param_count +ref_num:.byte 0 ; ref_num +length: .byte 0,0,0 ; EOF (lo, mid, hi) .endproc hires := $2000 @@ -346,6 +359,7 @@ end: rts .proc open_file_and_init_window jsr open_file lda open_params::ref_num + sta get_eof_params::ref_num sta read_params::ref_num sta close_params::ref_num @@ -382,6 +396,28 @@ end: rts .endproc .proc show_file + jsr get_file_eof + + ;; If bigger than $2000, assume DHR + + lda get_eof_params::length ; fancy 3-byte unsigned compare + cmp #hires_size+1 + lda get_eof_params::length+2 + sbc #0 + bcs dhr + + jsr show_shr_file + jmp close + +dhr: jsr show_dhr_file + +close: jsr close_file + rts +.endproc + +.proc show_shr_file sta PAGE2OFF jsr read_file jsr close_file @@ -390,6 +426,25 @@ end: rts rts .endproc +.proc show_dhr_file + ;; AUX memory half + sta PAGE2ON + jsr read_file + + ;; MAIN memory half + sta PAGE2OFF + jsr read_file + + ;; TODO: Restore PAGE2 state? + + rts +.endproc + +;;; ================================================== +;;; Convert single hires to double hires + +;;; Assumes the image is loaded to MAIN $2000 and +;;; relies on the hgr_to_dhr.inc table. .proc hgr_to_dhr ptr := $06 @@ -456,6 +511,13 @@ done: sta PAGE2OFF rts .endproc +;;; ================================================== +;;; Stash/Unstash Menu Bar + +;;; Have not yet figured out how to force the menu to +;;; redraw, so instead we save the top 13 rows of the +;;; screen to a scratch buffer and restore after +;;; destroying the window. stash := $1200 ; Past DA code rows = 13 @@ -561,5 +623,6 @@ cloop: lda (src),y rts .endproc + .include "hires_table.inc" .include "hgr_to_dhr.inc"