Separating source into multiple files; updated count page to include hilighting capabilities.

This commit is contained in:
Rob Greene 2016-02-08 21:51:28 -06:00
parent 30c9272b73
commit 8b3684890a
12 changed files with 1305 additions and 1050 deletions

View File

@ -2,6 +2,7 @@
include local.config
# Local stuff:
SRC = afscanner.s diskii.s page-about.s page-browse.s page-count.s page-field.s page-graphics.s page-test.s page.s util.s
PGM = afscanner
SYS = afscannr.system
TYPE = SYS
@ -10,7 +11,7 @@ TMPL = template.po
DISK = afdisk.po
afscanner: afscanner.s
afscanner: $(SRC)
$(ASM) $(PGM).s
cp $(TMPL) $(DISK)
cat $(PGM) | $(AC) -p $(DISK) $(SYS) $(TYPE) $(ADDR)

File diff suppressed because it is too large Load Diff

118
diskii.s Executable file
View File

@ -0,0 +1,118 @@
******************************************************************************************
*
* Disk II routines
* ========================================================================================
*
******************************************************************************************
* Disk II addresses:
PHASEOFF = $C080
PHASEON = $C081
MOTOROFF = $C088
MOTORON = $C089
DRV0EN = $C08A
DRV1EN = $C08B
Q6L = $C08C
Q7L = $C08E
*
* DISK II routines
*
ReadTrack
jsr PRINT
dfb _HOME,$8D,4,$88
asc "T="
dfb _PRBYTE
da DSTTRK
dfb 0
ldx SLOT16 ; Slot*16
lda MOTORON,x ; turn on drive
lda DRV0EN,x ; Drive #1
lda Q7L,x ; Q7 = Low and Q6 = Low => READ mode
lda Q6L,x
jsr ARMMOVE ; Go to our track (app init sets to 40, so first time this recalibrates)
; Fully read the track into buffer @ DATA
jsr SETUPDATA
ldy #0
:loop lda Q6L,x
bpl :loop
sta (DATA),y
iny
bne :loop
inc DATA+1
dec TEMP
bne :loop
lda MOTOROFF,x
rts
* Move the Disk II arm:
ARMMOVE LDA CURTRK
CMP DSTTRK
BNE :MOVE
:THERE LDX SLOT16 ; restore standard slot
RTS
:MOVE PHP
LDA #0
ROL ; direction from CMP
TAY
LDA CURTRK
LSR
TYA
ROL ; odd/even from track
ASL ; times 2
TAY
LDA ARMTABLE,Y
JSR ARMPHASE
LDA ARMTABLE+1,Y
JSR ARMPHASE
PLP
BCS :SUB1
:ADD1 INC CURTRK
BRA ARMMOVE
:SUB1 DEC CURTRK
BRA ARMMOVE
ARMPHASE ORA SLOT16
TAX
LDA PHASEON,X
LDA #$56
JSR DELAY
LDA PHASEOFF,X
RTS
* Phase table for moving arm
* Grouped by inward/outward movement, odd/even track
* To move the arm, two phases need to be triggered
ARMTABLE HEX 0204
HEX 0600
HEX 0604
HEX 0200
* Standard DOS 13-sector and 16-sector address/data field bytes
AddressFieldPrologue
hex D5AA96
AddressFieldEpilogue
hex DEAAEB
DataFieldPrologue
hex D5AAAD
DataFieldEpilogue
hex DEAAEB
* DOS 13-sector translate table
Translate13
hex ABADAEAFB5B6B7BABBBDBEBFD6D7DADB
hex DDDEDFEAEBEDEEEFF5F6F7FAFBFDFEFF
* DOS 16-sector translate table
Translate16
hex 96979A9B9D9E9FA6A7ABACADAEAFB2B3
hex B4B5B6B7B9BABBBCBDBEBFCBCDCECFD3
hex D6D7D9DADBDCDDDEDFE5E6E7E9EAEBEC
hex EDEEEFF2F3F4F5F6F7F9FAFBFCFDFEFF

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 18 KiB

150
page-about.s Executable file
View File

