mirror of
https://github.com/Michaelangel007/apple2_hgr_font_tutorial.git
synced 2024-11-25 07:32:25 +00:00
Cleanup: ,,, names
This commit is contained in:
parent
9516310e1b
commit
aaba163470
169
README.md
169
README.md
@ -565,7 +565,7 @@ If you were wondering how this data was generated, you see the great thing about
|
|||||||
<body onload="OnLoad()">
|
<body onload="OnLoad()">
|
||||||
<img id="Apple2eFont7x8" src="Apple2eFont7x8.png">
|
<img id="Apple2eFont7x8" src="Apple2eFont7x8.png">
|
||||||
<hr>
|
<hr>
|
||||||
<pre id="hexdump"></pre>
|
<pre id="hexdump"></pre>IncCursorCol
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
@ -609,37 +609,47 @@ Before we can start a simple `DrawChar(char c)` function, we also first need to
|
|||||||
$F5 Low byte (16-bit address) Working pointer to screen byte
|
$F5 Low byte (16-bit address) Working pointer to screen byte
|
||||||
$F6 High byte (16-bit address) Working pointer to screen byte
|
$F6 High byte (16-bit address) Working pointer to screen byte
|
||||||
|
|
||||||
|
```assembly
|
||||||
|
HgrLo EQU $E5
|
||||||
|
HgrHi EQU $E6
|
||||||
|
TmpLo EQU $F5
|
||||||
|
TmpHi EQU $F6
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
Here's the disassembly of our (hard-coded) DrawChar() program:
|
Here's the disassembly of our (hard-coded) DrawChar() program:
|
||||||
|
|
||||||
```assembly
|
```assembly
|
||||||
; FUNC: DrawChar()
|
; FUNC: DrawChar()
|
||||||
; NOTES: A, X, Y is destroyed
|
; NOTES: A, X, Y is destroyed
|
||||||
ORG $0300
|
ORG $0300
|
||||||
300: JSR ScreenPtrToTempPtr
|
300:20 66 03 DrawChar JSR HgrToTmpPtr
|
||||||
303: LDA #00 ; glyph 'c' to draw (not used yet)
|
303:A9 00 LDA #00 ; glyph 'c' to draw (not used yet)
|
||||||
305: LDY #00 ; Y = column to draw at (hard-coded)
|
305:A0 00 LDY #00 ; Y = column to draw at (hard-coded)
|
||||||
307: JMP _DrawChar
|
307:4C 52 03 JMP _DrawChar
|
||||||
|
|
||||||
ORG $0352
|
ORG $0352
|
||||||
352: _DrawChar
|
352: _DrawChar
|
||||||
352: LDX #0
|
352:A2 00 LDX #0 ; next instruction is Self-Modifying!
|
||||||
354: .1 LDA $6200,X ; A = font[ offset + i ]
|
354:BD 00 00 LoadFont LDA $0000,X ; A = font[ offset + i ]
|
||||||
357: STA ($F5),Y ; screen[col] = A
|
357:91 F5 STA (TmpLo),Y ; screen[col] = A
|
||||||
359: CLC
|
359:18 CLC
|
||||||
35A: LDA $F6
|
35A:A5 F6 LDA TmpHi
|
||||||
35C: ADC #4
|
35C:69 04 ADC #4 ; screen += 0x400
|
||||||
35E: STA $F6
|
35E:85 F6 STA TmpHi
|
||||||
360: INX
|
360:E8 INX
|
||||||
361: CPX #8
|
361:E0 08 CPX #8
|
||||||
363: BNE .1
|
363:D0 EF BNE LoadFont
|
||||||
365: RTS
|
365:60 RTS
|
||||||
|
|
||||||
; FUNC: ScreenPtrToTempPtr() = $0366
|
; FUNC: HgrToTmpPtr()
|
||||||
366: LDA $E5 ; Copy initial screen
|
ORG $0366
|
||||||
368: STA $F5 ; destination pointer
|
366: HgrToTmpPtr
|
||||||
36A: LDA $E6 ; to working pointer
|
366:A5 E5 LDA HgrLo ; Copy initial screen
|
||||||
36C: STA $F6
|
368:85 F5 STA TmpLo ; destination pointer
|
||||||
36D: RTS
|
36A:A5 E6 LDA HgrHi ; to working pointer
|
||||||
|
36C:85 F6 STA TmpHi
|
||||||
|
36D:60 RTS
|
||||||
```
|
```
|
||||||
|
|
||||||
Enter in:
|
Enter in:
|
||||||
@ -708,12 +718,12 @@ After drawing a character with `DrawChar()` it is handy if we can advance both:
|
|||||||
; Increment the cursor column and move the destination screen pointer back
|
; Increment the cursor column and move the destination screen pointer back
|
||||||
; up 8 scan lines previously to what it was when DrawChar() was called.
|
; up 8 scan lines previously to what it was when DrawChar() was called.
|
||||||
ORG $0370
|
ORG $0370
|
||||||
370:C8 INY
|
370:C8 IncCursorCol INY
|
||||||
371:18 CLC
|
371:18 CLC
|
||||||
372:A5 F6 LDA $F6
|
372:A5 F6 LDA $F6
|
||||||
374:E9 1F SBC #$1F
|
374:E9 1F SBC #$1F
|
||||||
376:85 F6 STA $F6
|
376:85 F6 STA $F6
|
||||||
378:60 RTS
|
378:60 RTS
|
||||||
```
|
```
|
||||||
|
|
||||||
Enter in:
|
Enter in:
|
||||||
@ -853,17 +863,19 @@ Our prefix code to setup the source address becomes:
|
|||||||
Recall we'll re-use our existing font drawing code `_DrawChar` at $0352:
|
Recall we'll re-use our existing font drawing code `_DrawChar` at $0352:
|
||||||
|
|
||||||
```assembly
|
```assembly
|
||||||
352:A2 00 LDX #0
|
ORG $0352
|
||||||
354:BD 00 00 LDA $0000,X ; A = font[ offset + i ]
|
352: _DrawChar
|
||||||
357:91 F5 STA ($F5),Y ; screen[col] = A
|
352:A2 00 LDX #0 ; next instruction is Self-Modifying!
|
||||||
359:18 CLC
|
354:BD 00 00 _Draw LDA $0000,X ; A = font[ offset + i ]
|
||||||
35A:A5 F6 LDA $F6
|
357:91 F5 STA (TmpLo),Y ; screen[col] = A
|
||||||
35C:69 04 ADC #4 ; screen += 0x400
|
359:18 CLC
|
||||||
35E:85 F6 STA $F6
|
35A:A5 F6 LDA TmpHi
|
||||||
360:E8 INX
|
35C:69 04 ADC #4 ; screen += 0x400
|
||||||
361:E0 08 CPX #8
|
35E:85 F6 STA TmpHi
|
||||||
363:D0 EF BNE $304
|
360:E8 INX
|
||||||
365:60 RTS
|
361:E0 08 CPX #8
|
||||||
|
363:D0 EF BNE _Draw
|
||||||
|
365:60 RTS
|
||||||
```
|
```
|
||||||
|
|
||||||
We just need to touch up our entry point from $0352 ScreenPtrToTempPtr() to $033B DrawCharCol():
|
We just need to touch up our entry point from $0352 ScreenPtrToTempPtr() to $033B DrawCharCol():
|
||||||
@ -974,7 +986,7 @@ Let's fix it up to print the hex value of the current character we are inspectin
|
|||||||
; PARAM: A = nibble to print as hex char
|
; PARAM: A = nibble to print as hex char
|
||||||
1048:29 0F AND #F ; base 16
|
1048:29 0F AND #F ; base 16
|
||||||
104A:AA TAX ;
|
104A:AA TAX ;
|
||||||
104B:20 66 03 JSR ScreenPtrToTempPtr
|
104B:20 66 03 JSR HgrToTmpPtr
|
||||||
104E:BD 58 10 LDA NIB2HEX,X ; nibble to ASCII
|
104E:BD 58 10 LDA NIB2HEX,X ; nibble to ASCII
|
||||||
1051:C8 INY ; IncCursorCol()
|
1051:C8 INY ; IncCursorCol()
|
||||||
1052:20 3B 03 JSR $033B ; DrawCharCol()
|
1052:20 3B 03 JSR $033B ; DrawCharCol()
|
||||||
@ -1008,12 +1020,14 @@ And now we have our own DrawHexByte() function.
|
|||||||
Let's use IncCursorCol() to automatically advance the cusor. We'll also add a space after the character but before the hex value to improve readability of the output.
|
Let's use IncCursorCol() to automatically advance the cusor. We'll also add a space after the character but before the hex value to improve readability of the output.
|
||||||
|
|
||||||
```assembly
|
```assembly
|
||||||
; FUNC: PrintChar() = $0310
|
; FUNC: PrintChar()
|
||||||
; PARAM: A = glyph to draw
|
; PARAM: A = glyph to draw
|
||||||
; PARAM: Y = column to draw at; $0 .. $27 (Columns 0 .. 39) (not modified)
|
; PARAM: Y = column to draw at; $0 .. $27 (Columns 0 .. 39) (not modified)
|
||||||
; INPUT : $F5,$F6 pointer to the destination screen scanline
|
; INPUT : $F5,$F6 pointer to the destination screen scanline
|
||||||
; Must start at every 8 scanlines.
|
; Must start at every 8 scanlines.
|
||||||
; OUTPUT: The Y-Register (cursor column) is automatically incremented.
|
; OUTPUT: The Y-Register (cursor column) is automatically incremented.
|
||||||
|
ORG $0310
|
||||||
|
310 PrintChar
|
||||||
310:20 3B 03 JSR DrawCharCol
|
310:20 3B 03 JSR DrawCharCol
|
||||||
313:4C 70 03 JMP IncCursorCol
|
313:4C 70 03 JMP IncCursorCol
|
||||||
```
|
```
|
||||||
@ -1113,13 +1127,13 @@ This is our mini HGR Y Address look-up table. "Funny" that it has 24 entries --
|
|||||||
|
|
||||||
Enter these bytes (or save [hgrtable.bin](hgrtable.bin) and `bload hgrtable.bin,6400`):
|
Enter these bytes (or save [hgrtable.bin](hgrtable.bin) and `bload hgrtable.bin,6400`):
|
||||||
|
|
||||||
Our `HgrLo` table:
|
Our `HgrLoY` table:
|
||||||
|
|
||||||
6400:00 80 00 80 00 80 00 80
|
6400:00 80 00 80 00 80 00 80
|
||||||
6408:28 A8 28 A8 28 A8 28 A8
|
6408:28 A8 28 A8 28 A8 28 A8
|
||||||
6410:50 D0 50 D0 50 D0 50 D0
|
6410:50 D0 50 D0 50 D0 50 D0
|
||||||
|
|
||||||
Our `HgrHi` table:
|
Our `HgrHiY` table:
|
||||||
|
|
||||||
6418:00 00 01 01 02 02 03 03
|
6418:00 00 01 01 02 02 03 03
|
||||||
6420:00 00 01 01 02 02 03 03
|
6420:00 00 01 01 02 02 03 03
|
||||||
@ -1130,14 +1144,16 @@ To save this AppleWin press `F7`, at the debugger console `bsave "hgrtable.bin",
|
|||||||
To select which row to draw at we'll pass that in the X register to our DrawCharColRow() routine:
|
To select which row to draw at we'll pass that in the X register to our DrawCharColRow() routine:
|
||||||
|
|
||||||
```assembly
|
```assembly
|
||||||
; FUNC: DrawCharColRow() = $0320
|
; FUNC: DrawCharColRow()
|
||||||
; PARAM: A = glyph to draw
|
; PARAM: A = glyph to draw
|
||||||
; PARAM: Y = column to draw at; $0 .. $27 (Columns 0 .. 39) (not modified)
|
; PARAM: Y = column to draw at; $0 .. $27 (Columns 0 .. 39) (not modified)
|
||||||
; PARAM: X = row to draw at; $0 .. $17 (Rows 0 .. 23) (destroyed)
|
; PARAM: X = row to draw at; $0 .. $17 (Rows 0 .. 23) (destroyed)
|
||||||
320:48 PHA
|
ORG $0320
|
||||||
321:20 28 03 JSR SetCursorRow
|
320: DrawCharColRow
|
||||||
324:68 PLA
|
320:48 PHA
|
||||||
325:4C 3B 03 JMP DrawCharCol()
|
321:20 28 03 JSR SetCursorRow
|
||||||
|
324:68 PLA
|
||||||
|
325:4C 3B 03 JMP DrawCharCol
|
||||||
|
|
||||||
; FUNC: SetCursorRow( row )
|
; FUNC: SetCursorRow( row )
|
||||||
; PARAM: X = row to draw at; $0 .. $17 (Rows 0 .. 23) (not modified)
|
; PARAM: X = row to draw at; $0 .. $17 (Rows 0 .. 23) (not modified)
|
||||||
@ -1145,14 +1161,14 @@ To select which row to draw at we'll pass that in the X register to our DrawChar
|
|||||||
; Note: Must start at every 8 scanlines.
|
; Note: Must start at every 8 scanlines.
|
||||||
; OUTPUT: $F5,$F5 working pointer to the destination screen scanline
|
; OUTPUT: $F5,$F5 working pointer to the destination screen scanline
|
||||||
ORG $0328
|
ORG $0328
|
||||||
328:BD 00 64 LDA $6400,X ; HgrLo[ row ]
|
328:BD 00 64 LDA HgrLoY,X ; HgrLoY[ row ]
|
||||||
32B:18 CLC
|
32B:18 CLC
|
||||||
32C:65 E5 ADC $E5
|
32C:65 E5 ADC HgrLo
|
||||||
32E:85 F5 STA $F5
|
32E:85 F5 STA TmpLo
|
||||||
330:BD 18 64 LDA $6418,X ; HgrHi[ row ]
|
330:BD 18 64 LDA HgrHiY,X ; HgrHiY[ row ]
|
||||||
333:18 CLC
|
333:18 CLC
|
||||||
334:65 E6 ADC $E6
|
334:65 E6 ADC HgrHi
|
||||||
336:85 F6 STA $F6
|
336:85 F6 STA TmpHi
|
||||||
338:60 RTS
|
338:60 RTS
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -1166,10 +1182,11 @@ Enter in:
|
|||||||
Now we can print a char at any location:
|
Now we can print a char at any location:
|
||||||
|
|
||||||
```assembly
|
```assembly
|
||||||
1100:A9 41 ; A-register = char
|
ORG $1100
|
||||||
1102:A0 01 ; Y-register = col 1 (2nd column)
|
1100:A9 41 LDA #41 ; A-register = char
|
||||||
1104:A2 02 ; X-register = row 2 (3rd row)
|
1102:A0 01 LDY #1 ; Y-register = col 1 (2nd column)
|
||||||
1106:4C 20 03 ; DrawCharColRow( c, col )
|
1104:A2 02 LDX #2 ; X-register = row 2 (3rd row)
|
||||||
|
1106:4C 20 03 JSR DrawCharColRow
|
||||||
```
|
```
|
||||||
|
|
||||||
Enter in:
|
Enter in:
|
||||||
@ -1241,15 +1258,15 @@ This is a little clunky but it is progress. Let's write the new SetCursorColRow(
|
|||||||
; PARAM: X = column to draw at; $0 .. $27 (Columns 0 .. 39) (not modified)
|
; PARAM: X = column to draw at; $0 .. $27 (Columns 0 .. 39) (not modified)
|
||||||
; PARAM: Y = row to draw at; $0 .. $17 (Rows 0 .. 23) (not modified)
|
; PARAM: Y = row to draw at; $0 .. $17 (Rows 0 .. 23) (not modified)
|
||||||
; NOTES: Version 3! X and Y is swapped from earlier version!
|
; NOTES: Version 3! X and Y is swapped from earlier version!
|
||||||
; [$F5] = HgrLo[ Y ] + ScreenLo + X
|
; [$F5] = HgrLoY[ Y ] + ScreenLo + X
|
||||||
ORG $0379
|
ORG $0379
|
||||||
379:86 F5 STX $F5
|
379:86 F5 STX $F5
|
||||||
37B:B9 00 64 LDA HgrLo,Y ; HgrLo[ row ]
|
37B:B9 00 64 LDA HgrLoY,Y ; HgrLoY[ row ]
|
||||||
37E:18 CLC
|
37E:18 CLC
|
||||||
37F:65 E5 ADC $E5
|
37F:65 E5 ADC $E5
|
||||||
381:65 F5 ADC $F5 ; add column
|
381:65 F5 ADC $F5 ; add column
|
||||||
383:85 F5 STA $F5
|
383:85 F5 STA $F5
|
||||||
385:B9 18 64 LDA HgrHi,Y ; HgrHi[ row ]
|
385:B9 18 64 LDA HgrHiY,Y ; HgrHiY[ row ]
|
||||||
388:18 CLC
|
388:18 CLC
|
||||||
389:65 E6 ADC $E6
|
389:65 E6 ADC $E6
|
||||||
38B:85 F6 STA $F6
|
38B:85 F6 STA $F6
|
||||||
@ -1417,7 +1434,7 @@ Technically, to convert the HGR high byte address to a Text high byte address, w
|
|||||||
Which we could do via:
|
Which we could do via:
|
||||||
|
|
||||||
```assembly
|
```assembly
|
||||||
LDA HgrHi, Y ; Y is row
|
LDA HgrHiY, Y ; Y is row
|
||||||
AND #7 ; strip off top 6 bits
|
AND #7 ; strip off top 6 bits
|
||||||
OR #4 ; Set text page 1 = $0400
|
OR #4 ; Set text page 1 = $0400
|
||||||
````
|
````
|
||||||
@ -1425,8 +1442,8 @@ Which we could do via:
|
|||||||
But we'll save a byte and use the normal subtraction instead:
|
But we'll save a byte and use the normal subtraction instead:
|
||||||
|
|
||||||
```assembly
|
```assembly
|
||||||
LDA HgrHi, Y ; Y is row
|
LDA HgrHiY, Y ; Y is row
|
||||||
CLC ; Convert HgrHi to TextHi byte
|
CLC ; Convert HgrHiY to TextHiY byte
|
||||||
SBC #$1B ; A -= 0x1C
|
SBC #$1B ; A -= 0x1C
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -1439,11 +1456,11 @@ Here's the Pseudo-code to copy the text screen to the HGR Screen:
|
|||||||
```c
|
```c
|
||||||
for( row = 0; row < 24; row++ )
|
for( row = 0; row < 24; row++ )
|
||||||
{
|
{
|
||||||
SrcTextLo = HgrLo[ row ];
|
SrcTextLo = HgrLoY[ row ];
|
||||||
SrcTextHi = HgrHi[ row ] - 0x1C;
|
SrcTextHi = HgrHiY[ row ] - 0x1C;
|
||||||
// SetCursorColRow( 0, row ) which does:
|
// SetCursorColRow( 0, row ) which does:
|
||||||
DstHgrLo = HgrLo[ row ]
|
DstHgrLo = HgrLoY[ row ]
|
||||||
DstHgrHi = HgrHi[ row ]
|
DstHgrHi = HgrHiY[ row ]
|
||||||
|
|
||||||
for( col = 0; col < 40; col++ )
|
for( col = 0; col < 40; col++ )
|
||||||
{
|
{
|
||||||
@ -1460,7 +1477,7 @@ And here is the assembly:
|
|||||||
; FUNC: CopyTextToHGR()
|
; FUNC: CopyTextToHGR()
|
||||||
; DATA:
|
; DATA:
|
||||||
; $6000.$63FF Font 7x8 Data
|
; $6000.$63FF Font 7x8 Data
|
||||||
; $6400.$642F HgrLo, HgrHi table for every 8 scanlines
|
; $6400.$642F HgrLoY, HgrHiY table for every 8 scanlines
|
||||||
ORG $1300
|
ORG $1300
|
||||||
1300:A9 00 LDA #0
|
1300:A9 00 LDA #0
|
||||||
1302:85 F3 STA row
|
1302:85 F3 STA row
|
||||||
@ -1472,11 +1489,11 @@ And here is the assembly:
|
|||||||
130E:B0 20 BCS .3 ; Y >= 24
|
130E:B0 20 BCS .3 ; Y >= 24
|
||||||
1310:A2 00 LDX #0
|
1310:A2 00 LDX #0
|
||||||
1312:86 F2 STX col ; X = col
|
1312:86 F2 STX col ; X = col
|
||||||
1314:20 79 03 JSR SetCursorColRow ; A = HgrHi[ row ]
|
1314:20 79 03 JSR SetCursorColRow ; A = HgrHiY[ row ]
|
||||||
1317:18 CLC ; Convert HgrHi to TextHi byte
|
1317:18 CLC ; Convert HgrHiY to TextHiY byte
|
||||||
1318:E9 1B SBC #$1B ; A -= 0x1C
|
1318:E9 1B SBC #$1B ; A -= 0x1C
|
||||||
131A:85 F8 STA $F8
|
131A:85 F8 STA $F8
|
||||||
131C:B9 00 64 LDA $6400, Y ; A = HgrLo[ row ]
|
131C:B9 00 64 LDA $6400, Y ; A = HgrLoY[ row ]
|
||||||
131F:85 F7 STA $F7
|
131F:85 F7 STA $F7
|
||||||
1321:A4 F2 LDY col
|
1321:A4 F2 LDY col
|
||||||
1323:B1 F7 .2 LDA ($F7),Y
|
1323:B1 F7 .2 LDA ($F7),Y
|
||||||
|
Loading…
Reference in New Issue
Block a user