diff --git a/src/4cade.a b/src/4cade.a index 8d858f17a..dce3a34d0 100644 --- a/src/4cade.a +++ b/src/4cade.a @@ -89,7 +89,7 @@ ResetVector ; 6 bytes, copied to $100 !source "src/ui.browse.mode.a" ; / !source "src/ui.attract.hgr.a" ; \__ execution falls through - !source "src/glue.font.a" ; / + !source "src/ui.font.a" ; / !source "src/prodos.path.a" !source "src/ui.overlay.a" @@ -149,11 +149,13 @@ LastMover FONTSRC = * !pseudopc STACKBASE + 16 { FONTDST = * - !source "src/ui.font.data.a" + !source "src/ui.font.data.lc2.a" COPYDST = * COPYSRC = LastMover + COPYDST - FONTDST - !source "src/ui.font.a" - !source "src/prodos.impl.a" + !source "src/ui.font.lc2.a" + !source "src/prodos.impl.lc2.a" + !source "src/glue.prorwts2.lc2.a" + !source "src/glue.launch.lc2.a" LCRAM2_END = * !if * > $E000 { !error "code is too large: ends at ", * @@ -166,8 +168,10 @@ EvenLasterMover COPYSRC = * !pseudopc hdddataend { COPYDST = * - !source "src/prodos.impl.a" - !source "src/ui.font.a" + !source "src/prodos.impl.lc2.a" + !source "src/ui.font.lc2.a" + !source "src/glue.prorwts2.lc2.a" + !source "src/glue.launch.lc2.a" STACKBASE = * LCRAM2_END = STACKBASE + 16 FONTDST = (LCRAM2_END + 255) and -256 @@ -175,7 +179,7 @@ EvenLasterMover EvenLasterMover FONTSRC = * !pseudopc FONTDST { - !source "src/ui.font.data.a" + !source "src/ui.font.data.lc2.a" !if * > $E000 { !error "code is too large: ends at ", * } diff --git a/src/glue.font.a b/src/glue.font.a deleted file mode 100644 index 0c1b77201..000000000 --- a/src/glue.font.a +++ /dev/null @@ -1,41 +0,0 @@ -;license:MIT -;(c) 2018-9 by 4am -; -; hi-res font drawing routines -; -; Glue functions that handle bank switching and calling the real font drawing routines -; that live in LC RAM 2 now. -; -; Public functions -; - DrawPage -; - Draw40Chars -; - DrawCenteredString -; - DrawString -; - DrawBuffer -; - - ; /!\ execution falls through from ui.attract.hgr/HGRActionCallback -DrawString - jsr SwitchToBank2 - jsr DrawStringInternal - jmp SwitchToBank1 - -DrawPage - jsr SwitchToBank2 - jsr DrawPageInternal - jmp SwitchToBank1 - -Draw40Chars - jsr SwitchToBank2 - jsr Draw40CharsInternal - jmp SwitchToBank1 - -DrawCenteredString - jsr SwitchToBank2 - jsr DrawCenteredStringInternal - jmp SwitchToBank1 - -DrawBuffer - jsr SwitchToBank2 - jsr DrawBufferInternal - jmp SwitchToBank1 diff --git a/src/glue.launch.lc2.a b/src/glue.launch.lc2.a new file mode 100644 index 000000000..0e31bd8fe --- /dev/null +++ b/src/glue.launch.lc2.a @@ -0,0 +1,23 @@ +LaunchInternal + jsr SaveOrRestoreScreenHoles ; save screen hole contents + ldy #$F1 +- lda $100,y + sta STACKBASE - $F0,y ; back up stack + iny + bne - + tsx ; back up stack pointer + stx STACKBASE + sty RestoreStackNextTime + 1 + ; tell |Reenter| to restore the stack and stack pointer + + ldx #(end_promote-promote-1) +- lda promote,x ; copy ProDOS shim to main memory + sta $bf00,x + dex + bpl - + tya + ldy #$18 +- sta $bf57,y + dey + bne - + jmp $106 ; jump to pre-launch code diff --git a/src/glue.prorwts2.lc2.a b/src/glue.prorwts2.lc2.a new file mode 100644 index 000000000..b82de76b7 --- /dev/null +++ b/src/glue.prorwts2.lc2.a @@ -0,0 +1,62 @@ +LoadFileInternal + +LDADDR gPathname + +STAY namlo ; set filename + jsr traverse ; go to subdirectory, set up filename for read + lda #cmdread ; read (instead of write) + sta reqcmd + lda #0 ; 0 = read into main memory + sta auxreq + lda ldrlo+1 + bne + ; if caller provided a load address, use it + sta sizelo ; otherwise query the load address from file metadata + sta sizehi ; 0 = query load address + jsr hddopendir ; call ProRWTS2 + +LDAY ldrlo2 + +STAY ldrlo ++ lda #$FF ; read entire file (ProRWTS2 will figure out exact size) + sta sizehi + jmp hddopendir ; exit via ProRWTS2 + +LoadDHRFileInternal + +LDADDR gPathname + +STAY namlo ; set filename + jsr traverse ; go to subdirectory, set up filename for read + lda #$00 ; read first $2000 bytes + sta sizelo + sta ldrlo + lda #$20 + sta sizehi + asl + sta ldrhi ; into $4000 + lda #1 ; 1 = read into aux memory + sta auxreq + lda #cmdread ; read (instead of write) + sta reqcmd + jsr hddopendir ; call ProRWTS2 + lda #$20 ; read next $2000 bytes + sta sizehi + asl + sta ldrhi ; into $4000 + dec auxreq ; 0 = read into main memory + clc ; not a subdirectory + jmp hddrdwrpart ; call ProRWTS2 + +SaveSmallFileInternal + +LDADDR gPathname + +STAY namlo ; set filename for ProRWTS2 + jsr traverse ; go to subdirectory, set up filename for read + ;;if the write address is always a fixed value then we can discard the query + lda #cmdread ; read (instead of write) + sta reqcmd + lda #0 ; 0 = read into main memory + sta sizelo + sta sizehi ; 0 = query load address + jsr hddopendir ; call ProRWTS2 + lda ldrlo2 + sta ldrlo + lda ldrhi2 + sta ldrhi + lda #cmdwrite ; write (instead of read) + sta reqcmd + sta sizehi ; 512 bytes + jmp hddopendir ; exit via ProRWTS2 (must re-open the file after query) diff --git a/src/prodos.impl.a b/src/prodos.impl.lc2.a similarity index 78% rename from src/prodos.impl.a rename to src/prodos.impl.lc2.a index 41638328c..f0eb154c6 100644 --- a/src/prodos.impl.a +++ b/src/prodos.impl.lc2.a @@ -568,93 +568,6 @@ holepatch ;sta->lda holey_stuff !fill 64 -LoadFileInternal - +LDADDR gPathname - +STAY namlo ; set filename - jsr traverse ; go to subdirectory, set up filename for read - lda #cmdread ; read (instead of write) - sta reqcmd - lda #0 ; 0 = read into main memory - sta auxreq - lda ldrlo+1 - bne + ; if caller provided a load address, use it - sta sizelo ; otherwise query the load address from file metadata - sta sizehi ; 0 = query load address - jsr hddopendir ; call ProRWTS2 - +LDAY ldrlo2 - +STAY ldrlo -+ lda #$FF ; read entire file (ProRWTS2 will figure out exact size) - sta sizehi - jmp hddopendir ; exit via ProRWTS2 - -LoadDHRFileInternal - +LDADDR gPathname - +STAY namlo ; set filename - jsr traverse ; go to subdirectory, set up filename for read - lda #$00 ; read first $2000 bytes - sta sizelo - sta ldrlo - lda #$20 - sta sizehi - asl - sta ldrhi ; into $4000 - lda #1 ; 1 = read into aux memory - sta auxreq - lda #cmdread ; read (instead of write) - sta reqcmd - jsr hddopendir ; call ProRWTS2 - lda #$20 ; read next $2000 bytes - sta sizehi - asl - sta ldrhi ; into $4000 - dec auxreq ; 0 = read into main memory - clc ; not a subdirectory - jmp hddrdwrpart ; call ProRWTS2 - -SaveSmallFileInternal - +LDADDR gPathname - +STAY namlo ; set filename for ProRWTS2 - jsr traverse ; go to subdirectory, set up filename for read - ;;if the write address is always a fixed value then we can discard the query - lda #cmdread ; read (instead of write) - sta reqcmd - lda #0 ; 0 = read into main memory - sta sizelo - sta sizehi ; 0 = query load address - jsr hddopendir ; call ProRWTS2 - lda ldrlo2 - sta ldrlo - lda ldrhi2 - sta ldrhi - lda #cmdwrite ; write (instead of read) - sta reqcmd - sta sizehi ; 512 bytes - jmp hddopendir ; exit via ProRWTS2 (must re-open the file after query) - -LaunchInternal - jsr SaveOrRestoreScreenHoles ; save screen hole contents - ldy #$F1 -- lda $100,y - sta STACKBASE - $F0,y ; back up stack - iny - bne - - tsx ; back up stack pointer - stx STACKBASE - sty RestoreStackNextTime + 1 - ; tell |Reenter| to restore the stack and stack pointer - - ldx #(end_promote-promote-1) -- lda promote,x ; copy ProDOS shim to main memory - sta $bf00,x - dex - bpl - - tya - ldy #$18 -- sta $bf57,y - dey - bne - - jmp $106 ; jump to pre-launch code - EnableAcceleratorAndSwitchToBank1 jsr EnableAccelerator jmp SwitchToBank1 diff --git a/src/ui.font.a b/src/ui.font.a index 1a9031e1e..0c1b77201 100644 --- a/src/ui.font.a +++ b/src/ui.font.a @@ -3,222 +3,39 @@ ; ; hi-res font drawing routines ; -; /!\ These live in LC RAM 2 and rely on the font data which is also in LC RAM 2. /!\ -; Code in LC RAM 1 (which is most program code) should call the functions in glue.font -; which handle bank switching for you. +; Glue functions that handle bank switching and calling the real font drawing routines +; that live in LC RAM 2 now. ; ; Public functions -; - DrawPageInternal -; - Draw40CharsInternal -; - DrawCenteredStringInternal -; - DrawStringInternal -; - DrawBufferInternal +; - DrawPage +; - Draw40Chars +; - DrawCenteredString +; - DrawString +; - DrawBuffer ; -DrawPageInternal -; A/Y contains address of character buffer -; carry bit clear -> draw on page 1 -; carry bit set -> draw on page 2 -; drawing starts at VTAB 0, HTAB 0 -; clobbers PTR -; clobbers A/X/Y -; preserves all flags, by a quirk of implementation - php - ldx #0 - stx VTAB - +STAY PTR -@drawLine - ldy #0 - sty HTAB -@parseLine - lda (PTR),y - cmp #$5B ; '[' at beginning on line - bne + ; ends the parsing - tya - beq @donePage -+ cmp #$0D - beq @doneParsingLine - cmp #$2A - bne + - lda #$10 - sta (PTR),y ; asterisk -> dot, small -+ cmp #$7E - bne + - lda #$11 - sta (PTR),y ; tilde -> dot, medium -+ iny - bne @parseLine -@doneParsingLine - sty SAVE - cpy #0 - beq @skip - ldx SAVE - +LDAY PTR - plp - php + ; /!\ execution falls through from ui.attract.hgr/HGRActionCallback +DrawString + jsr SwitchToBank2 + jsr DrawStringInternal + jmp SwitchToBank1 + +DrawPage + jsr SwitchToBank2 + jsr DrawPageInternal + jmp SwitchToBank1 + +Draw40Chars + jsr SwitchToBank2 + jsr Draw40CharsInternal + jmp SwitchToBank1 + +DrawCenteredString + jsr SwitchToBank2 + jsr DrawCenteredStringInternal + jmp SwitchToBank1 + +DrawBuffer + jsr SwitchToBank2 jsr DrawBufferInternal -@skip inc SAVE ; skip carriage return - lda SAVE ; advance PTR to start of next line - clc - adc PTR - sta PTR - bcc + - inc PTR+1 -+ inc VTAB ; this will print 255 lines if you give it - bne @drawLine ; 255 lines, so don't do that -@donePage - plp - rts - -Draw40CharsInternal -; A/Y contains address of character buffer -; carry bit clear -> draw on page 1 -; carry bit set -> draw on page 2 -; $25 contains textpage line (0..23) (this is the standard VTAB address) -; drawing starts at HTAB 0 -; increments VTAB -; sets HTAB to 0 on exit -; clobbers A/X/Y - jsr + - ldx #40 - jsr DrawBufferInternal - inc VTAB -+ ldx #0 - stx HTAB - rts - -DrawCenteredStringInternal -; A/Y contains address of length-prefixed string -; carry bit clear -> draw on page 1 -; carry bit set -> draw on page 2 -; $25 contains textpage line (0..23) (this is the standard VTAB address) -; clobbers A/X/Y -; clobbers PTR/PTR+1 - +STAY PTR - - php - ldy #0 - lda (PTR),y - sta HTAB - lda #40 - sec - sbc HTAB - lsr - sta HTAB - plp - jmp + - -DrawStringInternal -; A/Y contains address of length-prefixed string -; carry bit clear -> draw on page 1 -; carry bit set -> draw on page 2 -; $24 contains starting column (0..39) (this is the standard HTAB address) -; $25 contains textpage line (0..23) (this is the standard VTAB address) -; clobbers A/X/Y -; clobbers PTR/PTR+1 - +STAY PTR - - ldy #0 -+ lda (PTR),y - tax - inc PTR - bne + - inc PTR+1 -+ - +LDAY PTR - ; /!\ execution falls through here to DrawBufferInternal - -DrawBufferInternal -; A/Y contains address of character buffer -; X contains buffer length (1..40) -; carry bit clear -> draw on page 1 -; carry bit set -> draw on page 2 -; characters MUST have high bit off (0x00..0x7F) -; special characters (0x00..0x1F) will be drawn -; $24 contains starting column (0..39) (this is the standard HTAB address) -; $25 contains textpage line (0..23) (this is the standard VTAB address) -; all characters are drawn on the same line -; HTAB is incremented for each character -; VTAB is NOT incremented -; clobbers A/X/Y - +STAY @src+1 - bcs + - lda #$00 - +HIDE_NEXT_2_BYTES -+ - lda #$60 - sta @pagemask - dex - lda VTAB - asl - asl - asl -; routine to calculate memory address within HGR page -; and self-modify addresses within draw loop that follows -; (routine clobbers A and Y but preserves X) - asl - tay - and #$F0 - bpl @calc1 - ora #$05 -@calc1 bcc @calc2 - ora #$0A -@calc2 asl - asl - sta @hgrlo+1 - tya - and #$0E - adc #$10 - asl @hgrlo+1 - rol -@pagemask=*+1 - eor #$FD ; SMC (0=hi-res page 1, #$60=hi-res page 2) - sta @row0+2 - clc - adc #$04 - sta @row1+2 - adc #$04 - sta @row2+2 - adc #$04 - sta @row3+2 - adc #$04 - sta @row4+2 - adc #$04 - sta @row5+2 - adc #$04 - sta @row6+2 - adc #$04 - sta @row7+2 -@hgrlo lda #$FD - clc - adc HTAB - sta @row0+1 - sta @row1+1 - sta @row2+1 - sta @row3+1 - sta @row4+1 - sta @row5+1 - sta @row6+1 - sta @row7+1 -@loop -@src ldy $FDFD,x - lda FontDataRow0,y -@row0 sta $FDFD,x - lda FontDataRow1,y -@row1 sta $FDFD,x - lda FontDataRow2,y -@row2 sta $FDFD,x - lda FontDataRow3,y -@row3 sta $FDFD,x - lda FontDataRow4,y -@row4 sta $FDFD,x - lda FontDataRow5,y -@row5 sta $FDFD,x - lda FontDataRow6,y -@row6 sta $FDFD,x - lda FontDataRow7,y -@row7 sta $FDFD,x - inc HTAB - dex - bpl @loop - rts + jmp SwitchToBank1 diff --git a/src/ui.font.data.a b/src/ui.font.data.lc2.a similarity index 100% rename from src/ui.font.data.a rename to src/ui.font.data.lc2.a diff --git a/src/ui.font.lc2.a b/src/ui.font.lc2.a new file mode 100644 index 000000000..1a9031e1e --- /dev/null +++ b/src/ui.font.lc2.a @@ -0,0 +1,224 @@ +;license:MIT +;(c) 2018-9 by 4am +; +; hi-res font drawing routines +; +; /!\ These live in LC RAM 2 and rely on the font data which is also in LC RAM 2. /!\ +; Code in LC RAM 1 (which is most program code) should call the functions in glue.font +; which handle bank switching for you. +; +; Public functions +; - DrawPageInternal +; - Draw40CharsInternal +; - DrawCenteredStringInternal +; - DrawStringInternal +; - DrawBufferInternal +; + +DrawPageInternal +; A/Y contains address of character buffer +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; drawing starts at VTAB 0, HTAB 0 +; clobbers PTR +; clobbers A/X/Y +; preserves all flags, by a quirk of implementation + php + ldx #0 + stx VTAB + +STAY PTR +@drawLine + ldy #0 + sty HTAB +@parseLine + lda (PTR),y + cmp #$5B ; '[' at beginning on line + bne + ; ends the parsing + tya + beq @donePage ++ cmp #$0D + beq @doneParsingLine + cmp #$2A + bne + + lda #$10 + sta (PTR),y ; asterisk -> dot, small ++ cmp #$7E + bne + + lda #$11 + sta (PTR),y ; tilde -> dot, medium ++ iny + bne @parseLine +@doneParsingLine + sty SAVE + cpy #0 + beq @skip + ldx SAVE + +LDAY PTR + plp + php + jsr DrawBufferInternal +@skip inc SAVE ; skip carriage return + lda SAVE ; advance PTR to start of next line + clc + adc PTR + sta PTR + bcc + + inc PTR+1 ++ inc VTAB ; this will print 255 lines if you give it + bne @drawLine ; 255 lines, so don't do that +@donePage + plp + rts + +Draw40CharsInternal +; A/Y contains address of character buffer +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; $25 contains textpage line (0..23) (this is the standard VTAB address) +; drawing starts at HTAB 0 +; increments VTAB +; sets HTAB to 0 on exit +; clobbers A/X/Y + jsr + + ldx #40 + jsr DrawBufferInternal + inc VTAB ++ ldx #0 + stx HTAB + rts + +DrawCenteredStringInternal +; A/Y contains address of length-prefixed string +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; $25 contains textpage line (0..23) (this is the standard VTAB address) +; clobbers A/X/Y +; clobbers PTR/PTR+1 + +STAY PTR + + php + ldy #0 + lda (PTR),y + sta HTAB + lda #40 + sec + sbc HTAB + lsr + sta HTAB + plp + jmp + + +DrawStringInternal +; A/Y contains address of length-prefixed string +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; $24 contains starting column (0..39) (this is the standard HTAB address) +; $25 contains textpage line (0..23) (this is the standard VTAB address) +; clobbers A/X/Y +; clobbers PTR/PTR+1 + +STAY PTR + + ldy #0 ++ lda (PTR),y + tax + inc PTR + bne + + inc PTR+1 ++ + +LDAY PTR + ; /!\ execution falls through here to DrawBufferInternal + +DrawBufferInternal +; A/Y contains address of character buffer +; X contains buffer length (1..40) +; carry bit clear -> draw on page 1 +; carry bit set -> draw on page 2 +; characters MUST have high bit off (0x00..0x7F) +; special characters (0x00..0x1F) will be drawn +; $24 contains starting column (0..39) (this is the standard HTAB address) +; $25 contains textpage line (0..23) (this is the standard VTAB address) +; all characters are drawn on the same line +; HTAB is incremented for each character +; VTAB is NOT incremented +; clobbers A/X/Y + +STAY @src+1 + bcs + + lda #$00 + +HIDE_NEXT_2_BYTES ++ + lda #$60 + sta @pagemask + dex + lda VTAB + asl + asl + asl +; routine to calculate memory address within HGR page +; and self-modify addresses within draw loop that follows +; (routine clobbers A and Y but preserves X) + asl + tay + and #$F0 + bpl @calc1 + ora #$05 +@calc1 bcc @calc2 + ora #$0A +@calc2 asl + asl + sta @hgrlo+1 + tya + and #$0E + adc #$10 + asl @hgrlo+1 + rol +@pagemask=*+1 + eor #$FD ; SMC (0=hi-res page 1, #$60=hi-res page 2) + sta @row0+2 + clc + adc #$04 + sta @row1+2 + adc #$04 + sta @row2+2 + adc #$04 + sta @row3+2 + adc #$04 + sta @row4+2 + adc #$04 + sta @row5+2 + adc #$04 + sta @row6+2 + adc #$04 + sta @row7+2 +@hgrlo lda #$FD + clc + adc HTAB + sta @row0+1 + sta @row1+1 + sta @row2+1 + sta @row3+1 + sta @row4+1 + sta @row5+1 + sta @row6+1 + sta @row7+1 +@loop +@src ldy $FDFD,x + lda FontDataRow0,y +@row0 sta $FDFD,x + lda FontDataRow1,y +@row1 sta $FDFD,x + lda FontDataRow2,y +@row2 sta $FDFD,x + lda FontDataRow3,y +@row3 sta $FDFD,x + lda FontDataRow4,y +@row4 sta $FDFD,x + lda FontDataRow5,y +@row5 sta $FDFD,x + lda FontDataRow6,y +@row6 sta $FDFD,x + lda FontDataRow7,y +@row7 sta $FDFD,x + inc HTAB + dex + bpl @loop + rts