@ -0,0 +1,150 @@
******************************************************************************************
*
* About Page / Help Page
*
******************************************************************************************
*
* ABOUT page interface
*
* Build array of line pointers in INBUF.
AboutInit ; Returns with A:Y = max lines, C = scrolling
jsr PRINT
asc _INVERSE,_MT_ON,_U_ARROW,_D_ARROW,_MT_OFF,_NORMAL," Scroll / "
asc _INVERSE,_MT_ON,_O_APPLE,_NORMAL,"-",_INVERSE,_U_ARROW,_D_ARROW,_MT_OFF,_NORMAL," Page"
dfb 0
lda #<:lines
sta PTR
lda #>:lines
sta PTR+1
ldy #0 ; max lines
ldx #0 ; buffer offset
:save lda PTR
sta inbuf,x
inx
lda PTR+1
sta inbuf,x
inx
iny
:loop lda (PTR)
bne :incr
dey ; we're one past...
lda #0 ; high byte of max lines; Y = low byte
clc ; we need scrolling
rts
:incr lda (PTR)
pha
inc PTR
bne :skip
inc PTR+1
:skip pla
beq :save
bne :incr
* Guide 00000000011111111112222222222333333333344444444445555555555666666666677777777778
* 12345678901234567890123456789012345678901234567890123456789012345678901234567890
* | + + + + + + + +|
:lines asc _INVERSE," Address Field Scanner ",_NORMAL,$00
asc "Version 2.0beta",$00
asc " ",$00
asc "This application is my lame attempt to understand the old Apple Disk II",$00
asc "interface.",$00
asc " ",$00
asc "As of Version 2 of AFSCANNER, multiple pages have been introduced to better",$00
asc "review the contents of a disk buffer and analyze a disk.",$00
asc " ",$00
asc "Use the ",_INVERSE,_MT_ON,_O_APPLE,_MT_OFF,_NORMAL,"-key combinations to toggle pages.",$00
asc " ",$00
asc _INVERSE,_MT_ON,_O_APPLE,_MT_OFF,_NORMAL,"A = This about page.",$00
asc _INVERSE,_MT_ON,_O_APPLE,_MT_OFF,_NORMAL,"B = Browse track buffer.",$00
asc _INVERSE,_MT_ON,_O_APPLE,_MT_OFF,_NORMAL,"C = Display buffer counts.",$00
asc _INVERSE,_MT_ON,_O_APPLE,_MT_OFF,_NORMAL,"F = Address field display. " ; (cont)
asc "(Assuming 'good' address fields on disk.)",$00
asc _INVERSE,_MT_ON,_O_APPLE,_MT_OFF,_NORMAL,"G = Graphical disk display.",$00
asc " ",$00
asc _INVERSE,_MT_ON,_O_APPLE,_MT_OFF,_NORMAL,"* = Enter Apple monitor.",$00
asc " ",$00
asc "Source available at https://github.com/a2geek/afscanner",$00
asc " ",$00
asc "Global Keys",$00
asc "===========",$00
asc " ",$00
asc _INVERSE,_MT_ON,_D_ARROW,_MT_OFF,_NORMAL," Scroll down 1 line",$00
asc _INVERSE,_MT_ON,_U_ARROW,_MT_OFF,_NORMAL," Scroll up 1 line",$00
asc _INVERSE,_MT_ON,_O_APPLE,_D_ARROW,_MT_OFF,_NORMAL," Page down 15 lines",$00
asc _INVERSE,_MT_ON,_O_APPLE,_U_ARROW,_MT_OFF,_NORMAL," Page up 15 lines",$00
asc _INVERSE,_MT_ON,_O_APPLE,_MT_OFF,_NORMAL,"Q Quit to ProDOS",$00
asc " ",$00
asc "Address Field Display",$00
asc "=====================",$00
asc " ",$00
asc "Display the list of Address Fields, the disk bytes, as well as the decoded",$00
asc "values to indicate what sectors are phyiscally present and their order on disk.",$00
asc "Note that the buffer is $2000 (8192) bytes long and some sectors will be",$00
asc "repeated.",$00
asc " ",$00
asc "Headers are currently set to "
dfb 1
da AddressFieldPrologue
dfb " ",1
da AddressFieldPrologue+1
dfb " ",1
da AddressFieldPrologue+2
dfb $00
asc " ",$00
asc "Browse Track Buffer",$00
asc "===================",$00
asc " ",$00
asc "Browse the raw track buffer. Header fields are hilighted. Note that the ",$00
asc "buffer is $2000 (8192) bytes long and some sectors will be repeated.",$00
asc " ",$00
asc "Headers are currently set to "
dfb 1
da AddressFieldPrologue
dfb " ",1
da AddressFieldPrologue+1
dfb " ",1
da AddressFieldPrologue+2
dfb $00
asc " ",$00
asc "Graphical Disk Display",$00
asc "======================",$00
asc " ",$00
asc "Scans an entire disk and graphically displays where sync ($FF) bytes appear on",$00
asc "disk. Note that the length of each bar indicates how many sync bytes were in",$00
asc "that section of the disk. Each bar represents approximately 46 bytes.",$00
asc " ",$00
asc "Display Buffer Counts",$00
asc "=====================",$00
asc " ",$00
asc "Count the number of disk bytes in the buffer and display totals. This may be",$00
asc "helpful when trying to determine address field bytes.",$00
asc " ",$00
asc "To assist with identification, non-zero values or 13-sector bytes or 16-sector",$00
asc "bytes may be highlighted.",$00
asc " ",$00
asc "-END-",$00
dfb 0
AboutDisplay ; Called with A:Y = line
phy ; assuming < 256 lines
lda #_CLREOL
jsr COUT
pla
asl
tay
lda inbuf,y
tax
lda inbuf+1,y
jsr PRINTP
jmp PRCR
AboutKeypress ; Called with Acc = key
; Do Nothing, continue loop
jmp KeyboardWait

