;;; -*- tab-width: 8; -*- .export _vdc_read_reg, _vdc_read_addr, _vdc_read_mem .export _vdc_write_reg, _vdc_write_addr, _vdc_write_mem .export _vdc_load_thinfont .import popa, popax .importzp ptr1, ptr2 .include "c128.inc" .debuginfo on ;;; useful documentation: ;;; - 6502 instruction/addressing mode overview ;;; - http://www.obelisk.me.uk/6502/index.html ;;; - cc65 assembler interfacing with C ;;; - https://github.com/cc65/wiki/wiki/Parameter-passing-and-calling-conventions ;;; - https://github.com/cc65/wiki/wiki/Parameter-and-return-stacks ;;; - https://github.com/cc65/wiki/wiki/Using-runtime-zeropage-locations-in-assembly-language ;;; - Programming the VDC ;;; - Chapter 10 of http: //www.pagetable.com/docs/Commodore%20128%20Programmer%27s%20Reference%20Guide.pdf VDC_ADDR_REG := 18 VDC_MEM_REG := 31 ;;; unsigned char __fastcall__ vdc_read_reg (unsigned char reg); _vdc_read_reg: ldx #0 ; clear high byte of return register vdc_read_reg: sta VDC_INDEX @wait: bit VDC_INDEX ; busy wait until vdc is ready bpl @wait lda VDC_DATA rts ;;; unsigned __fastcall__ vdc_read_addr (unsigned char reg); _vdc_read_addr: tay ; copy vdc register iny ; next register is high byte of addr jsr vdc_read_reg tax ; save high byte in x return register tya jsr vdc_read_reg rts ;;; void __fastcall__ vdc_write_reg (unsigned char reg, unsigned char data); _vdc_write_reg: pha jsr popa tay pla vdc_write_reg: sty VDC_INDEX @wait: bit VDC_INDEX ; busy wait until vdc is ready bpl @wait sta VDC_DATA rts ;;; void __fastcall__ vdc_write_addr (unsigned char reg, unsigned addr); _vdc_write_addr: pha jsr popa ; this mustn't touch x (libsrc/runtime/popa.s) tay ; vdc register pla vdc_write_addr: pha txa ; get high byte of addr jsr vdc_write_reg iny ; next vdc register is high byte of addr pla jsr vdc_write_reg rts ;;; void __fastcall__ vdc_read_mem (unsigned dest, unsigned src, unsigned n); _vdc_read_mem: sta ptr1 ; store n stx ptr1+1 jsr popax ldy #VDC_ADDR_REG jsr vdc_write_addr jsr popax sta ptr2 stx ptr2+1 lda #VDC_MEM_REG sta VDC_INDEX ldy #0 ; offset into dest ;; first, loop over the high byte of n, 256 times ldx ptr1+1 ; get high byte of n beq @low ; skip if zero @cpyhi: bit VDC_INDEX bpl @cpyhi lda VDC_DATA sta (ptr2),y iny bne @cpyhi ; have we copied 256 bytes yet? inc ptr2+1 ; adjust dest pointer dex bne @cpyhi ; read 256 more bytes @low: ldx ptr1 ; get low byte of n beq @done ; skip if zero @cpy: bit VDC_INDEX bpl @cpy lda VDC_DATA sta (ptr2),y iny dex bne @cpy @done: rts ;;; void __fastcall__ vdc_write_mem (unsigned dest, const void* src, unsigned n); _vdc_write_mem: sta ptr1 ; store n stx ptr1+1 jsr popax sta ptr2 stx ptr2+1 jsr popax ldy #VDC_ADDR_REG jsr vdc_write_addr lda #VDC_MEM_REG sta VDC_INDEX ldy #0 ; offset into dest ;; first, loop over the high byte of n ldx ptr1+1 ; get high byte of n beq @low ; skip if zero @cpyhi: bit VDC_INDEX bpl @cpyhi lda (ptr2),y sta VDC_DATA iny bne @cpyhi ; have we copied 256 bytes yet? inc ptr2+1 ; adjust dest pointer dex bne @cpyhi ; read 256 more bytes @low: ldx ptr1 ; get low byte of n beq @done ; skip if zero @cpy: bit VDC_INDEX bpl @cpy lda (ptr2),y sta VDC_DATA iny dex bne @cpy @done: rts ;;; void __fastcall__ vdc_load_thinfont (void); _vdc_load_thinfont: ;; save MMU register lda $0 pha lda $1 pha ;; map in alternate font lda #$FF sta $0 lda #$33 sta $1 ;; call kernal load font routine jsr $FF62 ;; restore MMU pla sta $1 pla sta $0 rts