]> git.sur5r.net Git - c128-kasse/blob - src/vdc_util.s
patch charset to include umlauts
[c128-kasse] / src / vdc_util.s
1 ;;; -*- tab-width: 8; -*-
2         .export         _vdc_read_reg, _vdc_read_addr, _vdc_read_mem
3         .export         _vdc_write_reg, _vdc_write_addr, _vdc_write_mem
4         .export         _vdc_load_thinfont
5         .import         popa, popax
6         .importzp       ptr1, ptr2
7         .include        "c128.inc"
8         .debuginfo      on
9
10 ;;; useful documentation:
11 ;;; - 6502 instruction/addressing mode overview
12 ;;;     - http://www.obelisk.me.uk/6502/index.html
13 ;;; - cc65 assembler interfacing with C
14 ;;;     - https://github.com/cc65/wiki/wiki/Parameter-passing-and-calling-conventions
15 ;;;     - https://github.com/cc65/wiki/wiki/Parameter-and-return-stacks
16 ;;;     - https://github.com/cc65/wiki/wiki/Using-runtime-zeropage-locations-in-assembly-language
17 ;;; - Programming the VDC
18 ;;;     - Chapter 10 of http: //www.pagetable.com/docs/Commodore%20128%20Programmer%27s%20Reference%20Guide.pdf
19
20 VDC_ADDR_REG    := 19
21 VDC_MEM_REG     := 31
22
23 ;;; unsigned char __fastcall__ vdc_read_reg (unsigned char reg);
24 _vdc_read_reg:
25         ldx #0                  ; clear high byte
26 vdc_read_reg:       
27         sta VDC_INDEX
28
29 @wait:  bit VDC_INDEX           ; busy wait until vdc is ready
30         bpl @wait
31
32         lda VDC_DATA
33         rts
34
35 ;;; unsigned __fastcall__ vdc_read_addr (unsigned char reg);
36 _vdc_read_addr:
37         tay                     ; save copy of vdc reg
38         jsr vdc_read_reg
39         tax                     ; save high byte
40         dey                     ; set low byte vdc reg
41         tya
42         jsr vdc_read_reg
43         rts
44
45 ;;; void __fastcall__ vdc_write_reg (unsigned char reg, unsigned char data);
46 _vdc_write_reg:
47         pha
48         jsr popa
49         tay
50         pla
51 vdc_write_reg:
52         sty VDC_INDEX
53
54 @wait:  bit VDC_INDEX           ; busy wait until vdc is ready
55         bpl @wait
56
57         sta VDC_DATA
58         rts
59
60 ;;; void __fastcall__ vdc_write_addr (unsigned char reg, unsigned addr);
61 _vdc_write_addr:
62         pha
63         jsr popa
64         tay
65         pla
66 vdc_write_addr:
67         jsr vdc_write_reg
68         txa                     ; get high byte of addr
69         dey
70         jsr vdc_write_reg
71         rts
72
73 ;;; void __fastcall__ vdc_read_mem (unsigned dest, unsigned src, unsigned n);
74 _vdc_read_mem:
75         sta ptr1                ; store n
76         stx ptr1+1
77
78         jsr popax
79         ldy #VDC_ADDR_REG
80         jsr vdc_write_addr
81
82         jsr popax
83         sta ptr2
84         stx ptr2+1
85
86         lda #VDC_MEM_REG
87         sta VDC_INDEX
88
89         ldy #0                  ; offset into dest
90
91         ;; first, loop over the high byte of n, 256 times
92         ldx ptr1+1              ; get high byte of n
93         beq @low                ; skip if zero
94
95 @cpyhi: bit VDC_INDEX
96         bpl @cpyhi
97
98         lda VDC_DATA
99         sta (ptr2),y
100         iny
101         bne @cpyhi              ; have we copied 256 bytes yet?
102
103         inc ptr2+1              ; adjust dest pointer
104         dex
105         bne @cpyhi              ; read 256 more bytes
106         
107 @low:   ldx ptr1                ; get low byte of n
108         beq @done               ; skip if zero
109         
110 @cpy:   bit VDC_INDEX
111         bpl @cpy
112
113         lda VDC_DATA
114         sta (ptr2),y
115         iny
116         dex
117         bne @cpy
118
119 @done:  rts
120
121 ;;; void __fastcall__ vdc_write_mem (unsigned dest, const void* src, unsigned n);
122 _vdc_write_mem:
123         sta ptr1                ; store n
124         stx ptr1+1
125
126         jsr popax
127         sta ptr2
128         stx ptr2+1
129
130         jsr popax
131         ldy #VDC_ADDR_REG
132         jsr vdc_write_addr
133
134         lda #VDC_MEM_REG
135         sta VDC_INDEX
136
137         ldy #0                  ; offset into dest
138
139         ;; first, loop over the high byte of n
140         ldx ptr1+1              ; get high byte of n
141         beq @low                ; skip if zero
142
143 @cpyhi: bit VDC_INDEX
144         bpl @cpyhi
145
146         lda (ptr2),y
147         sta VDC_DATA
148         iny
149         bne @cpyhi              ; have we copied 256 bytes yet?
150
151         inc ptr2+1              ; adjust dest pointer
152         dex
153         bne @cpyhi              ; read 256 more bytes
154         
155 @low:   ldx ptr1                ; get low byte of n
156         beq @done               ; skip if zero
157         
158 @cpy:   bit VDC_INDEX
159         bpl @cpy
160
161         lda (ptr2),y
162         sta VDC_DATA
163         iny
164         dex
165         bne @cpy
166
167 @done:  rts
168
169 ;;; void __fastcall__ vdc_load_thinfont (void);
170 _vdc_load_thinfont:
171         ;; save MMU register
172         lda $0
173         pha
174         lda $1
175         pha
176
177         ;; map in alternate font
178         lda #$FF
179         sta $0
180         lda #$33
181         sta $1
182
183         ;; call kernal load font routine
184         jsr $FF62
185         
186         ;; restore MMU
187         pla
188         sta $1
189         pla
190         sta $0
191         rts