98
page-browse.s Executable file
View File

@ -0,0 +1,98 @@
******************************************************************************************
*
* Browse Address Buffer Page
*
******************************************************************************************
*
* BROWSE interface
*
BrowseInit ; Returns with Acc = max lines
jsr PRINT
asc _INVERSE,_MT_ON,_U_ARROW,_D_ARROW,_MT_OFF,_NORMAL," Scroll / "
asc _INVERSE,_MT_ON,_O_APPLE,_NORMAL,"-",_INVERSE,_U_ARROW,_D_ARROW,_MT_OFF,_NORMAL," Page / "
asc _MT_ON,_INVERSE,_L_ARROW,_R_ARROW,_NORMAL,_MT_OFF," Track / "
asc "re",_INVERSE,"S",_NORMAL,"can / "
asc _INVERSE,"R",_NORMAL,"ecalibrate / "
asc "goto ",_INVERSE,"T",_NORMAL,"rack"
dfb 0
* Scan for our prologue mark them by turning off the high bit
jsr ReadTrack ; position head and fully populate buffer
jsr SETUPDATA
:scan ldy #0 ; index for comparisons
:loop lda (DATA),y
cmp AddressFieldPrologue,Y
bne :adv
iny
cpy #3
bcc :loop
; We found prologue bytes, strip off high bit
:strip dey
bmi :adv
lda (DATA),y
and #$7f
sta (DATA),y
bne :strip ; should be always
:adv inc DATA
bne :scan
inc DATA+1
dec TEMP
bne :scan
; The number of lines is based on how many bytes we show on screen
lda #1 ; A:Y = $100 or 256 lines
ldy #0
clc ; we need scrolling
rts
BrowseDisplay ; Called with Acc = line
; Calculate buffer address
sta DATA+1
sty DATA
ldy #5 ; times 32
:mult32 asl DATA
rol DATA+1
dey
bne :mult32
clc
lda #>DATASTART
adc DATA+1
sta DATA+1
; Display offset
lda #"+"
jsr COUT
lda DATA+1
and #$3f
jsr PRHEX
lda DATA
jsr PRHEX
jsr PRINT
asc "- ",$00
; Display 'disk' bytes, highlighting the field markers (high bit was stripped off in init routine)
ldy #0
:nxtbyt lda (DATA),y
bmi :prhex
pha
lda #_INVERSE
jsr COUT
pla
ora #$80
:prhex jsr PRHEX
lda #_NORMAL
jsr COUT
tya
and #$07
cmp #$07
bne :testy
lda #" "
jsr COUT
:testy iny
cpy #32
bne :nxtbyt
jmp PRCR
BrowseKeypress ; Called with Acc = key
jmp FieldKeypress ; identical to Field ... for now at least

