Added DHGR, new DHGR, switched to Merlin32

This commit is contained in:
Michaelangel007 2017-10-22 08:14:18 -07:00
parent 2358e01f3a
commit ef29f1a835
12 changed files with 1621 additions and 1 deletions

16
Makefile Normal file
View File

@ -0,0 +1,16 @@
TARGETS = hgr.byte view.dhgr dhgr.byte
all: $(TARGETS)
.PHONY: clean
clean:
$(RM) $(TARGETS)
hgr.byte: hgr.byte.s
merlin32 $<
view.dhgr: view.dhgr.s
merlin32 $<
dhgr.byte: dhgr.byte.s
merlin32 $<

View File

@ -1,13 +1,21 @@
#Apple 2 HGR BYTE Inspector
# Apple 2 DHGR/HGR BYTE Inspector
![hgr byte inspector screenshot](hgrbyte.png?raw=true)
![dhgr byte inspector screenshot](dhgrbyte.png?raw=true)
![view screenshot](viewdhgr.png?raw=true)
Keys:
```
ESC Quit
g Toggle fullscreen
G Toggle fullscreen
i Move cursor up
j Move cursor left
k Move cursor right
l Move cursor down
I Move cursor up
J Move cursor left
K Move cursor right
@ -47,3 +55,77 @@ Keys:
= Paste byte (Set cursor byte from temporary)
```
# DHGR Colors
```Basic
0 DIM M(16)
1 FOR I=0 TO 7:READ M(I*2):M(I*2+1)=M(I*2)+8:NEXT:GOTO 9
2 POKE A,X:RETURN
3 B3=C *2:IF B3 > 15 THEN B3 = B3 - 15
4 B2=B3*2:IF B2 > 15 THEN B2 = B2 - 15
5 B1=B2*2:IF B1 > 15 THEN B1 = B1 - 15
6 B0=B1*2:IF B0 > 15 THEN B0 = B0 - 15
7 RETURN
9 P=8192:PRINT CHR$(12);CHR$(21):REM 40-COL
10 TEXT:HOME:HGR2:HGR
20 FOR Y=0 TO 7
30 Z=P + Y*1024
40 A=Z+P+1:GOSUB 110
50 A=Z+128:GOSUB 210
60 A=Z+P+256:GOSUB 110
70 A=Z+384+1:GOSUB 210
80 NEXT
90 POKE 3*P-2,0:POKE 3*P-1,32:REM SQUIRT PREVIEW:DHGR
100 VTAB 22:PRINT "BSAVE PAL.DHGR,A$2000,L$4000":END
110 FOR C=0 TO 15:REM Aux/Main/Aux/Main
120 GOSUB 3:IF C=0 THEN 190
130 A = A-P: X=M(B0):GOSUB 2
140 A = A+P: X=M(B1):GOSUB 2
150 A=A+1
160 A = A-P: X=M(B2):GOSUB 2
170 A = A+P: X=M(B3):GOSUB 2
180 A=A+1:PRINT
190 NEXT:RETURN
210 FOR C=0 TO 15:REM Main/Aux/Main/Aux
220 GOSUB 3:IF C=0 THEN 290
230 A = A+P: X=M(B0):GOSUB 2
240 A=A+1
250 A = A-P: X=M(B1):GOSUB 2
260 A = A+P: X=M(B2):GOSUB 2
270 A=A+1
280 A = A-P: X=M(B3):GOSUB 2
290 NEXT:RETURN
900 REM DHGR 16-colors
900 REM $00,$04,$44,$4C,$22,$2A,$66,$6E
901 REM $11,$19,$55,$5D,$33,$3B,$77,$7F
902 DATA 0,68
903 DATA 34,102
904 DATA 17,85
905 DATA 51,119
```
Memory order is:
* $2000 -> AUX $2000
* $4000 -> MAIN $2000
To view, you'll need a [DHGR Viewer](dhgr.view.s)
# Tutankhamun
Convertedt to dhgr via Sheldon's [tohgr](http://wsxyz.net/tohgr.html)
```
tohgr.mac -dhgr tut.png
```
# Assembler
* [Merlin32](https://www.brutaldeluxe.fr/products/crossdevtools/merlin/)
# License
* [WTFPL](http://www.wtfpl.net/)

BIN
dhgr.byte Normal file

Binary file not shown.

873
dhgr.byte.s Normal file
View File

@ -0,0 +1,873 @@
; Merlin32
CONFIG_DHGR = 1
; DHGR Byte Inspector
; https://github.com/Michaelangel007/apple2_hgrbyte/
;
; Michael Pohoreski
; Version 21
;
; TL:DR;
; IJKL to move
; Ctrl-IJKL to move to edges
; 0..9, A..F enter nibble into cursor byte
;
; Keys:
;
; ESC Quit
; G Toggle fullscreen
;
; i Move cursor up
; j Move cursor left
; k Move cursor right
; l Move cursor down
;
; I Move cursor up
; J Move cursor left
; K Move cursor right
; L Move cursor down
;
; ^I Move cursor to col 0
; ^J Move cursor to col 39
; ^K Move cursor to row 0
; ^L Move cursor to row 191
; RET Center cursor
;
; 0..9 "Append" hex nibble to cursor byte
; A..F
;
; ! Toggle bit 0
; @ Toggle bit 1
; # Toggle bit 2
; $ Toggle bit 3
; % Toggle bit 4
; ^ Toggle bit 5
; & Toggle bit 6
; * Toggle bit 7 (high bit)
; SPC Toggle high bit of byte (bit 7)
; ( Set byte to $FF (Shift-9)
; ) Clear byte to $00 (Shift-0)
; ` Flip all bits
; ~ Flip all bits
;
; , Shift byte left (with zero)
; . Shift byte right (with one )
; < Shift byte left (with zero)
; > Shift byte right (with one )
; [ Rotate byte left
; ] Rotate byte right
;
; - Save cursor byte to temporary
; = Set cursor byte from temporary
;
; TODO:
; Z = clear aux mem
; X = swap aux/main mem
; M = mark begin/end -- show width,height,x,y
;
; These aren't needed
; S = save
; L = load
CH = $24 ; 40-col text cursor column
CV = $25 ; 40-col text cursor row
CH80 = $57B ; 80-col text cursor column
GBASL = $26 ; 16-bit pointer to start of D/HGR scanline
GBASH = $27
DO CONFIG_DHGR
WIDTH = 80 ;
ELSE
WIDTH = 40 ; HGR
FIN
HPOSN = $F411 ; A=row, Y,X=col update GBASL GBASH
TABV = $FB5B ; A=row, ALL STA $25, JMP $FC22
HOME = $FC58
SETTXT = $FB39
; In 80-col mode
; CWSL = $36 -> C307 Output
; KSWL = $38 -> C305 Input
;COUT80 = $C307
;CR = $FC62
;CROUT = $FD8E ; Output CR
COUT = $FDED ; Char Output aka putch()
PR_HEX = $FDD3
PRBYTE = $FDDA
; When Store80 ON, Page 2=ON, read/writes touch aux mem
SW_STORE80 = $C000 ; STA $+0 OFF, $+1 ON
SW_STORE81 = $C001 ; $C055 = page 2
SW_SET40COL = $C00C ; 40-col mode
SW_SET80COL = $C00D ; 80-col mode
SW_AUXRDOFF = $C002 ; $+0 = Read Main $0200..$BFFF, $+1 = Read Aux $0200..$BFFF
SW_AUXWROFF = $C004 ; $+0 = Write Main $0200..$BFFF, $+1 = Write Aux $0200..$BFFF
SW_ALTCHAR0 = $C00E ; Mouse text off
KEYBOARD = $C000 ; LDA
KEYSTROBE = $C010
TXTCLR = $C050 ; Mode Graphics
MIXCLR = $C052 ; Full screen
MIXSET = $C053 ; Split screen
PAGE1 = $C054
HIRES = $C057 ; Mode HGR
SW_DHGR = $C05E ; Mode DHGR
SW_SHGR = $C05F ; Mode SHGR
cursor_row = $E2 ; used by Applesoft HGR.row
aux_ptr = $F7 ; copy of GBAS but points to HGR2 $40xx..$5Fxx
lastkey = $F9
cursor_org = $FA ; When cursor is saved
cursor_tmp = $FB ; Flashing cursor byte
cursor_val = $FC ; Current byte under cursor
FLAG_FULL = $01 ; == $1 -> $C052 MIXCLR
; ; == $0 -> $C053 MIXSET
flags = $FD ;
temp = $FE
cursor_col = $FF ; x2 for DHGR
HGRPAGE = $E6 ; used by Applesoft HGR.page
; $20=MAIN, $40=AUX
MOV_SRC = $003C ; A1L
MOV_END = $003E ; A2L
MOV_DST = $0042 ; A4L
AUXMOVE = $C311 ; C=0 Aux->Main, C=1 Main->Aux
MOVE = $FE2C ; Main<->Main, *MUST* set Y=0 prior!
__MAIN = $900
ORG __MAIN
DhgrByte
LDA #21 ; Version - copy HGR1 to aux, HGR2 to HGR1
JSR Init_Exit ; FEATURE: Set to 00 if you don't want to copy AUX $2000 to MAIN $4000
BIT PAGE1 ; Page 1
BIT TXTCLR ; not text, but graphics
BIT MIXSET ; Split screen text/graphics
BIT HIRES ; HGR, no GR
DO CONFIG_DHGR
STA SW_DHGR ; $C05E DHGR, not HGR
STA SW_SET80COL ; $C00D 80-col on
STA SW_STORE80 ; Turn off for app
FIN
BRA _Center
; Funcs that JMP to GetByte before GotKey()
; Funcs that JMP to PutByte after GotKey()
_Screen ; Toggle mixed/full screen
LDA flags ; A = %????_????
AND #FLAG_FULL ; A = %0000_000f
TAX ; f=0 f=1
STA MIXCLR,X ; C052 C053
LDA flags ; FULL MIX
EOR #FLAG_FULL ; mode is based on old leading edge
STA flags ; not new trailing edge
BRA FlashByte
_HighBit
EOR #$80
BRA PutByte
_MoveL DEC cursor_col
BPL GetByte
_MoveR INC cursor_col
LDA cursor_col
CMP #WIDTH
BCC GetByte ; intentional fall into _EdgeR
_EdgeR LDA #WIDTH-1
DB $2C ; BIT $ABS skip next instruction
_EdgeL LDA #0
STA cursor_col
BPL GetByte ; always
_MoveU DEC cursor_row
LDA cursor_row
CMP #$FF
BNE GetByte ; INTENTIONAL fall into if Y < 0
_MoveD INC cursor_row
LDA cursor_row
CMP #192
BCC GetByte ; intentional fall into
_EdgeD LDA #$BF
DB $2C ; BIT $ABS skip next instruction
_EdgeU LDA #00
STA cursor_row
ADC #1
BNE GetByte ; always
_Center
LDA #WIDTH/2
STA cursor_col
LDA #192/2
STA cursor_row ; intentional fall into GetByte
GetByte ; Cursor position changed
LDY #0 ; Update pointer to screen
LDX #0
LDA cursor_row
JSR HPOSN ; A=row, Y,X=col X->E0 Y->E1
DO CONFIG_DHGR
; NOTE $4000 is our shadow copy of AUX ram
LDA GBASL
STA aux_ptr+0
LDA GBASH
AND #$1F
ORA #$40
STA aux_ptr+1
FIN
JSR GetCursorByte
PutByte
STA cursor_val ; current value
STA cursor_tmp ; flashing cursor
JSR DrawStatus
FlashByte
JSR FlashCursorByte
GetKey
LDA KEYBOARD
BPL FlashByte
STA KEYSTROBE
AND #$7F ; Force ASCII
STA lastkey
CMP #'0' ; key < '0'
BCC TestHex
CMP #'9'+1 ; key < '9'+1
BCC Nibble
TestHex
CMP #'A'
BCC LoadKeys
CMP #'F'+1
BCC Nibble
LoadKeys
LDX #nKeys
FindKey
DEX
BMI FlashByte
CMP aKeys, X
BNE FindKey
GotKey
; If code doesn't fit within +/-127 bytes
; LDA aFuncHi, X
LDA #>__MAIN ; FuncAddressHi
PHA
LDA aFuncLo, X ; FuncAddressLo
PHA
LDA cursor_val ; Last displayed byte may be cursor_tmp
JSR SetCursorByte ; restore current val in case cursor moves
; Also pre-load for ROL/R SHL/R
LDX #0 ; for Toggle Bit #
RTS ; And call function assigned to key
; To BRUN under DOS.3 change above RTS to
; RTS
;_Exit JMP $3D0 ; DOS 3.3 Warmstart vector
; Functions starting with _ are invoked via keys
_Exit
LDA #$80 ; "Reverse" current DHGR mem config so it can be saved
JMP Init_Exit ; Exit to TEXT80
_ByteFF
LDA #$FF
BNE PutByte ; always
_Byte00
LDA #$00
BEQ PutByte ; always
_FlipByte
LDX #$FF
BNE PutBits
_Rol CMP #$80 ; C=a A=%abcd_efgh
_SHL1 ROL ; C=b A=%bcde_fgha C<-bit7, bit0<-C
BRA PutByte ; force branch always
_SHR1 ORA #$01 ; Force C=1 via ROR (SHR, OR #$80)
; Intentional fall into _Ror
; Using LSR instead of ROR to save a byte
; 8 Byte version
; CLC
; ROR
; BCC PutByte
; ORA #$80
; BCS PutByte
_Ror LSR ; C=h A=%0abc_defg 0->bit7, bit0->C
BCC PutByte
ORA #$80
BCS PutByte ; always
_ShiftL ASL ; C=a A=%bcde_fgh0
DB $A2 ; skip next LSR instruction; LDX dummy imm val
_ShiftR LSR ; C=h A=%0abc_defg
BRA PutByte
_Bit7 INX ; intentional fall into
_Bit6 INX
_Bit5 INX
_Bit4 INX
_Bit3 INX
_Bit2 INX
_Bit1 INX
_Bit0 INX
TAY ; save cursor_val
SEC ;
LDA #0 ; X=? A=0 C=1
TogBit ROL
DEX
BNE TogBit
TAX
TYA ; load cursor_val
; common _Bit# code
PutBits STX temp
EOR temp
GotoPutByte
BRA PutByte ; code is too far to directly branch
_SaveByte
STA cursor_org ; intentional fall into
_LoadByte
; *******************
; NOTE: Above code must fit on 1 page!
; IF _LoadByte overflows the initial page then
; LDA aFuncLo PHA RTS
; will have unpredictable results!
; ********************
ERR *-1/$9FF ; Merlin: Error if PC > $9FF
LDA cursor_org
CLC
BCC GotoPutByte ; always
Nibble
LDY #3
CursorSHL
ASL cursor_val
DEY
BPL CursorSHL
LDA lastkey
CMP #$41
BCC Digit
SBC #7 ; $41 - 6 - (C=1) = $3A
Digit
AND #$0F ; Key to Hex
CLC
ADC cursor_val
BCC GotoPutByte ; always
; ------------------------------------------------------------------------
DrawStatus
LDA #20 ; Cursor.Y = Top of 4 line split TEXT/HGR window
JSR VTAB_COL0 ; Cursor.X = 0
LDA #'X'+$80 ; X=## Y=## $=####:##
JSR COUT
DO CONFIG_DHGR
LDY #0 ; src = &char[0][8]
LDA cursor_col
CLC
ROR
BCS HaveMainMem
HaveAuxMem
LDY #8 ; src = &char[1][8]
HaveMainMem
LDX #0 ; dst = 0
CopyMemType
LDA sMemType,Y
STA sTextFooter,X
INY ; src++
INX ; dst++
CPX #8
BNE CopyMemType
FIN
LDA cursor_col
JSR PR_HEX
LDA #' '+$80
JSR COUT
LDA #'Y'+$80
JSR COUT
LDA cursor_row
JSR PR_HEX
LDA #' '+$80
JSR COUT
LDA #'$'+$80
JSR COUT
LDA GBASH
JSR PR_HEX
LDA cursor_col
DO CONFIG_DHGR
LSR ; Aux/Main is interleaved
FIN
CLC
ADC GBASL
JSR PRBYTE
LDA #':'+$80
JSR COUT
LDA cursor_val
JSR PRBYTE
LDA #' '+$80
JSR COUT
ReverseByte
LDX #8
LDA cursor_val
STA temp
ReverseBit
ASL temp
ROR
DEX
BNE ReverseBit
STA temp
PHA ; save reverse byte
LDX #8
PrintBitsNormal
LDA temp
JSR Bit2Asc
ROR temp
DEX
BNE PrintBitsNormal
LDA #'~'+$80
JSR COUT
LDX #8
LDA cursor_val
PrintBitsReverse
TAY
JSR Bit2Asc
TYA
LSR
DEX
BNE PrintBitsReverse
LDA #'$'+$80
JSR COUT
PLA ; restore reverse byte
JSR PRBYTE
LDA cursor_org ; X=0
PHA
LSR
LSR
LSR
LSR
JSR NibToInvTxt
PLA
JSR NibToInvTxt
LDA #21 ; Cursor.Y = 21
JSR VTAB_COL0
LDX #0
PrintFooter1
LDA sTextFooter, X
BEQ _DoneStatus
JSR COUT ; 4 line text window, 2nd row
INX
BNE PrintFooter1 ; (almost) always
_DoneStatus
; Draw pixel grouping
LDA #22
JSR VTAB_COL0
LDA #29
JSR HTAB
; (x & 4) * 8
LDA cursor_col ; src = sPixelFooter
AND #3
ASL
ASL
ASL
TAX ; src += 8*col
LDY #8 ; char [4][8]
PrintFooter2
LDA sPixelFooter,X
JSR COUT
INX
DEY ; len--
BNE PrintFooter2
RTS
; Display nibble as inverse text
; 0 -> '0' $30
; 9 -> '9' $39
; A -> ^A $01
; F -> ^F $06
NibToInvTxt
AND #$F
ORA #'0'+$00 ; ASCII: +$80
CMP #'9'+$01 ; ASCII: +$81
BCC PrintSave
SBC #$39 ; C=1, $3A ':' -> $01 'A', $3F '?' -> $06
PrintSave
STA sTextFooter+17,X ; VTAB 21:HTAB 17 and 18, Update Saved Byte
INX
RTS
Bit2Asc
AND #$01 ; 0 -> B0
BEQ FlipBit
LDA #$81 ; 1 -> 31
FlipBit
EOR #$B0
JMP COUT
; OUT:
; A = byte
; USES:
; GBAS = HGR Page 1 ptr
; aux_ptr = HGR Page 2 AUX shadow copy
GetCursorByte ; Main Aux
; Col & 1
; Even = Read Aux
; Odd = Read Main
DO CONFIG_DHGR
LDA cursor_col
CLC
ROR ; Aux/Main is interleaved
TAY ; y = byte column
BCS _get_main
_get_aux
STA SW_STORE80
LDA (aux_ptr),Y
DB $2C ; OPTIMIZAITON: BRA _get_val -> BIT $abs - BIT $26B1
_get_main
ELSE
LDY cursor_col
FIN
LDA (GBASL),Y
_get_val
STA cursor_val
RTS
FlashCursorByte
LDA cursor_tmp
EOR #$FF
STA cursor_tmp
; OPTIMIZATION: Intentionally fall-into SetCursorByte to save 3-byte JMP
; In:
; A = byte
SetCursorByte
; Col & 1
; Even = Read Aux
; Odd = Read Main
DO CONFIG_DHGR
TAX ; push byte
LDA cursor_col
CLC
ROR
TAY
TXA ; pop byte
BCS _set_main
STA SW_STORE80
STA (aux_ptr),Y ; Shadow copy to HGR2
STA SW_AUXWROFF+1 ; Write AUX
_set_main
ELSE
LDY cursor_col
FIN
STA (GBASL),Y ; Write to AUX or MAIN
STA SW_AUXWROFF ; Write MAIN
RTS
; ========================================================================
; Common code -- called by Init, Exit
Init_Exit
STA SW_SET80COL
DO CONFIG_DHGR
STA SW_AUXRDOFF
STA SW_AUXWROFF
STA SW_STORE80
STA SW_ALTCHAR0 ; Turn off mouse-text
LDX #$20
LDY #$40
; Q. Why is this needed?
; A. After the program has initially run memory is in "reverse" order
; MAIN = 2000
; AUX = 2000
; In order to allow the user to BSAVE linear memory we need to end up:
; MAIN 2000 -> MAIN 4000
; AUX 2000 -> MAIN 2000
;
; A=pos Convert DHGR format: MAIN 2000->AUX 2000, MAIN 4000->MAIN 2000
; A=neg Reverse DHGR format: MAIN 2000->MAIN 4000, AUX 2000->MAIN 2000
PHA
PLA ; Force flags to be updated
BMI OnExit
; HGR12 to AUX/MAIN
OnInit
; Copy MAIN $2000 -> AUX $2000
STX MOV_SRC+1 ; Src Hi
STY MOV_END+1 ; End Hi
STX MOV_DST+1 ; Dst Hi
CLC ; C=0 don't do MOVE
JSR SetDst00
SEC ; C=1 Main to Aux
JSR AUXMOVE
; Copy MAIN $4000 -> MAIN $2000
LDA #$60
STY MOV_SRC+1 ; Src Hi
STA MOV_END+1 ; End Hi
STX MOV_DST+1 ; Dst Hi
SEC ; C=1 also do MOVE
JSR SetDst00
; Copy AUX $2000 -> MAIN $4000
LDY #$40
STX MOV_SRC+1 ; Src Hi
STY MOV_END+1 ; End Hi
STY MOV_DST+1 ; Dst Hi
CLC ; C=0 Aux to Main
JSR SetDst00 ; C=0 don't do MOVE
JSR AUXMOVE
BRA DoneCopy
; "Unlinearize" interleaved AUX/MAIN memory
; so it can be saved in a linear format
OnExit
; Copy MAIN $2000 -> MAIN $4000
STX MOV_SRC+1 ; Src Hi
STY MOV_END+1 ; End Hi
STY MOV_DST+1 ; Dst Hi
SEC ; C=1 also do MOVE
JSR SetDst00
; Copy AUX $2000 -> MAIN $2000
LDY #$40
STX MOV_SRC+1 ; Src Hi
STY MOV_END+1 ; End Hi
STX MOV_DST+1 ; Dst Hi
CLC ; C=0 Aux to Main
JSR SetDst00
JSR AUXMOVE
STA SW_SET40COL ; $C00C
STA SW_DHGR+1 ; $C05F DHGR off
STA SW_STORE81 ; Enable Page 2 switching
DoneCopy
FIN
JSR SETTXT
JSR HOME
LDX #$20
STX HGRPAGE
LDA #0 ; also used by PrintFooter
STA flags
STA cursor_col
STA cursor_row
STA cursor_org
; OPTIMIZATION: Intentionally fall into HTAB
; ------------------------------------------------------------------------
; Move cursor to row=A,col=0
; A = Row
VTAB_COL0
JSR TABV ; update CV
HTAB00
LDA #0
HTAB
STA CH
STA CH80
RTS
; ------------------------------------------------------------------------
; Set src,dst,end low byte pointers to zero
; C=1 Also do MOVE
SetDst00
STZ MOV_SRC+0 ; Src Lo
STZ MOV_DST+0 ; Dst Hi
STZ MOV_END+0 ; End Lo
BCC DoneDst00
LDY #0
JMP MOVE
DoneDst00
RTS
; ========================================================================
sTextFooter
; 1 2 3
; 0123456789012345678901234567890123456789
; "X=## Y=## $=####:## %%%%%%%%~%%%%%%%%$00"
ASC "---/---- SAVE:?? 76543210 "
INV "12345678" ;1-8 INVERSE
; DB '1' & $3F
; DB '2' & $3F
; DB '3' & $3F
; DB '4' & $3F
; DB '5' & $3F
; DB '6' & $3F
; DB '7' & $3F
; DB '8' & $3F
DB $00
; char [2][8]
sMemType
ASC "AUX/----"
ASC "---/MAIN"
; These alternative text groupings
; don't look as good in DHGR 80-col text mode
; "()"
; "<>"
; "{}"
; "[]
; The brackets look the best
;
; char [4][8]
; 12345678123456781234567812345678
; Show which pixel group the bits belong to
sPixelFooter
ASC "[11]222 "
ASC "2[33]44 "
ASC "44[55]6 "
ASC "666[77] "
; ------------------------------------------------------------------------
; Keys are searched in reverse order
; Sorted by least used to most used
aKeys
DB '[' & $1F ; _Exit ESC Quit
ASC 'g' ; _Screen G Toggle fullscreen
ASC 'G' ; _Screen G Toggle fullscreen
DB 'H' & $1F ; _MoveL <- Ctrl-H $08
DB 'U' & $1F ; _MoveR -> Ctrl-U $15
DB 'I' & $1F ; _EdgeU ^I Ctrl-I $09 Move cursor to row 0
DB 'J' & $1F ; _EdgeL ^J Ctrl-J $0A Move cursor to col 0
DB 'K' & $1F ; _EdgeD ^K Ctrl-K $0B Move cursor to row 191
DB "L" & $1F ; _EdgeR ^L Ctrl-L $0C Move cursor to col 39
DB "M" & $1F ; _Center Center cursor
ASC 'i' ; _moveU Move cursor Up
ASC 'j' ; _moveL Move cursor Left
ASC 'k' ; _MoveD Move cursor Down
ASC 'l' ; _MoveR Move cursor Right
ASC 'I' ; _moveU Move cursor Up
ASC 'J' ; _moveL Move cursor Left
ASC 'K' ; _MoveD Move cursor Down
ASC 'L' ; _MoveR Move cursor Right
ASC '!' ; _Bit0 Toggle bit 0
ASC '@' ; _Bit1 Toggle bit 1
ASC '#' ; _Bit2 Toggle bit 2
ASC '$' ; _Bit3 Toggle bit 3
ASC '%' ; _Bit4 Toggle bit 4
ASC '^' ; _Bit5 Toggle bit 5
ASC '&' ; _Bit6 Toggle bit 6
ASC '*' ; _Bit7 Toggle bit 7
DO CONFIG_DHGR
ASC ' ' ; _HighBit Toggle high bit of byte (bit 7) is useless in DHGR mode
ELSE
ASC ' ' ; _HighBit Toggle high bit of byte (bit 7)
FIN
ASC '(' ; _ByteFF Set byte to FF (Shift-9)
ASC ')' ; _Byte00 Set byte to 00 (Shift-0)
ASC '`' ; _FlipByte Toggle all bits
ASC '~' ; _FlipByte
ASC ',' ; _ShiftL (with zero)
ASC '<' ; _ShiftL (with one )
ASC '.' ; _ShiftR (with zero)
ASC '>' ; _ShiftR (with one )
ASC '[' ; _Rol
ASC ']' ; _Ror
ASC '-' ; _SaveByte Save cursor byte
ASC '=' ; _LoadByte Load cursor byte
eKeys
nKeys = eKeys - aKeys ;
; Table of function pointers
; *Note*: Must match aKeys order!
aFuncLo
DB <_Exit -1 ; ESC
DB <_Screen -1 ; g
DB <_Screen -1 ; G
DB <_MoveL -1 ; <-
DB <_MoveR -1 ; ->
DB <_EdgeU -1 ; ^I
DB <_EdgeL -1 ; ^J
DB <_EdgeD -1 ; ^K
DB <_EdgeR -1 ; ^L
DB <_Center -1 ; RET
DB <_MoveU -1 ; 'i'
DB <_MoveL -1 ; 'j'
DB <_MoveD -1 ; 'k'
DB <_MoveR -1 ; 'l'
DB <_MoveU -1 ; 'I'
DB <_MoveL -1 ; 'J'
DB <_MoveD -1 ; 'K'
DB <_MoveR -1 ; 'L'
DB <_Bit0 -1 ; '1'
DB <_Bit1 -1 ; '2'
DB <_Bit2 -1 ; '3'
DB <_Bit3 -1 ; '4'
DB <_Bit4 -1 ; '5'
DB <_Bit5 -1 ; '6'
DB <_Bit6 -1 ; '7'
DB <_Bit7 -1 ; '8'
DO CONFIG_DHGR
DB <_HighBit -1 ; SPC
ELSE
DB <_HighBit -1 ; SPC
FIN
DB <_ByteFF -1 ; '('
DB <_Byte00 -1 ; ')'
DB <_FlipByte-1 ; '`'
DB <_FlipByte-1 ; '~' not a dup mistake
DB <_ShiftL -1 ; `,`
DB <_SHL1 -1 ; `<`
DB <_ShiftR -1 ; `.`
DB <_SHR1 -1 ; `>`
DB <_Rol -1 ; '['
DB <_Ror -1 ; ']
DB <_SaveByte-1 ; '='
DB <_LoadByte-1 ; '-'
__END ; Needed for DOS 3.3

BIN
dhgrbyte.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
hgr.byte Normal file

Binary file not shown.

556
hgr.byte.s Normal file
View File

@ -0,0 +1,556 @@
; Merlin32
CONFIG_PRODOS = 1
; HGR Byte Inspector
; https://github.com/Michaelangel007/apple2_hgrbyte/
;
; Michael Pohoreski
; Version 17
;
; TL:DR;
; IJKL to move
; Ctrl-IJKL to move to edges
; 0..9, A..F enter nibble into cursor byte
;
; Keys:
;
; ESC Quit
; G Toggle fullscreen
;
; i Move cursor up
; j Move cursor left
; k Move cursor right
; l Move cursor down
;
; I Move cursor up
; J Move cursor left
; K Move cursor right
; L Move cursor down
;
; ^I Move cursor to col 0
; ^J Move cursor to col 39
; ^K Move cursor to row 0
; ^L Move cursor to row 191
; RET Center cursor
;
; 0..9 "Append" hex nibble to cursor byte
; A..F
;
; ! Toggle bit 0
; @ Toggle bit 1
; # Toggle bit 2
; $ Toggle bit 3
; % Toggle bit 4
; ^ Toggle bit 5
; & Toggle bit 6
; * Toggle bit 7 (high bit)
; SPC Toggle high bit of byte (bit 7)
; ( Set byte to $FF (Shift-9)
; ) Clear byte to $00 (Shift-0)
; ` Flip all bits
; ~ Flip all bits
;
; , Shift byte left (with zero)
; . Shift byte right (with one )
; < Shift byte left (with zero)
; > Shift byte right (with one )
; [ Rotate byte left
; ] Rotate byte right
;
; - Save cursor byte to temporary
; = Set cursor byte from temporary
GBASL = $26 ; 16-bit pointer to start of D/HGR scanline
GBASH = $27
WIDTH = 40 ; HGR
CH = $24 ; text cursor column
CV = $25 ; text cursor row
ROW_20 = $0550 ; VTAB 21 TEXT address
ROW_21 = $06D0 ; VTAB 22 TEXT address
ROW_22 = $0750 ; VTAB 23 TEXT address
ROW_23 = $07D0 ; VTAB 24 TEXT address
HPOSN = $F411 ; A=row, Y,X=col update GBASL GBASH
TABV = $FB5B ; A=row, ALL STA $25, JMP $FC22
VTAB = $FC22 ; $25=row //e LDA $25, STA$28
HOME = $FC58
COUT = $FDED
PR_HEX = $FDD3
PRBYTE = $FDDA
KEYBOARD = $C000
SW_SET40COL = $C00C ; 40-col mode
KEYSTROBE = $C010
TXTCLR = $C050 ; Mode Graphics
MIXCLR = $C052 ; Full screen
MIXSET = $C053 ; Split screen
PAGE1 = $C054
HIRES = $C057 ; Mode HGR
lastkey = $F9
cursor_row = $E2 ; used by Applesoft HGR.row
cursor_org = $FA ; When cursor is saved
cursor_tmp = $FB ; Flashing cursor byte
cursor_val = $FC ; Current byte under cursor
flags = $FD ;
temp = $FE
cursor_col = $FF
FLAG_FULL = $01 ; == $1 -> $C052 MIXCLR
; ; == $0 -> $C053 MIXSET
HGRPAGE = $E6 ; used by Applesoft HGR.page
__MAIN = $0900
DO CONFIG_PRODOS
ORG __MAIN
ELSE
ORG __MAIN - 4
DW __MAIN
DW __END-*-2
FIN
HgrByte
LDA #17 ; Version
STA SW_SET40COL ; Version 17 force 40-col mode
BIT PAGE1 ; Page 1
BIT TXTCLR ; not text, but graphics
BIT MIXSET ; Split screen text/graphics
BIT HIRES ; HGR, no GR
LDX #0 ; also used by PrintFooter
STX flags
STX cursor_col
STX cursor_row
STX cursor_org
STX GBASL
LDA #$20
STA GBASH
STA HGRPAGE
PrintFooter
LDA TextFooter, X
BEQ _Center ; Default to center of screen
STA ROW_21,X ; 4 line text window, 2nd row
INX
BNE PrintFooter ; (almost) always
; Funcs that JMP to GetByte before GotKey()
; Funcs that JMP to PutByte after GotKey()
_Screen ; Toggle mixed/full screen
LDA flags ; A = %????_????
AND #FLAG_FULL ; A = %0000_000f
TAX ; f=0 f=1
STA MIXCLR,X ; C052 C053
LDA flags ; FULL MIX
EOR #FLAG_FULL ; mode is based on old leading edge
STA flags ; not new trailing edge
BRA FlashByte
_HighBit
EOR #$80
BRA PutByte
_MoveL DEC cursor_col
BPL GetByte
_MoveR INC cursor_col
LDA cursor_col
CMP #WIDTH
BCC GetByte ; intentional fall into _EdgeR
_EdgeR LDA #WIDTH-1
DB $2C ; BIT $ABS skip next instruction
_EdgeL LDA #0
STA cursor_col
BPL GetByte ; always
_MoveU DEC cursor_row
LDA cursor_row
CMP #$FF
BNE GetByte ; INTENTIONAL fall into if Y < 0
_MoveD INC cursor_row
LDA cursor_row
CMP #192
BCC GetByte ; intentional fall into
_EdgeD LDA #$BF
DB $2C ; BIT $ABS skip next instruction
_EdgeU LDA #00
STA cursor_row
ADC #1
BNE GetByte ; always
_Center
LDA #WIDTH/2
STA cursor_col
LDA #192/2
STA cursor_row ; intentional fall into GetByte
GetByte ; Cursor position changed
LDY #0 ; Update pointer to screen
LDX #0
LDA cursor_row
JSR HPOSN ; A=row, Y,X=col X->E0 Y->E1
JSR GetCursorByte
PutByte
STA cursor_val ; current value
STA cursor_tmp ; flashing cursor
JSR DrawStatus
FlashByte
JSR FlashCursorByte
GetKey
LDA KEYBOARD
BPL FlashByte
STA KEYSTROBE
AND #$7F ; Force ASCII
STA lastkey
CMP #'0' ; key < '0'
BCC TestHex
CMP #'9'+1 ; key < '9'+1
BCC Nibble
TestHex
CMP #'A'
BCC LoadKeys
CMP #'F'+1
BCC Nibble
LoadKeys
LDX #nKeys
FindKey
DEX
BMI FlashByte
CMP aKeys, X
BNE FindKey
GotKey
; If code doesn't fit within +/-127 bytes
; LDA aFuncHi, X
LDA #>__MAIN ; FuncAddressHi
PHA
LDA aFuncLo, X ; FuncAddressLo
PHA
LDA cursor_val ; Last displayed byte may be cursor_tmp
JSR SetCursorByte ; restore current val in case cursor moves
; Also pre-load for ROL/R SHL/R
LDX #0 ; for Toggle Bit #
_Exit RTS ; And call function assigned to key
; To BRUN under DOS.3 change above RTS to
; RTS
;_Exit JMP $3D0 ; DOS 3.3 Warmstart vector
; Functions starting with _ are invoked via keys
_ByteFF
LDA #$FF
BNE PutByte ; always
_Byte00
LDA #$00
BEQ PutByte ; always
_FlipByte
LDX #$FF
BNE PutBits
_Rol CMP #$80 ; C=a A=%abcd_efgh
_SHL1 ROL ; C=b A=%bcde_fgha C<-bit7, bit0<-C
BRA PutByte ; force branch always
_SHR1 ORA #$01 ; Force C=1 via ROR (SHR, OR #$80)
; Intentional fall into _Ror
; Using LSR instead of ROR to save a byte
; 8 Byte version
; CLC
; ROR
; BCC PutByte
; ORA #$80
; BCS PutByte
_Ror LSR ; C=h A=%0abc_defg 0->bit7, bit0->C
BCC PutByte
ORA #$80
BCS PutByte ; always
_ShiftL ASL ; C=a A=%bcde_fgh0
DB $A2 ; skip next LSR instruction; LDX dummy imm val
_ShiftR LSR ; C=h A=%0abc_defg
BRA PutByte
_Bit7 INX ; intentional fall into
_Bit6 INX
_Bit5 INX
_Bit4 INX
_Bit3 INX
_Bit2 INX
_Bit1 INX
_Bit0 INX
TAY ; save cursor_val
SEC ;
LDA #0 ; X=? A=0 C=1
TogBit ROL
DEX
BNE TogBit
TAX
TYA ; load cursor_val
; common _Bit# code
PutBits STX temp
EOR temp
GotoPutByte
BRA PutByte ; code is too far to directly branch
_SaveByte
STA cursor_org ; intentional fall into
_LoadByte
; *******************
; NOTE: Above code must fit on 1 page!
; IF _LoadByte overflows the initial page then
; LDA aFuncLo PHA RTS
; will have unpredictable results!
; ********************
ERR *-1/$9FF ; Merlin: Error if PC > $9FF
LDA cursor_org
CLC
BCC GotoPutByte ; always
Nibble
LDY #3
CursorSHL
ASL cursor_val
DEY
BPL CursorSHL
LDA lastkey
CMP #$41
BCC Digit
SBC #7 ; $41 - 6 - (C=1) = $3A
Digit
AND #$0F ; Key to Hex
CLC
ADC cursor_val
BCC GotoPutByte ; always
TextFooter
; "X=## Y=## $=####:## %%%%%%%%~%%%%%%%%"
ASC " SAVE:?? 76543210 "
INV "12345678" ;1-8 INVERSE
DB $00
; ------------------------------------------------------------------------
DrawStatus
LDA #0 ; Cursor.X = 0
STA CH
LDA #20 ; Cursor.Y = Top of 4 line split TEXT/HGR window
JSR TABV ; update CV
PrintStatus
LDA #'X'+$80 ; X=## Y=## $=####:##
JSR COUT
LDA cursor_col
JSR PR_HEX
LDA #' '+$80
JSR COUT
LDA #'Y'+$80
JSR COUT
LDA cursor_row
JSR PR_HEX
LDA #' '+$80
JSR COUT
LDA #'$'+$80
JSR COUT
LDA GBASH
JSR PR_HEX
LDA GBASL
CLC
ADC cursor_col
JSR PRBYTE
LDA #':'+$80
JSR COUT
LDA cursor_val
JSR PRBYTE
LDA #' '+$80
JSR COUT
ReverseByte
LDX #8
LDA cursor_val
STA temp
ReverseBit
ASL temp
ROR
DEX
BNE ReverseBit
STA temp
PHA ; save reverse byte
LDX #8
PrintBitsNormal
LDA temp
JSR Bit2Asc
ROR temp
DEX
BNE PrintBitsNormal
LDA #'~'+$80
JSR COUT
LDX #8
LDA cursor_val
PrintBitsReverse
TAY
JSR Bit2Asc
TYA
LSR
DEX
BNE PrintBitsReverse
LDA #'$'+$80
JSR COUT
PLA ; restore reverse byte
JSR PRBYTE
LDA cursor_org ; X=0
PHA
LSR
LSR
LSR
LSR
JSR NibToInvTxt
PLA
; Display nibble as inverse text
; 0 -> '0' $30
; 9 -> '9' $39
; A -> ^A $01
; F -> ^F $06
NibToInvTxt
AND #$F
ORA #'0'+$00 ; ASCII: +$80
CMP #'9'+$01 ; ASCII: +$81
BCC PrintSave
SBC #$39 ; C=1, $3A ':' -> $01 'A', $3F '?' -> $06
PrintSave
STA ROW_21+17,X
INX
RTS
Bit2Asc
AND #$01 ; 0 -> B0
BEQ FlipBit
LDA #$81 ; 1 -> 31
FlipBit
EOR #$B0
JMP COUT
; A = byte
GetCursorByte
LDY cursor_col
LDA (GBASL),Y
STA cursor_val
SetCursorByte
LDY cursor_col
STA (GBASL),Y
RTS
FlashCursorByte
LDA cursor_tmp
EOR #$FF
STA cursor_tmp
JMP SetCursorByte
; Keys are searched in reverse order
; Sorted by least used to most used
aKeys
DB '[' & $1F ; _Exit ESC Quit
ASC 'g' ; _Screen G Toggle fullscreen
ASC 'G' ; _Screen G Toggle fullscreen
DB 'H' & $1F ; _MoveL <- Ctrl-H $08
DB 'U' & $1F ; _MoveR -> Ctrl-U $15
DB 'I' & $1F ; _EdgeU ^I Ctrl-I $09 Move cursor to row 0
DB 'J' & $1F ; _EdgeL ^J Ctrl-J $0A Move cursor to col 0
DB 'K' & $1F ; _EdgeD ^K Ctrl-K $0B Move cursor to row 191
DB "L" & $1F ; _EdgeR ^L Ctrl-L $0C Move cursor to col 39
DB "M" & $1F ; _Center Center cursor
ASC 'i' ; _moveU Move cursor Up
ASC 'j' ; _moveL Move cursor Left
ASC 'k' ; _MoveD Move cursor Down
ASC 'l' ; _MoveR Move cursor Right
ASC 'I' ; _moveU Move cursor Up
ASC 'J' ; _moveL Move cursor Left
ASC 'K' ; _MoveD Move cursor Down
ASC 'L' ; _MoveR Move cursor Right
ASC '!' ; _Bit0 Toggle bit 0
ASC '@' ; _Bit1 Toggle bit 1
ASC '#' ; _Bit2 Toggle bit 2
ASC '$' ; _Bit3 Toggle bit 3
ASC '%' ; _Bit4 Toggle bit 4
ASC '^' ; _Bit5 Toggle bit 5
ASC '&' ; _Bit6 Toggle bit 6
ASC '*' ; _Bit7 Toggle bit 7
ASC ' ' ; _HighBit Toggle high bit of byte (bit 7)
ASC '(' ; _ByteFF Set byte to FF (Shift-9)
ASC ')' ; _Byte00 Set byte to 00 (Shift-0)
ASC '`' ; _FlipByte Toggle all bits
ASC '~' ; _FlipByte
ASC ',' ; _ShiftL (with zero)
ASC '<' ; _ShiftL (with one )
ASC '.' ; _ShiftR (with zero)
ASC '>' ; _ShiftR (with one )
ASC '[' ; _Rol
ASC ']' ; _Ror
ASC '-' ; _SaveByte Save cursor byte
ASC '=' ; _LoadByte Load cursor byte
eKeys
nKeys = eKeys - aKeys ;
; Table of function pointers
; *Note*: Must match aKeys order!
aFuncLo
DB <_Exit -1 ; ESC
DB <_Screen -1 ; g
DB <_Screen -1 ; G
DB <_MoveL -1 ; <-
DB <_MoveR -1 ; ->
DB <_EdgeU -1 ; ^I
DB <_EdgeL -1 ; ^J
DB <_EdgeD -1 ; ^K
DB <_EdgeR -1 ; ^L
DB <_Center -1 ; RET
DB <_MoveU -1 ; 'i'
DB <_MoveL -1 ; 'j'
DB <_MoveD -1 ; 'k'
DB <_MoveR -1 ; 'l'
DB <_MoveU -1 ; 'I'
DB <_MoveL -1 ; 'J'
DB <_MoveD -1 ; 'K'
DB <_MoveR -1 ; 'L'
DB <_Bit0 -1 ; '1'
DB <_Bit1 -1 ; '2'
DB <_Bit2 -1 ; '3'
DB <_Bit3 -1 ; '4'
DB <_Bit4 -1 ; '5'
DB <_Bit5 -1 ; '6'
DB <_Bit6 -1 ; '7'
DB <_Bit7 -1 ; '8'
DB <_HighBit -1 ; SPC
DB <_ByteFF -1 ; '('
DB <_Byte00 -1 ; ')'
DB <_FlipByte-1 ; '`'
DB <_FlipByte-1 ; '~' not a dup mistake
DB <_ShiftL -1 ; `,`
DB <_SHL1 -1 ; `<`
DB <_ShiftR -1 ; `.`
DB <_SHR1 -1 ; `>`
DB <_Rol -1 ; '['
DB <_Ror -1 ; ']
DB <_SaveByte-1 ; '='
DB <_LoadByte-1 ; '-'
__END ; Needed for DOS 3.3

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 12 KiB

BIN
view.dhgr Normal file

Binary file not shown.

93
view.dhgr.s Normal file
View File

@ -0,0 +1,93 @@
; Show DHGR image in AUX,MAIN format
;
; References:
; Apple IIe #3
; Double High-Resolution Graphics
; * http://www.1000bit.it/support/manuali/apple/technotes/aiie/tn.aiie.03.html
MOV_SRC = $003C ; A1L
MOV_END = $003E ; A2L
MOV_DST = $0042 ; A4L
KEY = $C000
KEYSTROBE = $C010
STORE80 = $C000
RDMAINRAM = $C002 ; 2=OFF, 3=ON
WRMAINRAM = $C004
SET40COL = $C00C
SET80COL = $C00D
CLRALTCHAR = $C00E
AUXMOVE = $C311 ; Main<->Aux
MOVE = $FE2C ; Main<->Main
GR = $C050
FULL = $C052
MIXED = $C053
HGR = $C057
AN3 = $C05E
SETTXT = $FB39
HOME = $FC58
; ========================================
ORG $1F80
; Main
STA STORE80
STA RDMAINRAM
STA WRMAINRAM
STA SET40COL
STA CLRALTCHAR
; Copy MAIN $2000..$3FFF to AUX $2000
LDA #$20 ;
STA MOV_SRC+1 ; Src Hi
STA MOV_DST+1 ; Dst Hi
LDA #$40
STA MOV_END+1 ; End Hi
LDA #$00 ;
STA MOV_SRC+0 ; Src Lo
STA MOV_DST+0 ; Dst Hi
STA MOV_END+0 ; End Lo
SEC ; C=1 Main to Aux
JSR AUXMOVE
; Copy MAIN $4000..$5FFF to MAIN $2000
LDA #$40
STA MOV_SRC+1 ; Src Hi
LDA #$20
STA MOV_DST+1 ; Dst Hi
LDA #$60
STA MOV_END+1 ; End Hi
LDA #$00 ;
STA MOV_SRC+0 ; Src Lo
STA MOV_DST+0 ; Dst Hi
STA MOV_END+0 ; End Lo
JSR MOVE
; Showtime!
STA HGR ; $C057
STA GR ; $C050
STA AN3 ; $C05E
STA FULL ; $C052
STA SET80COL ; $C00D
WaitForKey
LDA KEY
BPL WaitForKey
STA KEYSTROBE
STA SET40COL ; $C00C
STA AN3+1 ; $C05F
JSR SETTXT
JMP HOME

BIN
viewdhgr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB