Skip to content

Commit 09d370a

Browse files
committed
Vdc wip
1 parent 1c6f2c8 commit 09d370a

1 file changed

Lines changed: 267 additions & 0 deletions

File tree

lib/vdc.asm

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#importonce
3333

3434
#import "labels/lib/kernal.asm"
35+
#import "labels/lib/screeneditor.asm"
3536
#import "labels/lib/vdc.asm"
3637

3738
.filenamespace c128lib
@@ -399,6 +400,272 @@ InitText: {
399400
stx $d600; bit $d600; bpl *-3; sta $d601
400401
}
401402

403+
/**
404+
* @brief Read from Vdc internal memory and write it to Vic screen memory by
405+
* using coordinates.
406+
*
407+
* @param[in] xPos X coord on Vdc screen
408+
* @param[in] yPos Y coord on Vdc screen
409+
* @param[in] destination Vic screen memory absolute address
410+
* @param[in] qty Number of byte to copy
411+
*
412+
* @note Use c128lib_ReadFromVdcMemoryByCoordinates in vdc-global.asm
413+
*
414+
* @since 1.1.0
415+
*/
416+
.macro ReadFromVdcMemoryByCoordinates(xPos, yPos, destination, qty) {
417+
.errorif (xPos == -1 && yPos != -1), "xPos and yPos must be -1 at same time"
418+
.errorif (xPos != -1 && yPos == -1), "xPos and yPos must be -1 at same time"
419+
.errorif (xPos < -1 || yPos < -1), "xPos and yPos can't be lower than -1"
420+
.errorif (qty <= 0), "qty must be greater than 0"
421+
.errorif (qty > 255), "qty must be lower than 256"
422+
.if (xPos != -1 && yPos != -1) {
423+
ldx #$12
424+
lda #>getTextOffset80Col(xPos, yPos)
425+
jsr ScreenEditor.WRITEREG
426+
lda #<getTextOffset80Col(xPos, yPos)
427+
inx
428+
jsr ScreenEditor.WRITEREG
429+
}
430+
ldy #0
431+
CopyLoop:
432+
jsr ScreenEditor.READ80
433+
sta destination, y
434+
iny
435+
cpy #qty
436+
bne CopyLoop
437+
}
438+
.asserterror "ReadFromVdcMemoryByCoordinates(-1, 0, $beef, 100)", { ReadFromVdcMemoryByCoordinates(-1, 0, $beef, 100) }
439+
.asserterror "ReadFromVdcMemoryByCoordinates(0, -1, $beef, 100)", { ReadFromVdcMemoryByCoordinates(0, -1, $beef, 100) }
440+
.asserterror "ReadFromVdcMemoryByCoordinates(-2, 0, $beef, 100)", { ReadFromVdcMemoryByCoordinates(-2, 0, $beef, 100) }
441+
.asserterror "ReadFromVdcMemoryByCoordinates(0, -2, $beef, 100)", { ReadFromVdcMemoryByCoordinates(0, -2, $beef, 100) }
442+
.asserterror "ReadFromVdcMemoryByCoordinates(-2, -2, $beef, 100)", { ReadFromVdcMemoryByCoordinates(-2, -2, $beef, 100) }
443+
.asserterror "ReadFromVdcMemoryByCoordinates(2, 2, $beef, 0)", { ReadFromVdcMemoryByCoordinates(2, 2, $beef, 0) }
444+
.asserterror "ReadFromVdcMemoryByCoordinates(2, 2, $beef, 256)", { ReadFromVdcMemoryByCoordinates(2, 2, $beef, 256) }
445+
.assert "ReadFromVdcMemoryByCoordinates(-1, -1, $beef, 100)", { ReadFromVdcMemoryByCoordinates(-1, -1, $beef, 100) },
446+
{
447+
ldy #0; jsr $CDD8; sta $beef, y; iny; cpy #100; bne *-9;
448+
}
449+
.assert "ReadFromVdcMemoryByCoordinates(1, 1, $beef, 100)", { ReadFromVdcMemoryByCoordinates(1, 1, $beef, 100) },
450+
{
451+
ldx #$12; lda #0; jsr $CDCC; lda #81; inx; jsr $CDCC;
452+
ldy #0; jsr $CDD8; sta $beef, y; iny; cpy #100; bne *-9;
453+
}
454+
.assert "ReadFromVdcMemoryByCoordinates(1, 1, $beef, 255)", { ReadFromVdcMemoryByCoordinates(1, 1, $beef, 255) },
455+
{
456+
ldx #$12; lda #0; jsr $CDCC; lda #81; inx; jsr $CDCC;
457+
ldy #0; jsr $CDD8; sta $beef, y; iny; cpy #255; bne *-9;
458+
}
459+
460+
/**
461+
* @brief Read from Vdc internal memory and write it to Vic screen memory by
462+
* using source address.
463+
*
464+
* @param[in] source Vdc memory absolute address
465+
* @param[in] destination Vic screen memory absolute address
466+
* @param[in] qty Number of byte to copy
467+
*
468+
* @note Use c128lib_ReadFromVdcMemoryByAddress in vdc-global.asm
469+
*
470+
* @since 1.1.0
471+
*/
472+
.macro ReadFromVdcMemoryByAddress(source, destination, qty) {
473+
.errorif (qty <= 0), "qty must be greater than 0"
474+
.errorif (qty > 255), "qty must be lower than 256"
475+
ldx #$12
476+
lda #>source
477+
jsr c128lib.ScreenEditor.WRITEREG
478+
lda #<source
479+
inx
480+
jsr c128lib.ScreenEditor.WRITEREG
481+
482+
ldy #0
483+
CopyLoop:
484+
jsr c128lib.ScreenEditor.WRITE80
485+
sta destination, y
486+
iny
487+
cpy #qty
488+
bne CopyLoop
489+
}
490+
.asserterror "ReadFromVdcMemoryByAddress($beef, $baab, 0)", { ReadFromVdcMemoryByAddress($beef, $baab, 0) }
491+
.asserterror "ReadFromVdcMemoryByAddress($beef, $baab, 256)", { ReadFromVdcMemoryByAddress($beef, $baab, 256) }
492+
.assert "ReadFromVdcMemoryByAddress($beef, $baab, 100)", { ReadFromVdcMemoryByAddress($beef, $baab, 100) },
493+
{
494+
ldx #$12; lda #$be; jsr $CDCC; lda #$ef; inx; jsr $CDCC;
495+
ldy #0; jsr $CDCA; sta $baab, y; iny; cpy #100; bne *-9;
496+
}
497+
.assert "ReadFromVdcMemoryByAddress($beef, $baab, 255)", { ReadFromVdcMemoryByAddress($beef, $baab, 255) },
498+
{
499+
ldx #$12; lda #$be; jsr $CDCC; lda #$ef; inx; jsr $CDCC;
500+
ldy #0; jsr $CDCA; sta $baab, y; iny; cpy #255; bne *-9;
501+
}
502+
503+
/**
504+
* @brief Read from Vic screen memory and write it to Vdc internal memory by
505+
* using coordinates.
506+
*
507+
* @param[in] xPos X coord on Vic screen
508+
* @param[in] yPos Y coord on Vic screen
509+
* @param[in] destination Vdc internal memory absolute address
510+
* @param[in] qty Number of byte to copy
511+
*
512+
* @note Use c128lib_WriteToVdcMemoryByCoordinates in vdc-global.asm
513+
*
514+
* @since 1.1.0
515+
*/
516+
.macro WriteToVdcMemoryByCoordinates(source, xPos, yPos, qty) {
517+
.errorif (xPos == -1 && yPos != -1), "xPos and yPos must be -1 at same time"
518+
.errorif (xPos != -1 && yPos == -1), "xPos and yPos must be -1 at same time"
519+
.errorif (xPos < -1 || yPos < -1), "xPos and yPos can't be lower than -1"
520+
.errorif (qty <= 0), "qty must be greater than 0"
521+
.errorif (qty > 255), "qty must be lower than 256"
522+
.if (xPos != -1 && yPos != -1) {
523+
ldx #$12
524+
lda #>getTextOffset80Col(xPos, yPos)
525+
jsr c128lib.ScreenEditor.WRITEREG
526+
lda #<getTextOffset80Col(xPos, yPos)
527+
inx
528+
jsr c128lib.ScreenEditor.WRITEREG
529+
}
530+
ldy #0
531+
CopyLoop:
532+
lda source, y
533+
jsr c128lib.ScreenEditor.WRITE80
534+
iny
535+
cpy #qty
536+
bne CopyLoop
537+
}
538+
.asserterror "WriteToVdcMemoryByCoordinates($beef, -1, 0, 100)", { WriteToVdcMemoryByCoordinates($beef, -1, 0, 100) }
539+
.asserterror "WriteToVdcMemoryByCoordinates($beef, 0, -1, 100)", { WriteToVdcMemoryByCoordinates($beef, 0, -1, 100) }
540+
.asserterror "WriteToVdcMemoryByCoordinates($beef, -2, 0, 100)", { WriteToVdcMemoryByCoordinates($beef, -2, 0, 100) }
541+
.asserterror "WriteToVdcMemoryByCoordinates($beef, 0, -2, 100)", { WriteToVdcMemoryByCoordinates($beef, 0, -2, 100) }
542+
.asserterror "WriteToVdcMemoryByCoordinates($beef, -2, -2, 100)", { WriteToVdcMemoryByCoordinates($beef, -2, -2, 100) }
543+
.asserterror "WriteToVdcMemoryByCoordinates($beef, 2, 2, 0)", { WriteToVdcMemoryByCoordinates($beef, 2, 2, 0) }
544+
.asserterror "WriteToVdcMemoryByCoordinates($beef, 2, 2, 256)", { WriteToVdcMemoryByCoordinates($beef, 2, 2, 256) }
545+
.assert "WriteToVdcMemoryByCoordinates($beef, -1, -1, 100)", { WriteToVdcMemoryByCoordinates($beef, -1, -1, 100) },
546+
{
547+
ldy #0; lda $beef, y; jsr $CDCA; iny; cpy #100; bne *-9;
548+
}
549+
.assert "WriteToVdcMemoryByCoordinates($beef, 1, 1, 100)", { WriteToVdcMemoryByCoordinates($beef, 1, 1, 100) },
550+
{
551+
ldx #$12; lda #0; jsr $CDCC; lda #81; inx; jsr $CDCC;
552+
ldy #0; lda $beef, y; jsr $CDCA; iny; cpy #100; bne *-9;
553+
}
554+
.assert "WriteToVdcMemoryByCoordinates($beef, 1, 1, 255)", { WriteToVdcMemoryByCoordinates($beef, 1, 1, 255) },
555+
{
556+
ldx #$12; lda #0; jsr $CDCC; lda #81; inx; jsr $CDCC;
557+
ldy #0; lda $beef, y; jsr $CDCA; iny; cpy #255; bne *-9;
558+
}
559+
560+
/**
561+
* @brief Read from Vic screen memory and write it to Vdc internal memory by
562+
* using coordinates.
563+
*
564+
* @param[in] source Vdc memory absolute address
565+
* @param[in] destination Vic screen memory absolute address
566+
* @param[in] qty Number of byte to copy
567+
*
568+
* @note Use c128lib_WriteToVdcMemoryByAddress in vdc-global.asm
569+
*
570+
* @since 1.1.0
571+
*/
572+
.macro WriteToVdcMemoryByAddress(source, destination, qty) {
573+
.errorif (qty <= 0), "qty must be greater than 0"
574+
.errorif (qty > 255), "qty must be lower than 256"
575+
ldx #$12
576+
lda #>destination
577+
jsr c128lib.ScreenEditor.WRITEREG
578+
lda #<destination
579+
inx
580+
jsr c128lib.ScreenEditor.WRITEREG
581+
582+
ldy #0
583+
CopyLoop:
584+
lda source, y
585+
jsr c128lib.ScreenEditor.WRITE80
586+
iny
587+
cpy #qty
588+
bne CopyLoop
589+
}
590+
.asserterror "WriteToVdcMemoryByAddress($beef, $baab, 0)", { WriteToVdcMemoryByAddress($beef, $baab, 0) }
591+
.asserterror "WriteToVdcMemoryByAddress($beef, $baab, 256)", { WriteToVdcMemoryByAddress($beef, $baab, 256) }
592+
.assert "WriteToVdcMemoryByAddress($beef, $baab, 100)", { WriteToVdcMemoryByAddress($beef, $baab, 100) },
593+
{
594+
ldx #$12; lda #$ba; jsr $CDCC; lda #$ab; inx; jsr $CDCC;
595+
ldy #0; lda $beef, y; jsr $CDCA; iny; cpy #100; bne *-9;
596+
}
597+
.assert "WriteToVdcMemoryByAddress($beef, $baab, 255)", { WriteToVdcMemoryByAddress($beef, $baab, 255) },
598+
{
599+
ldx #$12; lda #$ba; jsr $CDCC; lda #$ab; inx; jsr $CDCC;
600+
ldy #0; lda $beef, y; jsr $CDCA; iny; cpy #255; bne *-9;
601+
}
602+
603+
/**
604+
* @brief Calculates memory offset of text cell specified by given coordinates
605+
* on 80 cols screen
606+
*
607+
* @param[in] xPos X coord on Vdc screen
608+
* @param[in] yPos Y coord on Vdc screen
609+
* @return Memory offset of Vdc specified coordinate
610+
*
611+
* @note Use c128lib_WriteToVdcMemoryByAddress in vdc-global.asm
612+
*
613+
* @since 1.1.0
614+
*/
615+
.function getTextOffset80Col(xPos, yPos) {
616+
.return xPos + Vdc.TEXT_SCREEN_80_COL_WIDTH * yPos
617+
}
618+
.assert "getTextOffset80Col(0,0) gives 0", getTextOffset80Col(0, 0), 0
619+
.assert "getTextOffset80Col(79,0) gives 79", getTextOffset80Col(79, 0), 79
620+
.assert "getTextOffset80Col(0,1) gives 80", getTextOffset80Col(0, 1), 80
621+
.assert "getTextOffset80Col(19,12) gives 979", getTextOffset80Col(19, 12), 979
622+
.assert "getTextOffset80Col(79,24) gives 1999", getTextOffset80Col(79, 24), 1999
623+
624+
/**
625+
* @brief Returns the address start of Vdc display memory data. This
626+
* is stored in Vdc register SCREEN_MEMORY_STARTING_HIGH_ADDRESS and
627+
* SCREEN_MEMORY_STARTING_LOW_ADDRESS.
628+
* The 16-bit value is stored in $FB and $FC.
629+
*
630+
* @note Use c128lib_GetVdcDisplayStart in vdc-global.asm
631+
*
632+
* @since 1.1.0
633+
*/
634+
.macro GetVdcDisplayStart() {
635+
ldx #Vdc.SCREEN_MEMORY_STARTING_HIGH_ADDRESS
636+
ReadVdc()
637+
638+
sta $fb
639+
inx
640+
ReadVdc()
641+
sta $fc
642+
}
643+
644+
/**
645+
* @brief Set the pointer to the RAM area that is to be updated.
646+
* The update pointer is stored in Vdc register CURRENT_MEMORY_HIGH_ADDRESS
647+
* and CURRENT_MEMORY_LOW_ADDRESS.
648+
*
649+
* @param[in] address Address of update area
650+
*
651+
* @note Use c128lib_SetVdcUpdateAddress in vdc-global.asm
652+
*
653+
* @since 1.1.0
654+
*/
655+
.macro SetVdcUpdateAddress(address) {
656+
ldx #Vdc.CURRENT_MEMORY_HIGH_ADDRESS
657+
lda #>address
658+
WriteVdc();
659+
660+
inx
661+
.var a1 = <address
662+
.var a2 = >address
663+
.if (a1 != a2) {
664+
lda #<address // include if different from hi-byte.
665+
}
666+
WriteVdc()
667+
}
668+
402669
/**
403670
* @brief Write a value into Vdc register without using kernal
404671
* routine instead of pure instruction. It needs register

0 commit comments

Comments
 (0)