232
page-count.s Executable file
View File

@ -0,0 +1,232 @@
******************************************************************************************
*
* Buffer Count Page
*
******************************************************************************************
* Count Settings values (most of these are implicit):
Count_NONE = 0
Count_NONZERO = 1
Count_13SECTOR = 2
Count_16SECTOR = 3
CountInit ; Returns with A:Y = max lines, C = scrolling
jsr CountStatusBar
; Set inbuf to zero (only counting $80, so $200-$2ff sufficient)
ldy #0
tya
:erase sta inbuf,y
iny
bne :erase
; Start counting
jsr ReadTrack
jsr SETUPDATA
ldy #0
:loop lda (DATA),y
asl ; times 2, we don't care about highbit
tax
inc inbuf,x
bne :skip
inc inbuf+1,x
:skip iny
bne :loop
inc DATA+1
dec TEMP
bne :loop
jsr SetCountFlags
; Setup framework
lda #0 ; No lines
tay
sec ; No scrolling
rts
CountDisplay ; Called with A:Y = line
jsr PRINT
dfb $8D
dfb 14
asc " Low +0 +1 +2 +3 +4 +5 +6 +7 High",$8D
dfb 19
asc " ==== ==== ==== ==== ==== ==== ==== ====",$8D
dfb 0
; Y = byte, X = temp, A = temp
ldy #$80
:next ldx #14
lda #" "
:tab jsr COUT
dex
bne :tab
tya
jsr PRHEX
lda #" "
jsr COUT
jsr COUT
:line lda #" " ; re-loading space due to loop construction
jsr COUT
tya
asl
tax
lda inbuf+1,x
bpl :norm
pha
lda #_INVERSE
jsr COUT
pla
:norm and #$7f ; ensure high-bit clear in the count as it is our highlight flag
jsr PRHEX
lda inbuf,x
jsr PRHEX
lda #_NORMAL
jsr COUT
iny
tya
and #$07
bne :line
lda #" "
jsr COUT
jsr COUT
jsr COUT
jsr COUT
tya
dec
jsr PRHEX
jsr PRCR
cpy #0
bne :next
jsr PRCR
jsr PRCR
; Fall through to CountStatusBar for redisplay
CountStatusBar
jsr PRINT
asc "[-]",$00
lda #_NORMAL
ldx CountSettings
cpx #Count_NONE
bne :prnone
lda #_INVERSE
:prnone jsr COUT
jsr PRINT
asc "None",_NORMAL," [0]",$00
lda #_NORMAL
ldx CountSettings
cpx #Count_NONZERO
bne :prnzro
lda #_INVERSE
:prnzro jsr COUT
jsr PRINT
asc "Non-Zero",_NORMAL," [3]",$00
lda #_NORMAL
ldx CountSettings
cpx #Count_13SECTOR
bne :pr13
lda #_INVERSE
:pr13 jsr COUT
jsr PRINT
asc "13-Sector",_NORMAL," [6]",$00
lda #_NORMAL
ldx CountSettings
cpx #Count_16SECTOR
bne :pr16
lda #_INVERSE
:pr16 jsr COUT
jsr PRINT
asc "16-Sector",_NORMAL,$00
rts
CountKeypress ; Called with Acc = key
ldx #0
:test cmp :keys,x
beq :set
inx
cpx #4
bne :test
jmp KeyboardWait
:keys asc "-036"
:set stx CountSettings
jsr SetCountFlags
jmp DrawPage
SetCountFlags
lda CountSettings
asl
tax
jmp (:jmp,x)
:jmp da CountClear
da CountNonZero
da Count13Sector
da Count16Sector
CountClear
ldy #$80
:loop tya
asl
tax
lda inbuf+1,x
and #$7f
sta inbuf+1,x
iny
bne :loop
rts
CountNonZero
jsr CountClear
ldy #$80
:loop tya
asl
tax
lda inbuf,x
ora inbuf+1,x
beq :next
lda inbuf+1,x
ora #$80
sta inbuf+1,x
:next iny
bne :loop
rts
Count13Sector
jsr CountClear
ldy #0
:loop lda Translate13,y
jsr CountSetBit
iny
cpy #32
bne :loop
; Set the reserved bytes which are identical for 13-sector and 16-sector formats
CountSetReserved
lda #$D5
jsr CountSetBit
lda #$AA
jsr CountSetBit
rts
Count16Sector
jsr CountClear
ldy #0
:loop lda Translate16,y
jsr CountSetBit
iny
cpy #64
bne :loop
beq CountSetReserved
CountSetBit
asl
tax
lda inbuf+1,x
ora #$80
sta inbuf+1,x
rts
CountSettings
dfb 0

