mirror of
https://github.com/Michaelangel007/apple2_printshop_viewer.git
synced 2024-12-11 00:52:05 +00:00
238 lines
5.9 KiB
ArmAsm
238 lines
5.9 KiB
ArmAsm
; PrintShop / MiniPix Unpacker and Viewer
|
|
; Version 5, March 31, 2019
|
|
; Copyleft Michaelangel007
|
|
; "Sharing is Caring"
|
|
|
|
|
|
; === Our Zero Page Variables ===
|
|
|
|
zSrcPtr = $F7 ; 16-bit pointr to source packed PrintShop graphic
|
|
zSrcBits = $F9
|
|
zSrcMask = $FA ; counter 0 .. 7
|
|
zSrcCol = $FB ; cache of Y reg for lda (zSrcPtr),Y
|
|
|
|
zDstPtr = $26 ; 16-bit pointer to dest; GBASL
|
|
|
|
zDstRow = $FC
|
|
zDstBits = $FD
|
|
zDstColMod7 = $FE
|
|
zDstRowMod3 = $FF
|
|
|
|
|
|
; === PrintShop ===
|
|
|
|
PrintShopSprite = $5800 ; Default load adddress
|
|
;LEN = 572 ; File size
|
|
|
|
; Dimensions
|
|
W_PIXELS = 88
|
|
W_BYTES = 88/8 ; Source (Packed) Bytes/Row
|
|
H_PIXELS = 52
|
|
|
|
X_SCALE = 2 ; Not actually used as hard-coded. For reference
|
|
Y_SCALE = 3
|
|
|
|
|
|
; === Applesoft/Monitor Zero Page Variables ===
|
|
|
|
MON_GBAS = $26 ; 16-bit Pointer to HGR scanline
|
|
|
|
HGR_COLOR = $E4 ;
|
|
HGR_HORIZ = $E5 ; X column / 7 = scanline byte offset
|
|
HGR_PAGE = $E6 ; $20 or $40
|
|
|
|
|
|
; === I/O Softswitches ===
|
|
|
|
TXTCLR = $C050 ; Graphics mode
|
|
TXTSET = $C051
|
|
|
|
MIXCLR = $C052 ; Split screen
|
|
MIXSET = $C053 ; Full screen
|
|
|
|
PAGE1 = $C054
|
|
PAGE2 = $C055
|
|
|
|
LORES = $C056
|
|
HIRES = $C057
|
|
|
|
|
|
; === Applesoft/Monitor ROM ===
|
|
|
|
HGR = $F3E2 ; Clear and View HGR with mixed text/graphics
|
|
HCLR = $F3F2
|
|
HPOSN = $F411 ; Set GBASL, GBASH, MON.HMASK, HGR.BITS ; uses HGR.PAGE,
|
|
MOVE.DOWN = $F505 ; Update GBASL, GBASH
|
|
COLORTBL = $F6F6 ; byte colors[7]
|
|
HCOLOR = $F6E9
|
|
|
|
HOME = $FC58
|
|
|
|
; =====================================================================
|
|
|
|
ORG $6000
|
|
|
|
PrintShopViewer
|
|
|
|
jsr HGR
|
|
sta MIXCLR ; Full screen
|
|
|
|
ldx #>PrintShopSprite
|
|
ldy #<PrintShopSprite
|
|
stx zSrcPtr+1
|
|
sty zSrcPtr+0
|
|
|
|
; Src PS 2x is 88 * 2x scaling = 176 pixels
|
|
; Dstr HGR screen is 40 columns * 7 px/col = 280 pixels
|
|
; =====================================================================
|
|
|
|
; Horz Centering:
|
|
; = (280 - W_PIXELS*X_SCALE)/2
|
|
; = (280 - 88*2)/2
|
|
; = 52 px/col
|
|
; = 52 px / 7px/col
|
|
; = 7.42... = scanline offset
|
|
;
|
|
; 52 px mod 7 px/byte
|
|
; = 52 mod 7
|
|
; = 3
|
|
CENTER_X = 52
|
|
X_MOD_7 = 1 ; Since each pixel is doubled we need to divide (52 mod 7) / 2
|
|
|
|
; Vert Centering:
|
|
; = (192 - H_PIXELS*Y_SCALE)/2
|
|
; = (192 - 52*3)/2
|
|
; = (192 - 156) / 2
|
|
; = 18
|
|
CENTER_Y = {192 - {H_PIXELS*Y_SCALE}}/2
|
|
|
|
; DEBUG -- Same x,y as PrintShop Graphic Editor
|
|
;CENTER_Y = 23
|
|
;CENTER_X = 0
|
|
|
|
|
|
; Image will be centered on screen
|
|
; HGR does NOT need to be cleared to black as we set each byte to zero
|
|
; ==========
|
|
UnpackToScreenHGR
|
|
lda #CENTER_Y ; y = 18
|
|
sta zDstRow
|
|
ldy #0 ; HPOSN: column = Y,X
|
|
sty HGR_COLOR ; 0 = Black
|
|
|
|
:NextTripleY
|
|
sty zDstRowMod3 ; Do y scaling
|
|
|
|
:NextSrcRow
|
|
ldx #CENTER_X ; HPOSN: column = y,X
|
|
lda zDstRow ; HPOSN: row = A
|
|
jsr HPOSN + 6 ; We don't use HGR.X .. HGR.Y @ $E0 .. $E2
|
|
tay ; on exit A = HGR.COLOR = 0 @ $F450
|
|
sta zSrcCol ; Y = zSrcCol
|
|
sta zDstBits
|
|
|
|
clc ; GBAS points to start of scanline
|
|
lda HGR_HORIZ ; Take X column into account
|
|
adc zDstPtr
|
|
sta zDstPtr
|
|
|
|
ldx #X_MOD_7 ; LDX Can be optimized out if x mod 7 is 0
|
|
stx zDstColMod7 ;
|
|
|
|
:NextSrcByte
|
|
lda #1 ; Unpack 8 bits since source = monochrome 8 bits/pix
|
|
sta zSrcMask
|
|
|
|
lda (zSrcPtr),y ; Loop Invariant: Y = zSrcCol
|
|
sta zSrcBits
|
|
|
|
:UnpackSrcBits ; same source byte
|
|
asl zSrcBits
|
|
lda zDstBits
|
|
bcs :PutOne
|
|
:PutZero ; 0 = white
|
|
ora Column2ColorHGR,X
|
|
sta zDstBits
|
|
:PutOne ; 1 = black
|
|
; nothing to do since zDstBits initialized to zero
|
|
inx
|
|
cpx #4
|
|
beq :NextDstByte
|
|
cpx #7
|
|
bne :SameDstByte
|
|
|
|
:NextDstByte
|
|
sty zSrcCol ; 65C02: PHY
|
|
jsr PutHgrByte
|
|
sta zDstBits
|
|
ldy zSrcCol ; 65C02: PLY
|
|
|
|
inc zDstPtr + 0
|
|
cpx #7
|
|
bne :SameDstByte
|
|
ldx #0
|
|
stx zDstColMod7
|
|
|
|
:SameDstByte
|
|
asl zSrcMask
|
|
bcc :UnpackSrcBits ; After 8 loops
|
|
|
|
iny
|
|
sty zSrcCol
|
|
cpy #W_BYTES
|
|
bcc :NextSrcByte
|
|
|
|
lda zDstBits ;
|
|
; ldy #0 ; Need Y=0 for :NextSrcRow --> col = Y,X
|
|
; sta (zDstPtr),Y ; Need last pixel on this scanline
|
|
jsr PutHgrByte
|
|
|
|
; Repeat each src line 3 times
|
|
inc zDstRow
|
|
inc zDstRowMod3
|
|
ldx zDstRowMod3
|
|
cpx #3
|
|
bne :NextSrcRow ; Y = 0 --> col = Y,X
|
|
|
|
clc ; Move to next linear source row
|
|
lda #W_BYTES
|
|
adc zSrcPtr + 0
|
|
sta zSrcPtr + 0
|
|
bcc :SameSrcPage
|
|
:NextSrcPage
|
|
inc zSrcPtr + 1
|
|
:SameSrcPage
|
|
|
|
lda zDstRow
|
|
cmp #H_PIXELS*Y_SCALE + CENTER_Y
|
|
bne :NextTripleY
|
|
:Done
|
|
rts
|
|
|
|
PutHgrByte
|
|
pha ; Save High Bit
|
|
and #$7f ; HGR = 7 bits/pixel as we don't want half-pixels
|
|
ldy #0 ; Need Y=0 for :NextSrcRow --> col = Y,X
|
|
sta (zDstPtr),Y ; Need last pixel on this scanline
|
|
pla ; Restore High Bit
|
|
rol ; C = Bit 7 propogate
|
|
lda #0 ; into next dst byte bit 0
|
|
rol
|
|
beq :NoCarry ; if we have high bit crossing even into odd column
|
|
cpx #4
|
|
bne :NoCarry
|
|
lda #3 ; then we also need to the bottom 2 bits
|
|
:NoCarry
|
|
rts
|
|
|
|
; Single Pixel to Double Pixel
|
|
Column2ColorHGR
|
|
|
|
DB %00000110 ; [0] = $06 Even Column
|
|
DB %00011000 ; [1] = $18
|
|
DB %01100000 ; [2] = $60
|
|
DB %10000000 ; [3] = $80
|
|
DB %00001100 ; [4] = $0C Odd Column
|
|
DB %00110000 ; [5] = $30
|
|
DB %11000000 ; [6] = $C0
|