-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsystem.asm
More file actions
481 lines (424 loc) · 19.2 KB
/
Copy pathsystem.asm
File metadata and controls
481 lines (424 loc) · 19.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
// ***********************************************************************************************************************************************
// ***********************************************************************************************************************************************
//
// Microvision System Code
// =======================
//
// Functionality:
//
// LCD Interface : bit writing, polarity reversal, update, number font generation, number area clear, number screen rendering.
// Speaker : Sound managed through update (overall pitch) and polarity reversal (length)
// Other : Random Number Generation
//
// Pages Occupied:
// Page 15 ($3C0), 0 ($000), 1 ($040), 2 ($080)
//
// Written by Paul Robson January 2014
//
// ***********************************************************************************************************************************************
// ***********************************************************************************************************************************************
HWNotDataClock = 7 // R Latch connected to not- dataclock on LCD
HWLatchPulse = 6 // R Latch connected to Latch Pulse on LCD
HWKeyLeftCol = 10 // Keyboard column selection R Latches
HWKeyMiddleCol = 9
HWKeyRightCol = 8
HWSpeaker = 0 // Speaker line
// Page 0 of RAM Allocation
// ========================
// 0-3 Lookup Table (8,4,2,1)
// 4 Sound Timer - off when zero
// 5 Pitch
// 6 Pitch Counter - adds Pitch to Pitch Counter, bit 3 is copied to the sound bit
// 7 Temporary value used by WriteBits routine. Note that WriteBitsX routines can operate with X register non zero
// provided memory location (X,7) is kept as this will be overwritten.
// 8 Line pointer (y position on screen)
// 9 Offset pointer (in page X+4)
// 10,11 Seed values for the 4 bit RNG.
OSDSoundTimer = 4 // Non-zero for sound to play - decremented when > zero ever polarity reversal (frame)
OSDPitch = 5 // Pitch - added to PitchCounter every time Address Latch->Holding latch is performed
__PitchCounter = 6 // Bit 3 of the PitchCounter is mirrored to the speaker line.
__LinePointer = 8
__OffsetPointer = 9
__XNRandom = 10 // Random Number seeds.
__CNRandom = 11
// ***********************************************************************************************************************************************
//
// Program starts here
//
// ***********************************************************************************************************************************************
// Page 15 ($3C0) [2 bytes spare]
// ***********************************************************************************************************************************************
StartLibrary
ldx 0 // Set up the bit table at M(0,0)
tcy 0
tcmiy 8
tcmiy 4
tcmiy 2
tcmiy 1
tcmiy 0 // Turn sound off by setting timer to zero.
tcy HWNotDataClock // set !dataclock 1, latch pulse 0
setr // Initial state of control lines.
tcy HWLatchPulse
rstr
lbr __StartProgram
// ***********************************************************************************************************************************************
//
// Output a bit position to the LCD Driver, either row or column. There are four near identical subroutines, which output
// M(M(XY)), M(XY), Y or A. It converts the value to a sequence of nibbles with the nth bit set, (where 0 is the left most bit/upper bit)
//
// Four phases - it one's complements the position so 15 is now the left most
// - it outputs zeros before the position
// - it outputs the bit pattern at the position
// - it outputs the bit pattern after the position
//
// Requires a table at (X0) to contain 8,4,2,1 (bit lookup)
// Uses (X7) as temporary storage - this is used for efficiency (so we don't keep changing Y)
//
// ***********************************************************************************************************************************************
OSWriteBitsM // Position in M(XY)
tmy
OSWriteBitsY // Position in Y
tya
OSWriteBitsA // A = 0..15, Bit position (15 = right most)
cpaiz // Invert A so that 15 is now the left most pixel.
dan
tcy HWNotDataClock // Y = Not Data Clock
tam // Save to 0:HWNotDataClock
cla
tdo // set the output lines to $00.
tma // Restore the value.
__WBStart
a4aac // Add 4 to the Bit position - if 12..15 (e.g. the right position),status will be set and it will be 0..3
br __WBEndStart
rstr // Pulse Not(Data Clock) to write out leading zero nibbles.
setr
br __WBStart
__WBEndStart
tay // Point to the look up table
tma // Read it to get the nibble to write
tdo // Write to the O lines
tcy HWNotDataClock // Pulse the not data clock to write it out.
rstr
setr
cla // Clear the O line again
tdo
tma // Read the original value back (e.g. the value at the start)
__WBEnd
a12aac // Subtract 4. Status set if value was >= 4
br __WBEndNibble // so output one zero nibble
retn
__WBEndNibble
rstr // Pulse the not data clock line
setr
br __WBEnd // And try it again.
// ***********************************************************************************************************************************************
//
// Copy addressed latches to holding latches, updating the display. Play sound if the sound counter is non-zero
//
// ***********************************************************************************************************************************************
OSUpdateDisplay
ldx 0
tcy OSDSoundTimer // Check sound timer
mnez // If it is non-zero
br __UDMakeSound // If so, go to make sound ....
OSUpdateDisplayNoSound
tcy HWLatchPulse // Pulse the latch pulse
setr
rstr
retn
__UDMakeSound
tcy OSDPitch // Read pitch
tma
tcy __PitchCounter // Add into pitch counter
amaac
tam // Write pitch counter back
tbit1 3 // Is MSB set ?
br __UDBitSet
tcy HWSpeaker // No, clear speaker bit
rstr
br OSUpdateDisplayNoSound
__UDBitSet // Yes, set speaker bit
tcy HWSpeaker
setr
br OSUpdateDisplayNoSound
page
// ***********************************************************************************************************************************************
//
// Create/Update Digit Pattern for Row X : X = 4..7. Pattern# is in (X,0), data starts at (X,1)
//
// (Note: all bit patterns are reversed, assuming BlockBuster PLA + Wiring)
// ***********************************************************************************************************************************************
// Page 0 ($000) [1 byte spare]
// ***********************************************************************************************************************************************
OSCreateGraphicY // Use graphic Y in column X
tya
OSCreateGraphicA // Use graphic A in column X
tcy 0 // Store A in offset 0
tam
OSUpdateGraphic // Update image in column X
tcy 0 // Start at location zero.
tma // Load the character value
tcy 1 // Point to the store area.
tam // Store it in M(X,Y)
a6aac // is it >= 10
br __CGExit1 // if so, exit now after erasing the tam before
mnez // If non zero goto 1-9 code
br __CG1To9
tcmiy 7 // Output a zero. ***
tcmiy 5 // * *
tcmiy 5 // * *
__CG0b
tcmiy 5 // * *
__CG0a
tcmiy 7 // ***
br __CGExit
__CG1To9 // M(X,Y) contains the number
tma // Load into A
a11aac // Will cause carry to be set if 5,6,7,8,9
br __CG5To9
__CG1To4 // Process 1 to 4.
dman // Now 0-3 representing 1-4
cpaiz // Now S will be set if it was 0 (was originally 1)
br __CG1 // So draw the 1 code if so, a vertical line.
tma // Otherwise, reload the number from A, it is 2,3 or 4.
a12aac // This will cause a carry if it was originally 4
br __CG4 // If so , do 4 code. Now it is 2 or 3 (now A = 14 and 15 for these)
tcmiy 7 // So do *** which is the top 3 lines for both 2 and 3.
tcmiy 4 // then *
tcmiy 7 // then ***
iac // Carry will be set if it is 3 (it was 15), in which case do the tail to 5 (backwards L)
br __CG5a
tcmiy 1 // do *.. then solid tail and exit (e.g. bottom rows of 2) (e.g. forwards L)
br __CG0a
__CG4 // Output a '4'.
tcmiy 5 // *.*
tcmiy 5 // *.*
tcmiy 7 // ***
br __CG1a // Use last two lines of 1 code to output the rest of the 4.
__CG1 // Output a '1'.
tcmiy 4
__CG1b // 4 x ..*
tcmiy 4
tcmiy 4
__CG1a // 2 x ..*
tcmiy 4
tcmiy 4
br __CGExit
__CG5To9 // Do 5,6,7,8,9, represented by 0,1,2,3,4 at this point due to the A11AAC.
tcmiy 7 // always a top line *** for 5-9.
a14aac // will drop through if 5 or 6 (14 and 15), 7,8,9 are 0,1,2.
br __CG7To9
tcmiy 1 // Output *.. - these are common for both 5 and 6.
tcmiy 7 // Output ***
iac // Will set carry if it was 6 (6 -> 1 -> 15 after a11aac and a15aac)
br __CG0b // In which case draw the bottom two lines of '0'
__CG5a
tcmiy 4 // Draw ..* - this is the reverse L and the bottom two lines of '5'
br __CG0a // Draw Bottom line and exit.
__CG7To9
cpaiz // (0,1,2 representing 7,8,9). S will be set if A was zero following cpaiz.
br __CG1b // In which case it was 7, so draw the tail (4 x ..*)
tcmiy 5 // Draw *.* which are commonalities for 8 and 9.
tcmiy 7 // Draw ***
iac // if it was 8, then draw the *.* and *** e.g. bottom of 8
br __CG0b
br __CG5a // Draw tail of 9
__CGExit1 // >= 10, a value was stored though so clear it
tcmiy 0
__CGExit
tcy 0 // Load current value into A
tma
retn // End of routine.
page
// ***********************************************************************************************************************************************
//
// Render the text/number display.
//
// On entry, Y contains the vertical position of the top line of the text. This needs a label 'RenderTextExit' to be defined as this is a
// jump in, jump out routine *not* a subroutine, as it uses subroutines and we only have one level.
//
// This does the *whole* of the rendering including polarity switching.
//
// ***********************************************************************************************************************************************
// Page 1 ($040) [1 byte spare]
// ***********************************************************************************************************************************************
OSRenderTextDisplay
tya
ldx 0 // Point to page zero
tcy __LinePointer // Write vertical screen position to line pointer
tamiyc
tcmiy 1 // Write offset (initially 1) to offset pointer
call OSSwitchPolarity // Switch polarity, start of frame.
__RTDLoop
tcy __LinePointer // Read line pointer
lcall OSWriteBitsM // and write that column value.
call __RTDNibble2 // Read offset pointer into Y
ldx 4 // Output nibble from 4,5,6 and 7.
call __RTDNibble // offset pointer is reloaded on exit.
ldx 5
call __RTDNibble
ldx 6
call __RTDNibble
ldx 7
call __RTDNibble
lcall OSUpdateDisplay // Update the display.
tcy __LinePointer // Bump line pointer
imac
tamiyc // Save and point to offset pointer
imac // Read and increment and update
tam // Write back
tay // Put in Y
ynec 6 // Do for offsets 1-5.
br __RTDLoop
lbr OSExternalRenderTextExit // Exit the rendering.
__RTDNibble
tma // Read the (X,Offset) into
tdo // Put on output lines.
ldx 0 // Back to page 0.
tcy HWNotDataClock // now controlling the data clock
rstr // 1->0->1 pulse on data clock
setr
__RTDNibble2
tcy __OffsetPointer // Read the offset pointer into Y for next time
tmy
retn
// ***********************************************************************************************************************************************
//
// Call to switch polarity. Leaves !DC = 0 on exit, so that the next word latch (a rising edge on !DC) clocks in the data
// at the right time - setting it back to 1 would cause a clock here. Decrement the sound timer if it is greater than zero.
//
// ***********************************************************************************************************************************************
OSSwitchPolarity
ldx 0
tcy OSDSoundTimer // Point Y to sound timer
dman // Load and decrement, S set if wasn't zero.
br __SPNotZero
cla // If was zero, leave it at zero
__SPNotZero
tam // Write it back.
tcy HWLatchPulse // On Entry, !DC = 1, LP = 0
setr // !DC = 1, LP = 1 - copies the addressed latches to the holding latches (no effect)
tcy HWNotDataClock // set !dataclock to 0
rstr
tcy HWLatchPulse // Falling Edge on Latch Pulse with !DC = 0, toggles polarity
rstr
retn // Leave !DC = 0 for latching next word.
// ***********************************************************************************************************************************************
//
// Clear the display space to 0 (digit) and all spaces
//
// ***********************************************************************************************************************************************
OSClearDisplaySpace
tcy 5 // Start at offset 5
cla // Value to write out
__CDSLoop
ldx 4 // Write to bank 4,5,6,7 in turn.
tam
ldx 5
tam
ldx 6
tam
ldx 7
tamdyn // Keep doing until Y goes -ve
br __CDSLoop
retn
page
// ***********************************************************************************************************************************************
//
// Random Number Generator (preserves Y), sets X to zero.
//
// ***********************************************************************************************************************************************
// Page 2 ($080) [1 byte spare]
// ***********************************************************************************************************************************************
OSRandomNumber
ldx 0 // Access page 0.
tya // Save Y in NotDataClock temp
tcy HWNotDataClock
tam
tcy __XNRandom // read XNext
tma // A = XNext value
tcy __CNRandom // Y points to CNext
alem // S set if XNext <= CNext
br __OSRLNoDecrement // so clear if CNext < XNext
dan // so A = XNext-1 if CNext < XNext
__OSRLNoDecrement
xma // now : A is old CNext, CNext is XNext maybe -1
tcy __XNRandom // now calculate XNext := XNext + old CNext + 1
amaac // add XNext to old CNext
iac // add one
tam // write back to XNext
tcy HWNotDataClock // restore Y
tmy
retn
// ***********************************************************************************************************************************************
//
// Same as render text display but calls OSUpdateGraphic on each bank first
//
// ***********************************************************************************************************************************************
OSUpdateAllAndRenderTextDisplay
ldx 0 // Save Y (vertical position) in NotDataClock temp in bank 0
tya
tcy HWNotDataClock
tam
ldx 4 // Update 4 banks
lcall OSUpdateGraphic
ldx 5
lcall OSUpdateGraphic
ldx 6
lcall OSUpdateGraphic
ldx 7
lcall OSUpdateGraphic
ldx 0 // Restore vertical position
tcy HWNotDataClock
tmy
lbr OSRenderTextDisplay // and then render the text
// ***********************************************************************************************************************************************
//
// Add 1, 10, 100 to current 'score' in banks 4,5,6,7 - if used as score.
//
// These routines are jump in jump out routines.
//
// ***********************************************************************************************************************************************
OSIncrementHundred
tcy 1 // Jump into hundreds
br __Increment100
OSIncrementTen
tcy 1 // Jump into tens
br __Increment10
OSIncrementOne
ldx 7 // Start at least significant digit
tcy 1 // Carry forward 1 to start with
call __Increment // Add into first digit, carry out is in Y
__Increment10
ldx 6 // tens
call __Increment
__Increment100
ldx 5 // hundreds
call __Increment
ldx 4 // thousands
call __Increment
lbr OSExternalIncrementExit
// Add Y to (X,0) - fix for decimal - Y is carry out
__Increment
tya // Save carry forward in A
tcy 0 // Point to digit (e.g. M(X,0))
amaac // add current digit to the carry forward
tam // Write it back to M(X,0)
a6aac // add 6, S if overflow (e.g. it was 10, decimal carry)
br __Overflow
retn // No overflow, return Y = 0 e.g. no carry forward.
__Overflow
tcmiy 0 // reset current digit to zero, set Y to 1 carry forward
retn // and exit - handy instruction :)
// ***********************************************************************************************************************************************
//
// Start of Main Program
//
// ***********************************************************************************************************************************************
page
__StartProgram
// Updates
//
// 17-1-14 Changes OSUpdateDisplay and OSSwitchPolarity to set X = 0 at the start, pretty much compulsory.
// (all change X except OSWriteBits* which can work in any page if you sacrifice or preserve (X,7))
//