139
page-field.s Executable file
View File

@ -0,0 +1,139 @@
******************************************************************************************
*
* Address Field Page
*
******************************************************************************************
*
* FIELD Interface
*
FieldInit ; Returns with A:Y = max lines
jsr PRINT
asc _INVERSE,_MT_ON,_U_ARROW,_D_ARROW,_MT_OFF,_NORMAL," Scroll / "
asc _INVERSE,_MT_ON,_O_APPLE,_NORMAL,"-",_INVERSE,_U_ARROW,_D_ARROW,_MT_OFF,_NORMAL," Page / "
asc _MT_ON,_INVERSE,_L_ARROW,_R_ARROW,_NORMAL,_MT_OFF," Track / "
asc "re",_INVERSE,"S",_NORMAL,"can / "
asc _INVERSE,"R",_NORMAL,"ecalibrate / "
asc "goto ",_INVERSE,"T",_NORMAL,"rack"
dfb 0
* Scan for our prologue and save positions in INBUF
jsr ReadTrack ; position head and fully populate buffer
ldx #0 ; index for INBUF
jsr SETUPDATA
:scan ldy #0 ; index for comparisons
:loop lda (DATA),y
cmp AddressFieldPrologue,Y
bne :adv
iny
cpy #3
bcc :loop
; We found prologue bytes, save DATA address
lda DATA
sta inbuf,x
inx
lda DATA+1
sta inbuf,x
inx
:adv inc DATA
bne :scan
inc DATA+1
dec TEMP
bne :scan
; Calculate # of lines
txa
lsr
tay
lda #0 ; Assumed < 256 lines
clc ; we need scrolling
rts
FieldDisplay ; Called with A:Y = line
tya ; Assuming < 256 lines
asl
tay
lda inbuf,y
sta DATA
pha
lda inbuf+1,y
sta DATA+1
pha
; Display offset
lda #"+"
jsr COUT
pla
and #$3f
jsr PRHEX
pla
jsr PRHEX
jsr PRINT
asc "- ",$00
; Display 'disk' bytes
ldy #0
ldx #0
:nextg lda :groups,x
sta TEMP
:bytes lda (DATA),y
jsr PRHEX
iny
dec TEMP
bne :bytes
lda #" "
jsr COUT
inx
cpx #6
bne :nextg
jsr COUT ; 2nd space
; Display values
lda #"V"
ldy #OFFSETV
jsr PRDATA
lda #"T"
ldy #OFFSETT
jsr PRDATA
lda #"S"
ldy #OFFSETS
jsr PRDATA
lda #"C"
ldy #OFFSETC
jsr PRDATA
jmp PRCR
; Address Field byte groupings
:groups dfb 3,2,2,2,2,3
FieldKeypress ; Called with Acc = key
ldx #-1
cmp #LARROW
beq :chgtrk
ldx #1
cmp #RARROW
beq :chgtrk
cmp #"R"
beq :recal
cmp #"S"
beq :setup
cmp #"T"
beq :gotrk
:back jmp KeyboardWait
:chgtrk txa
clc
adc CURTRK
cmp #35 ; cap at track 35 (0..34)
bcs :back
:setdst sta DSTTRK
:setup jmp SetupPage ; this redraws page and re-initializes on new track
:recal lda #40
sta CURTRK ; This forces the recalibration
lda #0
beq :setdst
:gotrk jsr CLRSCRN
jsr PRINT
asc "Enter track number: $"00
jsr READBYTE
bcs :setup
bcc :setdst

143
page-graphics.s Executable file
View File

@ -0,0 +1,143 @@
******************************************************************************************
*
* HGR Disk Display
*
******************************************************************************************
*
* HGR/Graphics interface
*
; Init displays HGR and the static text on the page
HgrInit
jsr PRINT
asc "re",_INVERSE,"S",_NORMAL,"can / "
asc _INVERSE,"R",_NORMAL,"ecalibrate"
dfb 0
; Lay out a our rudimentary page:
jsr HGR
stz TEMPY
:newlin lda TEMPY
jsr HPOSN
ldy #0
:line lda TEMPY
and #$8
bne :lownyb
:hinyb tya
lsr
lsr
lsr
lsr
bra :draw
:lownyb tya
and #$0f
:draw asl
asl
asl
sta TEMP
lda TEMPY
and #$07
ora TEMP
tax
lda HgrHexFont,x
sta (HBAS),y
iny
cpy #35
bne :line
inc TEMPY
lda TEMPY
cmp #16
blt :newlin
; return values
sec ; no scrolloing
lda #0 ; 0 = number of lines (A:Y)
tay
rts
HgrDisplay
; Store current track to not interfere with other screens
lda DSTTRK
pha
; 144 lines (18 text lines * 8 graphic lines ea)
; buffer = 8192 bytes / 144 lines = 56 bytes ea
; OR NIB suggest 6656 / 144 lines = 46 bytes ea
stz DSTTRK
:nxttrk jsr ReadTrack
lda #16
sta :ycoord
jsr SETUPDATA
stz :count
lda #46
sta :bytes
:loop lda (DATA)
cmp #$FF
bne :skip
inc :count
:skip dec :bytes
bne :skip2
lda :ycoord
jsr HPOSN
ldy CURTRK
ldx #0
lda :count
beq :empty
:bits inx
lsr
bne :bits
:empty lda :plot,x
sta (HBAS),y
inc :ycoord
lda :ycoord
cmp #160
bge :botm
stz :count
lda #46
sta :bytes
:skip2 inc DATA
bne :loop
inc DATA+1
dec TEMP
bne :loop
:botm inc DSTTRK
lda DSTTRK
cmp #35
blt :nxttrk
; Restore current target track for other screens
pla
sta DSTTRK
rts
:ycoord dfb 0
:count dfb 0
:bytes dfb 0
:plot hex 000103070f1f3f7fff
HgrKeypress
cmp #"R"
beq :recal
cmp #"S"
beq :setup
:back jmp KeyboardWait
:recal lda #40
sta CURTRK ; This forces the recalibration
stz DSTTRK
:setup jmp SetupPage ; this redraws page and re-initializes, presumably, on a new disk
HgrHexFont ; Stolen from https://github.com/Michaelangel007/apple2_hgr_font_tutorial
hex 1C22322A26221C00 ; 0
hex 080C080808081C00 ; 1
hex 1C22201804023E00 ; 2
hex 3E20101820221C00 ; 3
hex 101814123E101000 ; 4
hex 3E021E2020221C00 ; 5
hex 3804021E22221C00 ; 6
hex 3E20100804040400 ; 7
hex 1C22221C22221C00 ; 8
hex 1C22223C20100E00 ; 9
hex 081422223E222200 ; A
hex 1E22221E22221E00 ; B
hex 1C22020202221C00 ; C
hex 1E22222222221E00 ; D
hex 3E02021E02023E00 ; E
hex 3E02021E02020200 ; F

31
page-test.s Executable file
View File

@ -0,0 +1,31 @@
******************************************************************************************
*
* Test Page
*
* Used for independent testing various pieces of funcionality.
*
******************************************************************************************
*
* TEST interface
*
TestInit
lda #>535
ldy #<535 ; Nice odd number of lines > 256
rts
TestDisplay
phy
pha
lda #_CLREOL
jsr COUT
pla
jsr PRHEX
pla
jsr PRHEX
jmp PRCR
TestKeypress
jmp KeyboardWait

224
page.s Executable file
View File

@ -0,0 +1,224 @@
******************************************************************************************
*
* Primary page controller.
* ========================================================================================
*
******************************************************************************************
SetupPage
jsr TEXT ; ensure we are out of graphics modes as application has some!
jsr PRINT ; position cursor on bottom line
dfb _HOME
dfb 23,$8D
dfb _CLREOL
dfb $00
ldx #_init ; vector offset
jsr _VCALL
ror scrolling ; set flag based on C
sty maxlines
sta maxlines+1
stz topline
stz topline+1
DrawPage
jsr PRINT ; Clear and then draw the content area
dfb _HOME,$8d,$8d,0
; If we aren't scrolling, call _display vector ONCE and then handle keyboard.
bit scrolling
bpl :scroll
lda #0
tay
ldx #_display
jsr _VCALL
jmp KeyboardWait
:scroll lda #0
:loop pha
clc
adc topline
sta printline
lda topline+1
adc #0
sta printline+1
cmp maxlines+1
blt :drwlin
lda printline
cmp maxlines
bge :erase
:drwlin lda printline+1
ldy printline
ldx #_display
jsr _VCALL
bra :incr
:erase jsr PRINT
dfb _CLREOL,$8D,0
:incr pla
inc
cmp #PAGELEN
blt :loop
KeyboardWait
lda KEYBOARD
bpl KeyboardWait
; Uppercase the if it's A-Z
cmp #"a"
blt :goodky
cmp #"z"+1
bge :goodky
and #$df ; uppercase mask
:goodky sta KEYCLEAR
bit OpenApple
bpl :normal
; OpenApple handler
jsr SetScreen
bcs :paging
jsr CLRSCRN
jmp SetupPage
; OA-Up
:paging cmp #UpArrow
bne :nPgUp
ldy #15
:uploop jsr :up1
dey
bne :uploop
beq :back ; always
; OA-Down
:nPgUp cmp #DownArrow
bne :chkOAQ
ldy #15
:dnloop jsr :down1
dey
bne :dnloop
beq :back ; always
; OA-Q
:chkOAQ cmp #"Q"
bne :chkOA7
jsr PRODOSMLI
dfb _MLIQUIT
da QUITPARM
:back jmp DrawPage ; fall through and common return
; OA-*
:chkOA7 cmp #"*"
bne :back
jsr PRINT
asc _CLS,"Press CTRL-Y to re-enter AFScanner.",$8D,$00
jmp MONITOR
; Common keypress handler
; Up
:normal cmp #UpArrow
bne :notUp
jsr :up1
jmp DrawPage
; Down
:notUp cmp #DownArrow
bne :pgKey
jsr :down1
jmp DrawPage
; "Local" subroutines
; if topline+PAGELEN >= maxlines then return
; topline = topline + 1
:down1 clc
lda topline
adc #PAGELEN
sta printline
lda printline+1
adc #0
sta printline+1
cmp maxlines+1
bcc :minus1
lda printline
cmp maxlines
bge :rts
:minus1 inc topline
bne :rts
inc topline+1
rts
; if topline = 0 then return
; topline = topline - 1
:up1 lda topline
ora topline+1
beq :rts ; already = 0
sec
lda topline
sbc #1
sta topline
lda topline+1
sbc #0
sta topline+1
:rts rts
:pgKey ldx #_keypress
; Fall through and JMP to _keypress which takes control for local page keys
* Simple vector call from ZP based on X register
_VCALL jmp: ($00,x) ; Merlin32 needs to know 16 bit JMP
* Handle screen change - both called by app init and normal keyboard handler
SetScreen
ldx #0
:next bit :data,x
bpl :notf
cmp :data,x
beq :setup
pha
txa
clc
adc #7
tax
pla
bra :next
:notf sec ; Not found
rts
:setup ldy #0
:copy inx
lda :data,x
sta _init,y
iny
cpy #6
bne :copy
clc
rts
*
* Data per page: Apple ASCII, Initialization, Display, Keypress (7 bytes)
*
* Definitions:
* - BYTE = Character to match on, case insensitive
* - ADDR = Initialize routine (load track, calculate lookup tables, etc).
* Return:
* A:Y for number of lines,
* Carry: Set = no scrolling (graphics, form, etc), Clear = scrolling.
* Note: Initialization should also display 24th line for the page.
* (Cursor is there and line is clear.)
* - ADDR = Display routine. Called with A:Y for line number. Should end with $8D and is
* responsible for clearing the line.
* - ADDR = Keypress handler. NOT A SUBROUTINE. This routine has a number of entry
* points it might call. KeyboardWait for another keypress or SetupPage to
* reinitialize and redraw.
*
:data
dfb "A"
da AboutInit, AboutDisplay, AboutKeypress
dfb "F"
da FieldInit, FieldDisplay, FieldKeypress
dfb "B"
da BrowseInit, BrowseDisplay, BrowseKeypress
dfb "G"
da HgrInit, HgrDisplay, HgrKeypress
dfb "C"
da CountInit, CountDisplay, CountKeypress
dfb "T"
da TestInit, TestDisplay, TestKeypress
dfb 0 ; end

146
util.s Executable file
View File

@ -0,0 +1,146 @@
******************************************************************************************
*
* Utility routines
* ========================================================================================
*
******************************************************************************************
* Setup the data buffer
SETUPDATA LDA #>DATASTART
STA DATA+1
LDA #<DATASTART
STA DATA
LDA #>DATALEN
STA TEMP ; number of pages to load
RTS
* Print identifier and 4 and 4 encoded number
* Acc = character
* Output = " ?=" where ? is char in Acc
PRDATA PHA
LDA #" "
JSR COUT
PLA
JSR COUT
LDA #"="
JSR COUT
LDA (DATA),Y
SEC
ROL
INY
AND (DATA),Y
JMP PRHEX
* Output routine uses simple RLE type encoding
* High bit set = character;
* High bit clear =
* $00 = exit
* $01 = print byte from address
* $02-$7F = repeat next character
*
* There are two entry points:
* - PRINT = inline text being printed out; implicit PTR increment at start
* - PRINTP = print address passed in AX; no implicit PTR increment at start
PRINT PLA
STA PTR
PLA
STA PTR+1
JSR :MORE
LDA PTR+1
PHA
LDA PTR
PHA
RTS
PRINTP STA PTR+1
STX PTR
BRA :START
:MORE JSR INCPTR
:START LDX #1 ; Assume 1 char to be output
LDA (PTR)
BEQ :EXIT
BMI :SINGLE
CMP #1
BNE :REPEAT
JSR INCPTR
LDA (PTR)
STA PTR2
JSR INCPTR
LDA (PTR)
STA PTR2+1
LDA (PTR2)
JSR PRHEX
BRA :MORE
:REPEAT TAX
JSR INCPTR
LDA (PTR)
:SINGLE JSR COUT
DEX
BNE :SINGLE
BEQ :MORE
:EXIT RTS
INCPTR INC PTR
BNE :EXIT
INC PTR+1
:EXIT RTS
* Clear the data portion of the screen
* (Lines 3-22) and reposition to line 3.
CLRSCRN LDA #_HOME
JSR COUT
JSR PRCR
LDY #20
:1 JSR PRCR ; next line
LDA #_CLREOL
JSR COUT
DEY
BNE :1
LDA #_HOME
JSR COUT
JSR PRCR ; move to row 3
JMP PRCR
* Read a byte
* If invalid, carry is set (anything NOT 0-9,A-F is invalid)
READBYTE JSR READHEX
BCS :EXIT
ASL
ASL
ASL
ASL
STA TEMP
JSR READHEX ; carry falls through to exit
ORA TEMP
:EXIT RTS
READHEX JSR GETCH
JSR COUT
CMP #"9"+1
BCC :NUMERIC
CMP #"F"+1
BCC :ALPHA
:BAD SEC
RTS
:NUMERIC SEC
SBC #"0"
BVS :BAD
:GOOD CLC
RTS
:ALPHA SEC
SBC #"A"
BVS :BAD
ADC #10
:GOOD2 CLC
RTS
* ProDOS QUIT parameter tables
QUITPARM DFB 4 ; 4 parameters
DFB 0 ; 0 is the only quit type
DA 0 ; reserved
DFB 0 ; reserved
DA 0 ; reserved