OpenCores
URL https://opencores.org/ocsvn/rf68000/rf68000/trunk

Subversion Repositories rf68000

[/] [rf68000/] [trunk/] [software/] [examples/] [boot.asm] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 robfinch
;-------------------------------------------------------------------------------
2
;
3
; system memory map
4
;
5
;
6
; 00000000 +----------------+      <+
7
;          | startup sp,pc  | 8 B   |
8
; 00000008 +----------------+       |
9
;                                        |    vectors     | pair shared+
10
; 00000400 +----------------+       |
11
;                                        |   bios mem     |       |
12
; 00001000 +----------------+       |
13
;                                        |   bios code    |       |
14
; 00008000 +----------------+      <+
15
;                                        |    unused      |
16
; 00040000 +----------------+
17
;                                        |   local ram    |
18
; 00042000 +----------------+
19
;                                        |    unused      |
20
; 00100000 +----------------+
21
;                                        |   global ram   |
22
; 00101000 +----------------+
23
;                                        | serial rcvbuf  |
24
; 00102000 +----------------+
25
;                                        |    unused      |
26
; 20000000 +----------------+
27
;          |                |
28
;          |                |
29
;          |                |
30
;          :  dram memory   : 512 MB
31
;          |                |
32
;          |                |
33
;          |                |
34
; 40000000 +----------------+
35
;          |                |
36
;          :     unused     :
37
;          |                |
38
; FD000000 +----------------+
39
;          |                |
40
;          :    I/O area    : 1.0 M
41
;          |                |
42
; FFE00000 +----------------+
43
;          |                |
44
;          :     unused     :
45
;          |                |
46
; FFFFFFFF +----------------+
47
;
48
;-------------------------------------------------------------------------------
49
;
50
CTRLC   EQU             $03
51
CTRLH   EQU             $08
52
CTRLS   EQU             $13
53
CTRLX   EQU             $18
54
CTRLZ   EQU             $1A
55
LF              EQU             $0A
56
CR              EQU             $0D
57
XON             EQU             $11
58
XOFF    EQU             $13
59
 
60
SC_F12  EQU    $07
61
SC_C    EQU    $21
62
SC_T    EQU    $2C
63
SC_Z    EQU    $1A
64
SC_KEYUP        EQU             $F0
65
SC_EXTEND   EQU         $E0
66
SC_CTRL         EQU             $14
67
SC_RSHIFT       EQU             $59
68
SC_NUMLOCK      EQU             $77
69
SC_SCROLLLOCK   EQU     $7E
70
SC_CAPSLOCK             EQU     $58
71
SC_ALT          EQU             $11
72
SC_LSHIFT       EQU             $12
73
SC_DEL          EQU             $71             ; extend
74
SC_LCTRL        EQU             $58
75
SC_TAB      EQU         $0D
76
 
77
TEXTREG         EQU     $1E3FF00        ; virtual addresses
78
txtscreen       EQU     $1E00000
79
semamem         EQU     $1E50000
80
ACIA                    EQU     $1E60000
81
ACIA_RX         EQU     0
82
ACIA_TX         EQU     0
83
ACIA_STAT       EQU     4
84
ACIA_CMD        EQU     8
85
ACIA_CTRL       EQU     12
86
PLIC                    EQU     $1E90000
87
MMU                             EQU $FDC00000   ; physical address
88
leds                    EQU     $1EFFF00        ; virtual addresses
89
keybd                   EQU     $1EFFE00
90
KEYBD                   EQU     $1EFFE00
91
RAND                    EQU     $1EFFD00
92
RAND_NUM        EQU     $1EFFD00
93
RAND_STRM       EQU     $1EFFD04
94
RAND_MZ         EQU $1EFFD08
95
RAND_MW         EQU     $1EFFD0C
96
RST_REG         EQU     $1EFFC00
97
IO_BITMAP       EQU $1F00000
98
IOFocus         EQU     $0100000
99
 
100
SERIAL_SEMA     EQU     2
101
KEYBD_SEMA      EQU     3
102
RAND_SEMA               EQU     4
103
SCREEN_SEMA     EQU     5
104
MEMORY_SEMA EQU 6
105
TCB_SEMA                EQU     7
106
 
107
        data
108
        dc.l            $00040FFC
109
        dc.l            start
110
        dc.l            bus_err
111
        dc.l            0
112
        dc.l            illegal_trap            * ILLEGAL instruction
113
        dc.l            0
114
        dc.l            EXCEPTION_6                     * CHK
115
        dc.l            EXCEPTION_7                     * TRAPV
116
        dc.l            0
117
        dc.l            0
118
 
119
        ; 10
120
        dc.l            0
121
        dc.l            0
122
        dc.l            0
123
        dc.l            0
124
        dc.l            0
125
        dc.l            0
126
        dc.l            0
127
        dc.l            0
128
        dc.l            0
129
        dc.l            0
130
 
131
        ; 20
132
        dc.l            0
133
        dc.l            0
134
        dc.l            0
135
        dc.l            0
136
        dc.l            SpuriousIRQ
137
        dc.l            0
138
        dc.l            0
139
        dc.l            irq3_rout
140
        dc.l            0
141
        dc.l            0
142
 
143
        ; 30
144
        dc.l            TickIRQ                                         ; IRQ 30 - timer / keyboard
145
        dc.l            nmi_rout
146
        dc.l            0
147
        dc.l            0
148
        dc.l            0
149
        dc.l            trap3                                                   ; breakpoint
150
        dc.l            0
151
        dc.l            0
152
        dc.l            0
153
        dc.l            0
154
 
155
        ; 40
156
        dc.l            0
157
        dc.l            0
158
        dc.l            0
159
        dc.l            0
160
        dc.l            0
161
        dc.l            0
162
        dc.l            0
163
        dc.l            TRAP15
164
        dc.l            0
165
        dc.l            0
166
 
167
        ; 50
168
        dc.l            0
169
        dc.l            0
170
        dc.l            0
171
        dc.l            0
172
        dc.l            0
173
        dc.l            0
174
        dc.l            0
175
        dc.l            0
176
        dc.l            0
177
        dc.l            io_irq
178
 
179
        ; 60
180
        dc.l            KeybdIRQ
181
        dc.l            SerialIRQ
182
        dc.l            0
183
        dc.l            brdisp_trap
184
        dc.l            0
185
        dc.l            0
186
        dc.l            0
187
        dc.l            0
188
        dc.l            0
189
        dc.l            0
190
 
191
        org                     $400
192
 
193
InstalledIRQ:
194
        dc.l            0
195
        dc.l            0
196
        dc.l            0
197
        dc.l            0
198
        dc.l            0
199
        dc.l            0
200
        dc.l            0
201
        dc.l            0
202
 
203
        dc.l            0
204
        dc.l            0
205
        dc.l            0
206
        dc.l            0
207
        dc.l            0
208
        dc.l            0
209
        dc.l            0
210
        dc.l            0
211
 
212
        dc.l            0
213
        dc.l            0
214
        dc.l            0
215
        dc.l            0
216
        dc.l            0
217
        dc.l            0
218
        dc.l            0
219
        dc.l            0
220
 
221
        dc.l            0
222
        dc.l            0
223
        dc.l            0
224
        dc.l            0
225
        dc.l            0
226
        dc.l            0
227
        dc.l            0
228
        dc.l            0
229
 
230
        dc.l            0
231
        dc.l            0
232
        dc.l            0
233
        dc.l            0
234
        dc.l            0
235
        dc.l            0
236
        dc.l            0
237
        dc.l            0
238
 
239
        dc.l            0
240
        dc.l            0
241
        dc.l            0
242
        dc.l            0
243
        dc.l            0
244
        dc.l            0
245
        dc.l            0
246
        dc.l            0
247
 
248
        dc.l            0
249
        dc.l            0
250
        dc.l            0
251
        dc.l            0
252
        dc.l            0
253
        dc.l            0
254
        dc.l            0
255
        dc.l            0
256
 
257
        dc.l            0
258
        dc.l            0
259
        dc.l            0
260
        dc.l            0
261
        dc.l            0
262
        dc.l            0
263
        dc.l            0
264
        dc.l            0
265
 
266
        org                     $500
267
 
268
;-------------------------------------------------------------------------------
269
;-------------------------------------------------------------------------------
270
 
271
; BIOS variables which must be local (not shared) to each core
272
 
273
CursorRow       equ             $40000
274
CursorCol       equ             $40001
275
TextPos         equ             $40002
276
TextCurpos      equ     $40002
277
TextScr                 equ     $40004
278
S19StartAddress equ     $40008
279
KeybdEcho               equ     $4000C
280
KeybdWaitFlag   equ     $4000D
281
CmdBuf                  equ $40040
282
CmdBufEnd               equ     $40080
283
fgColor                 equ     $40084
284
bkColor                 equ     $40088
285
TextRows                equ     $4008C
286
TextCols                equ     $4008D
287
Regsave                 equ     $40100
288
numBreakpoints  equ             8
289
BreakpointFlag  equ             $40200
290
NumSetBreakpoints       equ     $40202  ; to $40203
291
Breakpoints                     equ             $40220  ; to $40240
292
BreakpointWords equ             $40280  ; to $402A0
293
;RunningTCB  equ $40300
294
TimerStack      equ     $40BFC
295
 
296
; Keyboard buffer is in shared memory
297
memend                  equ $00100004
298
KeybdLEDs               equ     $0010000E
299
_KeyState1      equ     $0010000F
300
_KeyState2      equ     $00100010
301
_KeybdHead      equ     $00100011
302
_KeybdTail      equ     $00100012
303
_KeybdCnt               equ     $00100013
304
KeybdID                 equ     $00100016
305
_KeybdBuf               equ     $00100020
306
S19Checksum     equ     $00100150
307
SerTailRcv      equ     $00100160
308
SerHeadRcv      equ     $00100162
309
SerRcvXon               equ     $00100164
310
SerRcvXoff      equ     $00100165
311
SerRcvBuf               equ     $00101000
312
 
313
        include "..\Femtiki\source\kernel\Femtiki_vars.x68"
314
 
315
        code
316
        align           2
317
start:
318
        move.w #$2700,sr                                        ; enable level 6 and higher interrupts
319
        moveq #0,d0                                                             ; set address space zero
320
        movec d0,asid
321
        ; Prepare local variable storage
322
        move.w #1023,d0                                         ; 1024 longs to clear
323
        lea     $40000,a0                                                       ; non shared local memory address
324
.0111:
325
        clr.l   (a0)+                                                           ; clear the memory area
326
        dbra d0,.0111
327
        move.l #$1fffff,fgColor         ; set foreground / background color
328
        move.l #$00003f,bkColor
329
        movec.l coreno,d0                                       ; get core number (2 to 9)
330
        subi.b #2,d0                                                    ; adjust (0 to 7)
331
        mulu #16384,d0                                          ; compute screen location
332
        addi.l #$FD000000,d0
333
        move.l d0,TextScr
334
        move.b #64,TextCols                             ; set rows and columns
335
        move.b #32,TextRows
336
        movec.l coreno,d0                                       ; get core number
337
        cmpi.b #2,d0
338
        bne     start_other
339
        move.b d0,IOFocus                                       ; Set the IO focus in global memory
340
        bsr InitMMU                                                             ; Can't access anything till this is done
341
        bsr     InitIOBitmap                                    ; not going to get far without this
342
        bsr     InitSemaphores
343
        bsr     InitRand
344
        bsr     Delay3s                                         ; give devices time to reset
345
        bsr     clear_screen
346
 
347
        bsr     _KeybdInit
348
;       bsr     InitIRQ
349
        bsr     SerialInit
350
 
351
        ; Write startup message to screen
352
 
353
        lea     msg_start,a1
354
        bsr     DisplayString
355
;       bsr     FemtikiInit
356
        movec   coreno,d0
357
        swap d0
358
        moveq   #1,d1
359
        bsr     UnlockSemaphore ; allow another cpu access
360
        moveq   #0,d1
361
        bsr     UnlockSemaphore ; allow other cpus to proceed
362
        move.w #$A4A4,leds                      ; diagnostics
363
        bsr     init_plic                               ; initialize platform level interrupt controller
364
        bra     StartMon
365
        bsr     cpu_test
366
;       lea     brdisp_trap,a0  ; set brdisp trap vector
367
;       move.l  a0,64*4
368
 
369
loop2:
370
        move.l  #-1,d0
371
loop1:
372
        move.l  d0,d1
373
        lsr.l           #8,d1
374
        lsr.l           #8,d1
375
        move.b  d1,leds
376
        dbra            d0,loop1
377
        bra                     loop2
378
 
379
start_other:
380
        bsr                     Delay3s2                                                ; need time for system setup (io_bitmap etc.)
381
        bsr                     clear_screen
382
        movec           coreno,d1
383
        bsr                     DisplayByte
384
        lea                     msg_core_start,a1
385
        bsr                     DisplayString
386
;       bsr                     FemtikiInitIRQ
387
do_nothing:
388
        bra                     StartMon
389
        bra                     do_nothing
390
 
391
;------------------------------------------------------------------------------
392
; Initialize the MMU to allow thread #0 access to IO
393
;------------------------------------------------------------------------------
394
        align 2
395
mmu_adrtbl:     ; virtual address[24:16], physical address[31:16] bytes reversed!
396
        dc.l    $0010,$10000300 ; global scratch pad
397
        dc.l    $01E0,$00FD0300
398
        dc.l    $01E1,$01FD0300
399
        dc.l    $01E2,$02FD0300
400
        dc.l  $01E3,$03FD0300
401
        dc.l    $01E5,$05FD0300
402
        dc.l    $01E6,$06FD0300
403
        dc.l    $01E9,$09FD0300
404
        dc.l    $01EF,$0FFD0300
405
        dc.l    $01F0,$10FD0300
406
 
407
        even
408
InitMMU:
409
        lea MMU+8,a0                            ; first 128kB is local RAM
410
        move.l #$32000,d2               ; map all pages to DRAM
411
        move.l #510,d0                  ; then override for IO later
412
.0002
413
        move.l d2,d1
414
        bsr rbo
415
        move.l d1,(a0)+
416
        addi.w #1,d2                            ; increment DRAM page number
417
        dbra d0,.0002
418
        lea MMU,a0                                      ; now program IO access
419
        lea mmu_adrtbl,a1
420
        moveq #9,d0
421
.0001
422
        move.l (a1)+,d2
423
        lsl.l #2,d2
424
        move.l (a1)+,(a0,d2.w)
425
        dbra d0,.0001
426
        rts
427
 
428
;------------------------------------------------------------------------------
429
; The IO bitmap needs to be initialized to allow access to IO.
430
;------------------------------------------------------------------------------
431
 
432
InitIOBitmap:
433
        ; mark all IO inaccessible
434
        move.w #8191,d0
435
        lea     IO_BITMAP,a0
436
.0001
437
        clr.l (a0)+
438
        dbra d0,.0001
439
        ; Give the system asid=0 complete access to the IO area
440
        move.w #127,d0
441
        moveq   #-1,d1
442
        lea     IO_BITMAP,a0
443
.0002
444
        move.l d1,(a0)+
445
        dbra d0,.0002
446
        ; Give all cores access to the screen
447
        lea IO_BITMAP+128,a0
448
        moveq #-1,d1
449
        move.w #62,d0           ; 63 more bitmaps to fill
450
.0004
451
        swap d0
452
        move.w #31,d0           ; 32 bytes for the screen area per bitmap
453
.0003
454
        move.l d1,(a0)+
455
        dbra d0,.0003
456
        swap d0
457
        lea 96(a0),a0
458
        dbra d0,.0004
459
        rts
460
 
461
;------------------------------------------------------------------------------
462
; RandInit
463
;       Initialize random number generator.
464
;
465
; Modifies:
466
;               none
467
; Parameters:
468
;               none
469
;       Returns:
470
;               none
471
;------------------------------------------------------------------------------
472
 
473
InitRand:
474
RandInit:
475
        movem.l d0/d1,-(a7)
476
        movec           coreno,d0
477
        swap            d0
478
        moveq           #RAND_SEMA,d1
479
        bsr                     LockSemaphore
480
        swap            d0
481
        lsl.l           #6,d0                                                                   ; allow 64 streams per core
482
        move.l  d0,RAND_STRM                                    ; select the stream
483
        move.l  #$12345678,RAND_MZ              ; initialize to some value
484
        move.l  #$98765432,RAND_MW
485
        move.l  #777777777,RAND_NUM             ; generate first number
486
        movec           coreno,d0
487
        swap            d0
488
        moveq           #RAND_SEMA,d1
489
        bsr                     UnlockSemaphore
490
        movem.l (a7)+,d0/d1
491
        rts
492
 
493
;------------------------------------------------------------------------------
494
;------------------------------------------------------------------------------
495
 
496
RandGetNum:
497
        movem.l d0/d2,-(a7)
498
        movec           coreno,d0
499
        swap            d0
500
        moveq           #RAND_SEMA,d1
501
        bsr                     LockSemaphore
502
        lsl.l           #6,d0
503
        move.l  d0,RAND_STRM                                    ; select the stream
504
        move.l  RAND_NUM,d2
505
        clr.l           RAND_NUM                                                        ; generate next number
506
        movec           coreno,d0
507
        swap            d0
508
        moveq           #RAND_SEMA,d1
509
        bsr                     UnlockSemaphore
510
        move.l  d2,d1
511
        movem.l (a7)+,d0/d2
512
        rts
513
 
514
;------------------------------------------------------------------------------
515
; RandWait
516
;    Wait some random number of clock cycles before returning.
517
;------------------------------------------------------------------------------
518
 
519
RandWait:
520
        movem.l d0/d1,-(a7)
521
        bsr                     RandGetNum
522
        andi.w  #15,d1
523
.0001:
524
        nop
525
        dbra            d1,.0001
526
        movem.l (a7)+,d0/d1
527
        rts
528
 
529
;------------------------------------------------------------------------------
530
; Initialize semaphores
531
; - all semaphores are set to unlocked except the first one, which is locked
532
; for core #2.
533
;
534
; Parameters:
535
;               
536
; Modifies:
537
;               
538
; Returns:
539
;               
540
;------------------------------------------------------------------------------
541
 
542
InitSemaphores:
543
        movem.l d1/a0,-(a7)
544
        lea                     semamem,a0
545
        move.l  #$20000,$2000(a0)       ; lock the first semaphore for core #2, thread #0
546
        move.w  #254,d1
547
.0001:
548
        lea                     4(a0),a0
549
        clr.l           $2000(a0)                                       ; write zeros to unlock
550
        dbra            d1,.0001
551
        movem.l (a7)+,d1/a0
552
        rts
553
 
554
; -----------------------------------------------------------------------------
555
; Parameters:
556
;               d1 semaphore number
557
;
558
; Side Effects:
559
;               increments semaphore, saturates at 255
560
;
561
; Returns:
562
;       z flag set if semaphore was zero
563
; -----------------------------------------------------------------------------
564
 
565
;IncrementSemaphore:
566
;       movem.l d1/a0,-(a7)                     ; save registers
567
;       lea                     semamem,a0                      ; point to semaphore memory
568
;       ext.w           d1                                                      ; make d1 word value
569
;       asl.w           #4,d1                                           ; align to memory
570
;       tst.b           1(a0,d1.w)                      ; read (test) value for zero
571
;       movem.l (a7)+,a0/d1                     ; restore regs
572
;       rts
573
 
574
; -----------------------------------------------------------------------------
575
; Parameters:
576
;               d1 semaphore number
577
;
578
; Side Effects:
579
;               decrements semaphore, saturates at zero
580
;
581
; Returns:
582
;       z flag set if semaphore was zero
583
; -----------------------------------------------------------------------------
584
 
585
;DecrementSemaphore:
586
;       movem.l d1/a0,-(a7)                     ; save registers
587
;       lea                     semamem,a0                      ; point to semaphore memory
588
;       andi.w  #255,d1                                 ; make d1 word value
589
;       asl.w           #4,d1                                           ; align to memory
590
;       tst.b           1(a0,d1.w)                      ; read (test) value for zero
591
;       movem.l (a7)+,a0/d1                     ; restore regs
592
;       rts
593
 
594
; -----------------------------------------------------------------------------
595
; Lock a semaphore
596
;
597
; Parameters:
598
;               d0 = key
599
;               d1 = semaphore number
600
; -----------------------------------------------------------------------------
601
 
602
LockSemaphore:
603
        movem.l d1/a0,-(a7)                     ; save registers
604
        lea                     semamem,a0                      ; point to semaphore memory lock area
605
        andi.w  #255,d1                                 ; make d1 word value
606
        lsl.w           #2,d1                                           ; align to memory
607
.0001:
608
        move.l  d0,(a0,d1.w)            ; try and write the semaphore
609
        cmp.l           (a0,d1.w),d0            ; did it lock?
610
        bne.s           .0001                                           ; no, try again
611
        movem.l (a7)+,a0/d1                     ; restore regs
612
        rts
613
 
614
; -----------------------------------------------------------------------------
615
; Unlocks a semaphore even if not the owner.
616
;
617
; Parameters:
618
;               d1 semaphore number
619
; -----------------------------------------------------------------------------
620
 
621
ForceUnlockSemaphore:
622
        movem.l d1/a0,-(a7)                             ; save registers
623
        lea                     semamem+$3000,a0        ; point to semaphore memory read/write area
624
        andi.w  #255,d1                                         ; make d1 word value
625
        lsl.w           #2,d1                                                   ; align to memory
626
        clr.l           (a0,d1.w)                                       ; write zero to unlock
627
        movem.l (a7)+,a0/d1                             ; restore regs
628
        rts
629
 
630
; -----------------------------------------------------------------------------
631
; Unlocks a semaphore. Must be the owner to have effect.
632
; Three cases:
633
;       1) the owner, the semaphore will be reset to zero
634
;       2) not the owner, the write will be ignored
635
; 3) already unlocked, the write will be ignored
636
;
637
; Parameters:
638
;               d0 = key
639
;               d1 = semaphore number
640
; -----------------------------------------------------------------------------
641
 
642
UnlockSemaphore:
643
        movem.l d1/a0,-(a7)                             ; save registers
644
        lea                     semamem+$1000,a0        ; point to semaphore memory unlock area
645
        andi.w  #255,d1                                         ; make d1 word value
646
        lsl.w           #2,d1                                                   ; align to memory
647
        move.l  d0,(a0,d1.w)                    ; write matching value to unlock
648
        movem.l (a7)+,a0/d1                             ; restore regs
649
        rts
650
 
651
; -----------------------------------------------------------------------------
652
; Parameters:
653
;               d1 = semaphore to lock / unlock
654
; -----------------------------------------------------------------------------
655
 
656
T15LockSemaphore:
657
        movec coreno,d0
658
        or.l RunningTCB,d0
659
        bra LockSemaphore
660
 
661
T15UnlockSemaphore:
662
        movec coreno,d0
663
        or.l RunningTCB,d0
664
        bra UnlockSemaphore
665
 
666
; -----------------------------------------------------------------------------
667
; Delay for a few seconds to allow some I/O reset operations to take place.
668
; -----------------------------------------------------------------------------
669
 
670
Delay3s:
671
        move.l  #3000000,d0             ; this should take a few seconds to loop
672
        lea                     leds,a0                         ; a0 = address of LED output register
673
        bra                     dly3s1                          ; branch to the loop
674
dly3s2:
675
        swap            d0                                              ; loop is larger than 16-bits
676
dly3s1:
677
        move.l  d0,d1                                   ; the counter cycles fast, so use upper bits for display
678
        rol.l           #8,d1                                   ; could use swap here, but lets test rol
679
        rol.l           #8,d1
680
        move.b  d1,(a0)                         ; set the LEDs
681
        dbra            d0,dly3s1                       ; decrement and branch back
682
        swap            d0
683
        dbra            d0,dly3s2
684
        rts
685
 
686
Delay3s2:
687
        movec           coreno,d0                       ; vary delay by core to stagger startup
688
        lsl.l           #8,d0
689
        addi.l  #3000000,d0             ; this should take a few seconds to loop
690
        bra                     .0001                                   ; branch to the loop
691
.0002
692
        swap            d0                                              ; loop is larger than 16-bits
693
.0001
694
        dbra            d0,.0001                        ; decrement and branch back
695
        swap            d0
696
        dbra            d0,.0002
697
        rts
698
 
699
        include "cputest.asm"
700
        include "TinyBasic.asm"
701
        include "..\Femtiki\source\kernel\Femtiki.x68"
702
 
703
; -----------------------------------------------------------------------------
704
; Gets the screen color in d0 and d1.
705
; -----------------------------------------------------------------------------
706
 
707
get_screen_color:
708
        move.l  fgColor,d0                      ; get foreground color
709
        asl.l           #5,d0                                           ; shift into position
710
        ori.l           #$40000000,d0           ; set priority
711
        move.l  bkColor,d1
712
        lsr.l           #8,d1
713
        lsr.l           #8,d1
714
        andi.l  #31,d1                                  ; mask off extra bits
715
        or.l            d1,d0                                           ; set background color bits in upper long word
716
        move.l  bkColor,d1                      ; get background color
717
        asl.l           #8,d1                                           ; shift into position for display ram
718
        asl.l           #8,d1
719
        rts
720
 
721
; -----------------------------------------------------------------------------
722
; -----------------------------------------------------------------------------
723
 
724
get_screen_address:
725
        move.l  TextScr,a0
726
        rts
727
 
728
; -----------------------------------------------------------------------------
729
; -----------------------------------------------------------------------------
730
 
731
clear_screen:
732
        movem.l d0/d1/d2/a0,-(a7)
733
        movec           coreno,d0
734
        swap            d0
735
        moveq           #SCREEN_SEMA,d1
736
        bsr                     LockSemaphore
737
        bsr                     get_screen_address      ; a0 = pointer to screen area
738
        move.b  TextRows,d0                                     ; d0 = rows
739
        move.b  TextCols,d2                                     ; d2 = cols
740
        ext.w           d0                                                                      ; convert to word
741
        ext.w           d2                                                                      ; convert to word
742
        mulu            d0,d2                                                           ; d2 = number of character cells to clear
743
        bsr                     get_screen_color                ; get the color bits
744
        ori.w           #32,d1                                                  ; load space character
745
        rol.w           #8,d1                                                           ; swap endian, text controller expects little endian
746
        swap            d1
747
        rol.w           #8,d1
748
        rol.w           #8,d0                                                           ; swap endian
749
        swap            d0
750
        rol.w           #8,d0
751
loop3:
752
        move.l  d1,(a0)+                                                ; copy char plus bkcolor to cell
753
        move.l  d0,(a0)+                                        ; copy fgcolor to cell
754
        dbra            d2,loop3
755
        movec           coreno,d0
756
        swap            d0
757
        moveq           #SCREEN_SEMA,d1
758
        bsr                     UnlockSemaphore
759
        movem.l (a7)+,d0/d1/d2/a0
760
        rts
761
 
762
CRLF:
763
        move.l  d1,-(a7)
764
        move.b  #13,d1
765
        bsr                     DisplayChar
766
        move.b  #10,d1
767
        bsr                     DisplayChar
768
        move.l  (a7)+,d1
769
        rts
770
 
771
;------------------------------------------------------------------------------
772
;------------------------------------------------------------------------------
773
 
774
UpdateTextPos:
775
        move.b  CursorRow,d0            ; compute screen location
776
        andi.w  #$7f,d0
777
        move.b  TextCols,d2
778
        ext.w           d2
779
        mulu.w  d2,d0
780
        move.l  d0,d3
781
        move.b  CursorCol,d2
782
        andi.w  #$ff,d2
783
        add.w           d2,d0
784
        move.w  d0,TextPos                      ; save cursor pos
785
        rts
786
 
787
;------------------------------------------------------------------------------
788
; Calculate screen memory location from CursorRow,CursorCol.
789
; Destroys d0,d2,a0
790
;------------------------------------------------------------------------------
791
 
792
CalcScreenLoc:
793
        bsr                     UpdateTextPos
794
        ext.l           d0                                                              ; make it into a long
795
        asl.l           #3,d0                                                   ; 8 bytes per char
796
        bsr                     get_screen_address
797
        add.l           d0,a0                                                   ; a0 = screen location
798
        rts
799
 
800
;------------------------------------------------------------------------------
801
; Display a character on the screen
802
; d1.b = char to display
803
;------------------------------------------------------------------------------
804
 
805
DisplayChar:
806
        movem.l d1/d2/d3,-(a7)
807
        movec           coreno,d2
808
        cmpi.b  #2,d2
809
;       bne.s           .0001
810
;       bsr                     SerialPutChar
811
.0001:
812
        andi.l  #$ff,d1                         ; zero out upper bytes of d1
813
        cmpi.b  #13,d1                          ; carriage return ?
814
        bne                     dccr
815
        clr.b           CursorCol                       ; just set cursor column to zero on a CR
816
dcx14:
817
        bsr                     SyncCursor              ; set position in text controller
818
dcx7:
819
        movem.l (a7)+,d1/d2/d3
820
        rts
821
dccr:
822
        cmpi.b  #$91,d1                 ; cursor right ?
823
        bne.s   dcx6
824
        move.b  TextCols,d2
825
        sub.b           #1,d2
826
        sub.b           CursorCol,d2
827
        beq.s           dcx7
828
        addi.b  #1,CursorCol
829
        bra.s           dcx14
830
dcx6:
831
        cmpi.b  #$90,d1                 ; cursor up ?
832
        bne.s           dcx8
833
        cmpi.b  #0,CursorRow
834
        beq.s           dcx7
835
        subi.b  #1,CursorRow
836
        bra.s           dcx14
837
dcx8:
838
        cmpi.b  #$93,d1                 ; cursor left?
839
        bne.s           dcx9
840
        cmpi.b  #0,CursorCol
841
        beq.s           dcx7
842
        subi.b  #1,CursorCol
843
        bra.s           dcx14
844
dcx9:
845
        cmpi.b  #$92,d1                 ; cursor down ?
846
        bne.s           dcx10
847
        move.b  TextRows,d2
848
        sub.b           #1,d2
849
        cmp.b           CursorRow,d2
850
        beq.s           dcx7
851
        addi.b  #1,CursorRow
852
        bra.s           dcx14
853
dcx10:
854
        cmpi.b  #$94,d1                 ; cursor home ?
855
        bne.s           dcx11
856
        cmpi.b  #0,CursorCol
857
        beq.s           dcx12
858
        clr.b           CursorCol
859
        bra                     dcx14
860
dcx12:
861
        clr.b           CursorRow
862
        bra                     dcx14
863
dcx11:
864
        movem.l d0/d1/d2/a0,-(a7)
865
        cmpi.b  #$99,d1                 ; delete ?
866
        beq.s           doDelete
867
        cmpi.b  #CTRLH,d1                       ; backspace ?
868
        beq.s   doBackspace
869
        cmpi.b  #CTRLX,d1                       ; delete line ?
870
        beq                     doCtrlX
871
        cmpi.b  #10,d1          ; linefeed ?
872
        beq.s           dclf
873
 
874
        ; regular char
875
        bsr                     CalcScreenLoc   ; a0 = screen location
876
        move.l  d1,d2                                   ; d2 = char
877
        bsr                     get_screen_color        ; d0,d1 = color
878
        or.l            d2,d1                                   ; d1 = char + color
879
        rol.w           #8,d1                                   ; text controller expects little endian data
880
        swap            d1
881
        rol.w           #8,d1
882
        move.l  d1,(a0)
883
        rol.w           #8,d0                                   ; swap bytes
884
        swap            d0                                              ; swap halfs
885
        rol.w           #8,d0                                   ; swap remaining bytes
886
        move.l  d0,4(a0)
887
        bsr                     IncCursorPos
888
        bsr                     SyncCursor
889
        bra                     dcx4
890
dclf:
891
        bsr                     IncCursorRow
892
dcx16:
893
        bsr                     SyncCursor
894
dcx4:
895
        movem.l (a7)+,d0/d1/d2/a0               ; get back a0
896
        movem.l (a7)+,d1/d2/d3
897
        rts
898
 
899
        ;---------------------------
900
        ; CTRL-H: backspace
901
        ;---------------------------
902
doBackspace:
903
        cmpi.b  #0,CursorCol            ; if already at start of line
904
        beq.s   dcx4                                            ; nothing to do
905
        subi.b  #1,CursorCol            ; decrement column
906
 
907
        ;---------------------------
908
        ; Delete key
909
        ;---------------------------
910
doDelete:
911
        movem.l d0/d1/a0,-(a7)  ; save off screen location
912
        bsr               CalcScreenLoc         ; a0 = screen location
913
        move.b  CursorCol,d0
914
.0001:
915
        move.l  8(a0),(a0)              ; pull remaining characters on line over 1
916
        move.l  12(a0),4(a0)    ; pull remaining characters on line over 1
917
        lea                     8(a0),a0
918
        addi.b  #1,d0
919
        cmp.b           TextCols,d0
920
        blo.s           .0001
921
        bsr                     get_screen_color
922
        move.w  #' ',d1                         ; terminate line with a space
923
        rol.w           #8,d1
924
        swap            d1
925
        rol.w           #8,d1
926
        move.l  d1,-8(a0)
927
        movem.l (a7)+,d0/d1/a0
928
        bra.s           dcx16                           ; finished
929
 
930
        ;---------------------------
931
        ; CTRL-X: erase line
932
        ;---------------------------
933
doCtrlX:
934
        clr.b           CursorCol                       ; Reset cursor to start of line
935
        move.b  TextCols,d0                     ; and display TextCols number of spaces
936
        ext.w           d0
937
        ext.l           d0
938
        move.b  #' ',d1                         ; d1 = space char
939
.0001:
940
        ; DisplayChar is called recursively here
941
        ; It's safe to do because we know it won't recurse again due to the
942
        ; fact we know the character being displayed is a space char
943
        bsr             DisplayChar
944
        subq    #1,d0
945
        bne.s   .0001
946
        clr.b   CursorCol                       ; now really go back to start of line
947
        bra.s   dcx16                           ; we're done
948
 
949
;------------------------------------------------------------------------------
950
; Increment the cursor position, scroll the screen if needed.
951
;------------------------------------------------------------------------------
952
 
953
IncCursorPos:
954
        addi.w  #1,TextCurpos
955
        addi.b  #1,CursorCol
956
        move.b  TextCols,d0
957
        cmp.b           CursorCol,d0
958
        bhs.s           icc1
959
        clr.b           CursorCol
960
IncCursorRow:
961
        addi.b  #1,CursorRow
962
        move.b  TextRows,d0
963
        cmp.b           CursorRow,d0
964
        bhi.s           icc1
965
        move.b  TextRows,d0
966
        move.b  d0,CursorRow            ; in case CursorRow is way over
967
        subi.b  #1,CursorRow
968
        ext.w           d0
969
        asl.w           #1,d0
970
        sub.w           d0,TextCurpos
971
        bsr                     ScrollUp
972
icc1:
973
        rts
974
 
975
;------------------------------------------------------------------------------
976
; Scroll screen up.
977
;------------------------------------------------------------------------------
978
 
979
ScrollUp:
980
        movem.l d0/d1/a0/a5,-(a7)               ; save off some regs
981
        movec           coreno,d0
982
        swap            d0
983
        moveq           #SCREEN_SEMA,d1
984
        bsr                     LockSemaphore
985
        bsr                     get_screen_address
986
        move.l  a0,a5                                                           ; a5 = pointer to text screen
987
.0003:
988
        move.b  TextCols,d0                                     ; d0 = columns
989
        move.b  TextRows,d1                                     ; d1 = rows
990
        ext.w           d0                                                                      ; make cols into a word value
991
        ext.w           d1                                                                      ; make rows into a word value
992
        asl.w           #3,d0                                                           ; make into cell index
993
        lea                     0(a5,d0.w),a0                           ; a0 = pointer to second row of text screen
994
        lsr.w           #3,d0                                                           ; get back d0
995
        subq            #1,d1                                                           ; number of rows-1
996
        mulu            d1,d0                                                           ; d0 = count of characters to move
997
.0001:
998
        move.l  (a0)+,(a5)+                                     ; each char is 64 bits
999
        move.l  (a0)+,(a5)+
1000
        dbra            d0,.0001
1001
        movec           coreno,d0
1002
        swap            d0
1003
        moveq           #SCREEN_SEMA,d1
1004
        bsr                     UnlockSemaphore
1005
        movem.l (a7)+,d0/d1/a0/a5
1006
        ; Fall through into blanking out last line
1007
 
1008
;------------------------------------------------------------------------------
1009
; Blank out the last line on the screen.
1010
;------------------------------------------------------------------------------
1011
 
1012
BlankLastLine:
1013
        movem.l d0/d1/d2/a0,-(a7)
1014
        movec           coreno,d0
1015
        swap            d0
1016
        moveq           #SCREEN_SEMA,d1
1017
        bsr                     LockSemaphore
1018
        bsr                     get_screen_address
1019
        move.b  TextRows,d0                                     ; d0 = rows
1020
        move.b  TextCols,d1                                     ; d1 = columns
1021
        ext.w           d0
1022
        ext.w           d1
1023
        subq            #1,d0                                                           ; last row = #rows-1
1024
        mulu            d1,d0                                                           ; d0 = index of last line
1025
        lsl.w           #3,d0                                                           ; *8 bytes per char
1026
        lea                     (a0,d0.w),a0                            ; point a0 to last row
1027
        move.b  TextCols,d2                                     ; number of text cells to clear
1028
        ext.w           d2
1029
        subi.w  #1,d2                                                           ; count must be one less than desired
1030
        bsr                     get_screen_color                ; d0,d1 = screen color
1031
        move.w  #32,d1                                                  ; set the character for display in low 16 bits
1032
        bsr                     rbo                                                                     ; reverse the byte order
1033
        rol.w           #8,d0
1034
        swap            d0
1035
        rol.w           #8,d0
1036
.0001:
1037
        move.l  d0,(a0)+
1038
        move.l  d1,(a0)+
1039
        dbra            d2,.0001
1040
        movec           coreno,d0
1041
        swap            d0
1042
        moveq           #SCREEN_SEMA,d1
1043
        bsr                     UnlockSemaphore
1044
        movem.l (a7)+,d0/d1/d2/a0
1045
        rts
1046
 
1047
;------------------------------------------------------------------------------
1048
; Display a string on the screen.
1049
;------------------------------------------------------------------------------
1050
 
1051
DisplayString:
1052
        movem.l d0/d1/a1,-(a7)
1053
dspj1:
1054
        clr.l           d1                                              ; clear upper bits of d1
1055
        move.b  (a1)+,d1                        ; move string char into d1
1056
        beq.s           dsret                                   ; is it end of string ?
1057
        bsr                     DisplayChar             ; display character
1058
        bra.s           dspj1                                   ; go back for next character
1059
dsret:
1060
        movem.l (a7)+,d0/d1/a1
1061
        rts
1062
 
1063
;------------------------------------------------------------------------------
1064
; Display a string on the screen followed by carriage return / linefeed.
1065
;------------------------------------------------------------------------------
1066
 
1067
DisplayStringCRLF:
1068
        bsr             DisplayString
1069
        bra             CRLF
1070
 
1071
;------------------------------------------------------------------------------
1072
; Display a string on the screen limited to 255 chars max.
1073
;------------------------------------------------------------------------------
1074
 
1075
DisplayStringLimited:
1076
        movem.l d0/d1/d2/a1,-(a7)
1077
        move.w  d1,d2                                   ; d2 = max count
1078
        andi.w  #$00FF,d2                       ; limit to 255 chars
1079
        bra.s           .0003                                   ; enter loop at bottom
1080
.0001:
1081
        clr.l           d1                                              ; clear upper bits of d1
1082
        move.b  (a1)+,d1                        ; move string char into d1
1083
        beq.s           .0002                                   ; is it end of string ?
1084
        bsr                     DisplayChar             ; display character
1085
.0003:
1086
        dbra            d2,.0001                        ; go back for next character
1087
.0002:
1088
        movem.l (a7)+,d0/d1/d2/a1
1089
        rts
1090
 
1091
DisplayStringLimitedCRLF:
1092
        bsr             DisplayStringLimited
1093
        bra             CRLF
1094
 
1095
;------------------------------------------------------------------------------
1096
; Set cursor position to top left of screen.
1097
;
1098
; Parameters:
1099
;               
1100
; Returns:
1101
;               
1102
; Registers Affected:
1103
;               
1104
;------------------------------------------------------------------------------
1105
 
1106
HomeCursor:
1107
        clr.b           CursorRow
1108
        clr.b           CursorCol
1109
        clr.w           TextPos
1110
        ; fall through
1111
 
1112
;------------------------------------------------------------------------------
1113
; SyncCursor:
1114
;
1115
; Sync the hardware cursor's position to the text cursor position but only for
1116
; the core with the IO focus.
1117
;
1118
; Parameters:
1119
;               
1120
; Returns:
1121
;               
1122
; Registers Affected:
1123
;               
1124
;------------------------------------------------------------------------------
1125
 
1126
SyncCursor:
1127
        movem.l d0/d2,-(a7)
1128
        bsr                     UpdateTextPos
1129
        movec           coreno,d2
1130
        cmp.b           IOFocus,d2
1131
        bne.s           .0001
1132
        subi.w  #2,d2                                           ; factor in location of screen in controller
1133
        mulu            #2048,d2                                ; 2048 cells per screen
1134
        add.w           d2,d0
1135
        rol.w           #8,d0                                           ; swap byte order
1136
        move.w  d0,TEXTREG+$24
1137
.0001:
1138
        movem.l (a7)+,d0/d2
1139
        rts
1140
 
1141
;==============================================================================
1142
; TRAP #15 handler
1143
;
1144
; Parameters:
1145
;               d0.w = function number to perform
1146
;==============================================================================
1147
 
1148
TRAP15:
1149
        movem.l d0/a0,-(a7)
1150
        lea                     T15DispatchTable,a0
1151
        asl.l           #2,d0
1152
        move.l  (a0,d0.w),a0
1153
        jsr                     (a0)
1154
        movem.l (a7)+,d0/a0
1155
        rte
1156
 
1157
                align   2
1158
T15DispatchTable:
1159
        dc.l    DisplayStringLimitedCRLF
1160
        dc.l    DisplayStringLimited
1161
        dc.l    StubRout
1162
        dc.l    StubRout
1163
        dc.l    StubRout
1164
        dc.l    GetKey
1165
        dc.l    DisplayChar
1166
        dc.l    CheckForKey
1167
        dc.l    StubRout
1168
        dc.l    StubRout
1169
        ; 10
1170
        dc.l    StubRout
1171
        dc.l    Cursor1
1172
        dc.l    SetKeyboardEcho
1173
        dc.l    DisplayStringCRLF
1174
        dc.l    DisplayString
1175
        dc.l    StubRout
1176
        dc.l    StubRout
1177
        dc.l    StubRout
1178
        dc.l    StubRout
1179
        dc.l    StubRout
1180
        ; 20
1181
        dc.l    StubRout
1182
        dc.l    StubRout
1183
        dc.l    StubRout
1184
        dc.l    StubRout
1185
        dc.l    StubRout
1186
        dc.l    StubRout
1187
        dc.l    StubRout
1188
        dc.l    StubRout
1189
        dc.l    StubRout
1190
        dc.l    StubRout
1191
        ; 30
1192
        dc.l    StubRout
1193
        dc.l    StubRout
1194
        dc.l    rotate_iofocus
1195
        dc.l    SerialPeekCharDirect
1196
        dc.l    SerialPutChar
1197
        dc.l    SerialPeekChar
1198
        dc.l    SerialGetChar
1199
        dc.l    T15LockSemaphore
1200
        dc.l    T15UnlockSemaphore
1201
        dc.l    StubRout
1202
 
1203
;------------------------------------------------------------------------------
1204
; Cursor positioning / Clear screen
1205
; - out of range settings are ignored
1206
;
1207
; Parameters:
1208
;               d1.w cursor position, bits 0 to 7 are row, bits 8 to 15 are column.
1209
;       Returns:
1210
;               none
1211
;------------------------------------------------------------------------------
1212
 
1213
Cursor1:
1214
        move.l          d1,-(a7)
1215
        cmpi.w          #$FF00,d1
1216
        bne.s                   .0002
1217
        bsr                             clear_screen
1218
        bra                             HomeCursor
1219
.0002:
1220
        cmp.b                   TextRows,d1             ; if cursor pos out of range, ignore setting
1221
        bhs.s                   .0003
1222
        move.b          d1,CursorRow
1223
.0003:
1224
        ror.w                   #8,d1
1225
        cmp.b                   TextCols,d1
1226
        bhs.s                   .0001
1227
        move.b          d1,CursorCol
1228
.0001:
1229
        bsr                             SyncCursor              ; update hardware cursor
1230
        move.l          (a7)+,d1
1231
        rts
1232
 
1233
;------------------------------------------------------------------------------
1234
; Stub routine for unimplemented functionality.
1235
;------------------------------------------------------------------------------
1236
 
1237
StubRout:
1238
        rts
1239
 
1240
;------------------------------------------------------------------------------
1241
; Select a specific IO focus.
1242
;------------------------------------------------------------------------------
1243
 
1244
select_iofocus:
1245
        cmpi.b  #2,d1
1246
        blo.s           .0001
1247
        cmpi.b  #9,d1
1248
        bhi.s           .0001
1249
        move.l  d1,d0
1250
        bra.s           select_focus1
1251
.0001:
1252
        rts
1253
 
1254
;------------------------------------------------------------------------------
1255
; Rotate the IO focus, done when ALT-Tab is pressed.
1256
;
1257
; Modifies:
1258
;               d0, IOFocus BIOS variable
1259
;------------------------------------------------------------------------------
1260
 
1261
rotate_iofocus:
1262
        move.b  IOFocus,d0                              ; d0 = focus, we can trash d0
1263
        add.b           #1,d0                                                   ; increment the focus
1264
        cmp.b           #9,d0                                                   ; limit to 2 to 9
1265
        bls.s           .0001
1266
        move.b  #2,d0
1267
.0001:
1268
select_focus1:
1269
        move.b  d0,IOFocus                              ; set IO focus
1270
        subi.b  #2,d0                                                   ; screen is 0 to 7, focus is 2 to 9
1271
        ext.w           d0                                                              ; make into long value
1272
        mulu            #2048,d0                                        ; * 2048        cells per screen
1273
        rol.w           #8,d0                                                   ; swap byte order
1274
        move.w  d0,TEXTREG+$28          ; update screen address in text controller
1275
        bra                     SyncCursor                              ; set cursor position
1276
 
1277
;==============================================================================
1278
; PLIC - platform level interrupt controller
1279
;
1280
; Register layout:
1281
;   bits 0 to 7  = cause code to issue (vector number)
1282
;   bits 8 to 11 = irq level to issue
1283
;   bit 16 = irq enable
1284
;   bit 17 = edge sensitivity
1285
;   bit 18 = 0=vpa, 1=inta
1286
;               bit 24 to 29 target core
1287
;
1288
; Note byte order must be reversed for PLIC.
1289
;==============================================================================
1290
 
1291
init_plic:
1292
        lea             PLIC,a0                                         ; a0 points to PLIC
1293
        lea             $80+4*29(a0),a1         ; point to timer registers (29)
1294
        move.l  #$0006033F,(a1) ; initialize, core=63,edge sensitive,enabled,irq6,vpa
1295
        lea                     4(a1),a1                                ; point to keyboard registers (30)
1296
        move.l  #$3C060502,(a1) ; core=2,level sensitive,enabled,irq6,inta
1297
        lea                     4(a1),a1                                ; point to nmi button register (31)
1298
        move.l  #$00070302,(a1) ; initialize, core=2,edge sensitive,enabled,irq7,vpa
1299
        lea             $80+4*16(a0),a1         ; a1 points to ACIA register
1300
        move.l  #$3D030502,(a1) ; core=2,level sensitive,enabled,irq3,inta
1301
        lea             $80+4*4(a0),a1          ; a1 points to io_bitmap irq
1302
        move.l  #$3B060702,(a1) ; core=2,edge sensitive,enabled,irq6,inta
1303
        rts
1304
 
1305
;==============================================================================
1306
; Keyboard stuff
1307
;
1308
; KeyState2_
1309
; 876543210
1310
; ||||||||+ = shift
1311
; |||||||+- = alt
1312
; ||||||+-- = control
1313
; |||||+--- = numlock
1314
; ||||+---- = capslock
1315
; |||+----- = scrolllock
1316
; ||+------ =
1317
; |+------- =
1318
; +-------- = extended
1319
;
1320
;==============================================================================
1321
 
1322
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1323
; Get ID - get the keyboards identifier code.
1324
;
1325
; Parameters: none
1326
; Returns: d = $AB83, $00 on fail
1327
; Modifies: d, KeybdID updated
1328
; Stack Space: 2 words
1329
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1330
 
1331
KeybdGetID:
1332
        move.w  #$F2,d1
1333
        bsr                     KeybdSendByte
1334
        bsr                     KeybdWaitTx
1335
        bsr                     KeybdRecvByte
1336
        btst            #7,d1
1337
        bne                     kgnotKbd
1338
        cmpi.b  #$AB,d1
1339
        bne                     kgnotKbd
1340
        bsr                     KeybdRecvByte
1341
        btst            #7,d1
1342
        bne                     kgnotKbd
1343
        cmpi.b  #$83,d1
1344
        bne                     kgnotKbd
1345
        move.l  #$AB83,d1
1346
kgid1:
1347
        move.w  d1,KeybdID
1348
        rts
1349
kgnotKbd:
1350
        moveq           #0,d1
1351
        bra                     kgid1
1352
 
1353
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1354
; Set the LEDs on the keyboard.
1355
;
1356
; Parameters:
1357
;               d1.b = LED state
1358
;       Modifies:
1359
;               none
1360
; Returns:
1361
;               none
1362
; Stack Space:
1363
;               1 long word
1364
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1365
 
1366
KeybdSetLED:
1367
        move.l  d1,-(a7)
1368
        move.b  #$ED,d1
1369
        bsr                     KeybdSendByte
1370
        bsr                     KeybdWaitTx
1371
        bsr                     KeybdRecvByte
1372
        tst.b           d1
1373
        bmi                     .0001
1374
        cmpi.b  #$FA,d1
1375
        move.l  (a7),d1
1376
        bsr                     KeybdSendByte
1377
        bsr                     KeybdWaitTx
1378
        bsr                     KeybdRecvByte
1379
.0001:
1380
        move.l  (a7)+,d1
1381
        rts
1382
 
1383
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1384
; Initialize the keyboard.
1385
;
1386
; Parameters:
1387
;               none
1388
;       Modifies:
1389
;               none
1390
; Returns:
1391
;               none
1392
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1393
 
1394
_KeybdInit:
1395
KeybdInit:
1396
;       movem.l d0/d1/d3/a1,-(a7)
1397
        clr.b   _KeyState1              ; records key up/down state
1398
        clr.b   _KeyState2              ; records shift,ctrl,alt state
1399
        rts
1400
 
1401
        bsr                     Wait300ms
1402
        bsr                     _KeybdGetStatus ; wait for response from keyboard
1403
        tst.b           d1
1404
        bpl                     .0001                                   ; is input buffer full ? no, branch
1405
        bsr                     _KeybdGetScancode
1406
        cmpi.b  #$AA,d1                         ; keyboard Okay
1407
        beq                     kbdi0005
1408
.0001:
1409
        moveq           #10,d3
1410
kbdi0002:
1411
        bsr                     Wait10ms
1412
        clr.b           KEYBD+1                         ; clear receive register (write $00 to status reg)
1413
        moveq           #-1,d1                          ; send reset code to keyboard
1414
        move.b  d1,KEYBD+1              ; write $FF to status reg to clear TX state
1415
        bsr                     KeybdSendByte   ; now write ($FF) to transmit register for reset
1416
        bsr                     KeybdWaitTx             ; wait until no longer busy
1417
        tst.l           d1
1418
        bmi                     kbdiXmitBusy
1419
        bsr                     KeybdRecvByte   ; look for an ACK ($FA)
1420
        cmpi.b  #$FA,d1
1421
        bne                     .0001
1422
        bsr                     KeybdRecvByte   ; look for BAT completion code ($AA)
1423
.0001:
1424
        cmpi.b  #$FC,d1                         ; reset error ?
1425
        beq                     kbdiTryAgain
1426
        cmpi.b  #$AA,d1                         ; reset complete okay ?
1427
        bne                     kbdiTryAgain
1428
 
1429
        ; After a reset, scan code set #2 should be active
1430
.config:
1431
        move.w  #$F0,d1                 ; send scan code select
1432
        move.b  d1,leds
1433
        bsr                     KeybdSendByte
1434
        bsr                     KeybdWaitTx
1435
        tst.l           d1
1436
        bmi                     kbdiXmitBusy
1437
        bsr                     KeybdRecvByte   ; wait for response from keyboard
1438
        tst.w           d1
1439
        bmi                     kbdiTryAgain
1440
        cmpi.b  #$FA,d1                         ; ACK
1441
        beq                     kbdi0004
1442
kbdiTryAgain:
1443
        dbra            d3,kbdi0002
1444
.keybdErr:
1445
        lea                     msgBadKeybd,a1
1446
        bsr                     DisplayStringCRLF
1447
        bra                     ledxit
1448
kbdi0004:
1449
        moveq           #2,d1                   ; select scan code set #2
1450
        bsr                     KeybdSendByte
1451
        bsr                     KeybdWaitTx
1452
        tst.l           d1
1453
        bmi                     kbdiXmitBusy
1454
        bsr                     KeybdRecvByte   ; wait for response from keyboard
1455
        tst.w           d1
1456
        bmi                     kbdiTryAgain
1457
        cmpi.b  #$FA,d1
1458
        bne                     kbdiTryAgain
1459
kbdi0005:
1460
        bsr                     KeybdGetID
1461
ledxit:
1462
        moveq           #$07,d1
1463
        bsr                     KeybdSetLED
1464
        bsr                     Wait300ms
1465
        moveq           #$00,d1
1466
        bsr                     KeybdSetLED
1467
        movem.l (a7)+,d0/d1/d3/a1
1468
        rts
1469
kbdiXmitBusy:
1470
        lea                     msgXmitBusy,a1
1471
        bsr                     DisplayStringCRLF
1472
        movem.l (a7)+,d0/d1/d3/a1
1473
        rts
1474
 
1475
msgBadKeybd:
1476
        dc.b            "Keyboard error",0
1477
msgXmitBusy:
1478
        dc.b            "Keyboard transmitter stuck",0
1479
 
1480
        even
1481
_KeybdGetStatus:
1482
        moveq           #0,d1
1483
        move.b  KEYBD+1,d1
1484
        rts
1485
 
1486
; Get the scancode from the keyboard port
1487
 
1488
_KeybdGetScancode:
1489
        moveq           #0,d1
1490
        move.b  KEYBD,d1                                ; get the scan code
1491
        move.b  #0,KEYBD+1                      ; clear receive register
1492
        rts
1493
 
1494
; Recieve a byte from the keyboard, used after a command is sent to the
1495
; keyboard in order to wait for a response.
1496
;
1497
KeybdRecvByte:
1498
        move.l  d3,-(a7)
1499
        move.w  #100,d3         ; wait up to 1s
1500
.0003:
1501
        bsr                     _KeybdGetStatus ; wait for response from keyboard
1502
        tst.b           d1
1503
        bmi                     .0004                   ; is input buffer full ? yes, branch
1504
        bsr                     Wait10ms        ; wait a bit
1505
        dbra            d3,.0003        ; go back and try again
1506
        move.l  (a7)+,d3
1507
        moveq           #-1,d1          ; return -1
1508
        rts
1509
.0004:
1510
        bsr                     _KeybdGetScancode
1511
        move.l  (a7)+,d3
1512
        rts
1513
 
1514
 
1515
; Wait until the keyboard transmit is complete
1516
; Returns -1 if timedout, 0 if transmit completed
1517
;
1518
KeybdWaitTx:
1519
        movem.l d2/d3,-(a7)
1520
        moveq           #100,d3         ; wait a max of 1s
1521
.0001:
1522
        bsr                     _KeybdGetStatus
1523
        btst            #6,d1                           ; check for transmit complete bit
1524
        bne         .0002                               ; branch if bit set
1525
        bsr                     Wait10ms                ; delay a little bit
1526
        dbra            d3,.0001                ; go back and try again
1527
        movem.l (a7)+,d2/d3
1528
        moveq           #-1,d1                  ; return -1
1529
        rts
1530
.0002:
1531
        movem.l (a7)+,d2/d3
1532
        moveq   #0,d1           ; return 0
1533
        rts
1534
 
1535
;------------------------------------------------------------------------------
1536
; d1.b 0=echo off, non-zero = echo on
1537
;------------------------------------------------------------------------------
1538
 
1539
SetKeyboardEcho:
1540
        move.b  d1,KeybdEcho
1541
        rts
1542
 
1543
;------------------------------------------------------------------------------
1544
; Get key pending status into d1.b
1545
;
1546
; Returns:
1547
;               d1.b = 1 if a key is available, otherwise zero.
1548
;------------------------------------------------------------------------------
1549
 
1550
CheckForKey:
1551
        moveq.l #0,d1                                   ; clear high order bits
1552
;       move.b  KEYBD+1,d1              ; get keyboard port status
1553
;       smi.b           d1                                              ; set true/false
1554
;       andi.b  #1,d1                                   ; return true (1) if key available, 0 otherwise
1555
        tst.b           _KeybdCnt
1556
        sne.b           d1
1557
        rts
1558
 
1559
;------------------------------------------------------------------------------
1560
; GetKey
1561
;       Get a character from the keyboard.
1562
;
1563
; Modifies:
1564
;               d1
1565
; Returns:
1566
;               d1 = -1 if no key available or not in focus, otherwise key
1567
;------------------------------------------------------------------------------
1568
 
1569
GetKey:
1570
        move.l  d0,-(a7)                                        ; push d0
1571
        move.b  IOFocus,d1                              ; Check if the core has the IO focus
1572
        movec.l coreno,d0
1573
        cmp.b           d0,d1
1574
        bne.s           .0004                                                   ; go return no key available, if not in focus
1575
        bsr                     KeybdGetCharNoWait      ; get a character
1576
        tst.l           d1                                              ; was a key available?
1577
        bmi.s           .0004
1578
        tst.b           KeybdEcho                                       ; is keyboard echo on ?
1579
        beq.s           .0003                                                   ; no echo, just return the key
1580
        cmpi.b  #CR,d1                                          ; convert CR keystroke into CRLF
1581
        bne.s           .0005
1582
        bsr                     CRLF
1583
        bra.s           .0003
1584
.0005:
1585
        bsr                     DisplayChar
1586
.0003:
1587
        move.l  (a7)+,d0                                        ; pop d0
1588
        rts                                                                                             ; return key
1589
; Return -1 indicating no char was available
1590
.0004:
1591
        move.l  (a7)+,d0                                        ; pop d0
1592
        moveq           #-1,d1                                          ; return no key available
1593
        rts
1594
 
1595
CheckForCtrlC:
1596
        bsr                     KeybdGetCharNoWait
1597
        cmpi.b  #CTRLC,d1
1598
        beq                     Monitor
1599
        rts
1600
 
1601
;------------------------------------------------------------------------------
1602
;------------------------------------------------------------------------------
1603
 
1604
KeybdGetCharNoWait:
1605
        clr.b   KeybdWaitFlag
1606
        bra             KeybdGetChar
1607
 
1608
KeybdGetCharWait:
1609
        move.b  #-1,KeybdWaitFlag
1610
 
1611
KeybdGetChar:
1612
        movem.l d0/d2/d3/a0,-(a7)
1613
.0003:
1614
        movec           coreno,d0
1615
        swap            d0
1616
        moveq           #KEYBD_SEMA,d1
1617
        bsr                     LockSemaphore
1618
        move.b  _KeybdCnt,d2            ; get count of buffered scan codes
1619
        beq.s           .0015                                           ;
1620
        move.b  _KeybdHead,d2           ; d2 = buffer head
1621
        ext.w           d2
1622
        lea                     _KeybdBuf,a0            ; a0 = pointer to keyboard buffer
1623
        clr.l           d1
1624
        move.b  (a0,d2.w),d1            ; d1 = scan code from buffer
1625
        addi.b  #1,d2                                           ; increment keyboard head index
1626
        andi.b  #31,d2                                  ; and wrap around at buffer size
1627
        move.b  d2,_KeybdHead
1628
        subi.b  #1,_KeybdCnt            ; decrement count of scan codes in buffer
1629
        exg                     d1,d2                                           ; save scancode value in d2
1630
        movec           coreno,d0
1631
        swap            d0
1632
        moveq           #KEYBD_SEMA,d1
1633
        bsr                     UnlockSemaphore
1634
        exg                     d2,d1                                           ; restore scancode value
1635
        bra                     .0001                                           ; go process scan code
1636
.0014:
1637
        bsr             _KeybdGetStatus         ; check keyboard status for key available
1638
        bmi             .0006                                                   ; yes, go process
1639
.0015:
1640
        movec           coreno,d0
1641
        swap            d0
1642
        moveq           #KEYBD_SEMA,d1
1643
        bsr                     UnlockSemaphore
1644
        tst.b           KeybdWaitFlag                   ; are we willing to wait for a key ?
1645
        bmi                     .0003                                                   ; yes, branch back
1646
        movem.l (a7)+,d0/d2/d3/a0
1647
        moveq           #-1,d1                                          ; flag no char available
1648
        rts
1649
.0006:
1650
        bsr             _KeybdGetScancode
1651
.0001:
1652
        move.w  #1,leds
1653
        cmp.b   #SC_KEYUP,d1
1654
        beq             .doKeyup
1655
        cmp.b   #SC_EXTEND,d1
1656
        beq             .doExtend
1657
        cmp.b   #SC_CTRL,d1
1658
        beq             .doCtrl
1659
        cmp.b   #SC_LSHIFT,d1
1660
        beq             .doShift
1661
        cmp.b   #SC_RSHIFT,d1
1662
        beq             .doShift
1663
        cmp.b   #SC_NUMLOCK,d1
1664
        beq             .doNumLock
1665
        cmp.b   #SC_CAPSLOCK,d1
1666
        beq             .doCapsLock
1667
        cmp.b   #SC_SCROLLLOCK,d1
1668
        beq             .doScrollLock
1669
        cmp.b   #SC_ALT,d1
1670
        beq     .doAlt
1671
        move.b  _KeyState1,d2                   ; check key up/down
1672
        move.b  #0,_KeyState1                   ; clear keyup status
1673
        tst.b   d2
1674
        bne         .0003                                       ; ignore key up
1675
        cmp.b   #SC_TAB,d1
1676
        beq     .doTab
1677
.0013:
1678
        move.b  _KeyState2,d2
1679
        bpl             .0010                                   ; is it extended code ?
1680
        and.b   #$7F,d2                                 ; clear extended bit
1681
        move.b  d2,_KeyState2
1682
        move.b  #0,_KeyState1                   ; clear keyup
1683
        lea             _keybdExtendedCodes,a0
1684
        move.b  (a0,d1.w),d1
1685
        bra             .0008
1686
.0010:
1687
        btst    #2,d2                                   ; is it CTRL code ?
1688
        beq             .0009
1689
        and.w   #$7F,d1
1690
        lea             _keybdControlCodes,a0
1691
        move.b  (a0,d1.w),d1
1692
        bra             .0008
1693
.0009:
1694
        btst    #0,d2                                   ; is it shift down ?
1695
        beq     .0007
1696
        lea             _shiftedScanCodes,a0
1697
        move.b  (a0,d1.w),d1
1698
        bra             .0008
1699
.0007:
1700
        lea             _unshiftedScanCodes,a0
1701
        move.b  (a0,d1.w),d1
1702
        move.w  #$0202,leds
1703
.0008:
1704
        move.w  #$0303,leds
1705
        movem.l (a7)+,d0/d2/d3/a0
1706
        rts
1707
.doKeyup:
1708
        move.b  #-1,_KeyState1
1709
        bra             .0003
1710
.doExtend:
1711
        or.b    #$80,_KeyState2
1712
        bra             .0003
1713
.doCtrl:
1714
        move.b  _KeyState1,d1
1715
        clr.b   _KeyState1
1716
        tst.b   d1
1717
        bpl.s   .0004
1718
        bclr    #2,_KeyState2
1719
        bra             .0003
1720
.0004:
1721
        bset    #2,_KeyState2
1722
        bra             .0003
1723
.doAlt:
1724
        move.b  _KeyState1,d1
1725
        clr.b   _KeyState1
1726
        tst.b   d1
1727
        bpl             .0011
1728
        bclr    #1,_KeyState2
1729
        bra             .0003
1730
.0011:
1731
        bset    #1,_KeyState2
1732
        bra             .0003
1733
.doTab:
1734
        move.l  d1,-(a7)
1735
  move.b  _KeyState2,d1
1736
  btst  #1,d1                 ; is ALT down ?
1737
  beq     .0012
1738
;       inc     _iof_switch
1739
  move.l        (a7)+,d1
1740
  bra     .0003
1741
.0012:
1742
  move.l        (a7)+,d1
1743
  bra     .0013
1744
.doShift:
1745
        move.b  _KeyState1,d1
1746
        clr.b   _KeyState1
1747
        tst.b   d1
1748
        bpl.s   .0005
1749
        bclr    #0,_KeyState2
1750
        bra             .0003
1751
.0005:
1752
        bset    #0,_KeyState2
1753
        bra             .0003
1754
.doNumLock:
1755
        bchg    #4,_KeyState2
1756
        bsr             KeybdSetLEDStatus
1757
        bra             .0003
1758
.doCapsLock:
1759
        bchg    #5,_KeyState2
1760
        bsr             KeybdSetLEDStatus
1761
        bra             .0003
1762
.doScrollLock:
1763
        bchg    #6,_KeyState2
1764
        bsr             KeybdSetLEDStatus
1765
        bra             .0003
1766
 
1767
KeybdSetLEDStatus:
1768
        movem.l d2/d3,-(a7)
1769
        clr.b           KeybdLEDs
1770
        btst            #4,_KeyState2
1771
        beq.s           .0002
1772
        move.b  #2,KeybdLEDs
1773
.0002:
1774
        btst            #5,_KeyState2
1775
        beq.s           .0003
1776
        bset            #2,KeybdLEDs
1777
.0003:
1778
        btst            #6,_KeyState2
1779
        beq.s           .0004
1780
        bset            #0,KeybdLEDs
1781
.0004:
1782
        move.b  KeybdLEDs,d1
1783
        bsr                     KeybdSetLED
1784
        movem.l (a7)+,d2/d3
1785
        rts
1786
 
1787
KeybdSendByte:
1788
        move.b  d1,KEYBD
1789
        rts
1790
 
1791
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1792
; Wait for 10 ms
1793
;
1794
; Parameters: none
1795
; Returns: none
1796
; Modifies: none
1797
; Stack Space: 2 long words
1798
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1799
 
1800
Wait10ms:
1801
        movem.l d0/d1,-(a7)
1802
        movec           tick,d0
1803
        addi.l  #400000,d0                      ; 400,000 cycles at 40MHz
1804
.0001:
1805
        movec           tick,d1
1806
        cmp.l           d1,d0
1807
        bhi                     .0001
1808
        movem.l (a7)+,d0/d1
1809
        rts
1810
 
1811
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1812
; Wait for 300 ms
1813
;
1814
; Parameters: none
1815
; Returns: none
1816
; Modifies: none
1817
; Stack Space: 2 long words
1818
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1819
 
1820
Wait300ms:
1821
        movem.l d0/d1,-(a7)
1822
        movec           tick,d0
1823
        addi.l  #12000000,d0                    ; 12,000,000 cycles at 40MHz
1824
.0001:
1825
        movec           tick,d1
1826
        cmp.l           d1,d0
1827
        bhi                     .0001
1828
        movem.l (a7)+,d0/d1
1829
        rts
1830
 
1831
;--------------------------------------------------------------------------
1832
; Keyboard IRQ routine.
1833
;
1834
; Returns:
1835
;       d1 = -1 if keyboard routine handled interrupt, otherwise positive.
1836
;--------------------------------------------------------------------------
1837
 
1838
KeybdIRQ:
1839
        move.w  #$2600,sr                                       ; disable lower interrupts
1840
        movem.l d0/d1/a0,-(a7)
1841
        bsr                     _KeybdGetStatus         ; check if keyboard
1842
        tst.b           d1
1843
        bpl                     .0001                                                   ; branch if not keyboard
1844
        movec           coreno,d0
1845
        swap            d0
1846
        moveq           #KEYBD_SEMA,d1
1847
        bsr                     LockSemaphore
1848
        btst            #1,_KeyState2                   ; Is Alt down?
1849
        beq.s           .0003
1850
        move.b  KEYBD,d0                                        ; get scan code
1851
        cmpi.b  #SC_TAB,d0                              ; is Alt-Tab?
1852
        bne.s           .0003
1853
        bsr                     _KeybdGetScancode       ; grab the scan code (clears interrupt)
1854
        bsr                     rotate_iofocus
1855
        clr.b           _KeybdHead                              ; clear keyboard buffer
1856
        clr.b           _KeybdTail
1857
        clr.b           _KeybdCnt
1858
        bra                     .0002                                                   ; do not store Alt-Tab
1859
.0003:
1860
        ; Insert keyboard scan code into raw keyboard buffer
1861
        bsr                     _KeybdGetScancode       ; grab the scan code (clears interrupt)
1862
        cmpi.b  #32,_KeybdCnt                   ; see if keyboard buffer full
1863
        bhs.s           .0002
1864
        move.b  _KeybdTail,d0                   ; keyboard buffer not full, add to tail
1865
        ext.w           d0
1866
        lea                     _KeybdBuf,a0                    ; a0 = pointer to buffer
1867
        move.b  d1,(a0,d0.w)                    ; put scancode in buffer
1868
        addi.b  #1,d0                                                   ; increment tail index
1869
        andi.b  #31,d0                                          ; wrap at buffer limit
1870
        move.b  d0,_KeybdTail                   ; update tail index
1871
        addi.b  #1,_KeybdCnt                    ; increment buffer count
1872
.0002:
1873
        movec           coreno,d0
1874
        swap            d0
1875
        moveq           #KEYBD_SEMA,d1
1876
        bsr                     UnlockSemaphore
1877
.0001:
1878
        movem.l (a7)+,d0/d1/a0          ; return
1879
        rte
1880
 
1881
;--------------------------------------------------------------------------
1882
; PS2 scan codes to ascii conversion tables.
1883
;--------------------------------------------------------------------------
1884
;
1885
_unshiftedScanCodes:
1886
        dc.b    $2e,$a9,$2e,$a5,$a3,$a1,$a2,$ac
1887
        dc.b    $2e,$aa,$a8,$a6,$a4,$09,$60,$2e
1888
        dc.b    $2e,$2e,$2e,$2e,$2e,$71,$31,$2e
1889
        dc.b    $2e,$2e,$7a,$73,$61,$77,$32,$2e
1890
        dc.b    $2e,$63,$78,$64,$65,$34,$33,$2e
1891
        dc.b    $2e,$20,$76,$66,$74,$72,$35,$2e
1892
        dc.b    $2e,$6e,$62,$68,$67,$79,$36,$2e
1893
        dc.b    $2e,$2e,$6d,$6a,$75,$37,$38,$2e
1894
        dc.b    $2e,$2c,$6b,$69,$6f,$30,$39,$2e
1895
        dc.b    $2e,$2e,$2f,$6c,$3b,$70,$2d,$2e
1896
        dc.b    $2e,$2e,$27,$2e,$5b,$3d,$2e,$2e
1897
        dc.b    $ad,$2e,$0d,$5d,$2e,$5c,$2e,$2e
1898
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
1899
        dc.b    $2e,$95,$2e,$93,$94,$2e,$2e,$2e
1900
        dc.b    $98,$7f,$92,$2e,$91,$90,$1b,$af
1901
        dc.b    $ab,$2e,$97,$2e,$2e,$96,$ae,$2e
1902
 
1903
        dc.b    $2e,$2e,$2e,$a7,$2e,$2e,$2e,$2e
1904
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1905
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1906
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1907
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1908
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1909
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1910
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1911
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1912
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1913
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1914
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1915
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1916
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1917
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1918
        dc.b    $2e,$2e,$fa,$2e,$2e,$2e,$2e,$2e
1919
 
1920
_shiftedScanCodes:
1921
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1922
        dc.b    $2e,$2e,$2e,$2e,$2e,$09,$7e,$2e
1923
        dc.b    $2e,$2e,$2e,$2e,$2e,$51,$21,$2e
1924
        dc.b    $2e,$2e,$5a,$53,$41,$57,$40,$2e
1925
        dc.b    $2e,$43,$58,$44,$45,$24,$23,$2e
1926
        dc.b    $2e,$20,$56,$46,$54,$52,$25,$2e
1927
        dc.b    $2e,$4e,$42,$48,$47,$59,$5e,$2e
1928
        dc.b    $2e,$2e,$4d,$4a,$55,$26,$2a,$2e
1929
        dc.b    $2e,$3c,$4b,$49,$4f,$29,$28,$2e
1930
        dc.b    $2e,$3e,$3f,$4c,$3a,$50,$5f,$2e
1931
        dc.b    $2e,$2e,$22,$2e,$7b,$2b,$2e,$2e
1932
        dc.b    $2e,$2e,$0d,$7d,$2e,$7c,$2e,$2e
1933
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
1934
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1935
        dc.b    $2e,$7f,$2e,$2e,$2e,$2e,$1b,$2e
1936
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1937
 
1938
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1939
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1940
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1941
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1942
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1943
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1944
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1945
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1946
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1947
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1948
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1949
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1950
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1951
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1952
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1953
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1954
 
1955
; control
1956
_keybdControlCodes:
1957
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1958
        dc.b    $2e,$2e,$2e,$2e,$2e,$09,$7e,$2e
1959
        dc.b    $2e,$2e,$2e,$2e,$2e,$11,$21,$2e
1960
        dc.b    $2e,$2e,$1a,$13,$01,$17,$40,$2e
1961
        dc.b    $2e,$03,$18,$04,$05,$24,$23,$2e
1962
        dc.b    $2e,$20,$16,$06,$14,$12,$25,$2e
1963
        dc.b    $2e,$0e,$02,$08,$07,$19,$5e,$2e
1964
        dc.b    $2e,$2e,$0d,$0a,$15,$26,$2a,$2e
1965
        dc.b    $2e,$3c,$0b,$09,$0f,$29,$28,$2e
1966
        dc.b    $2e,$3e,$3f,$0c,$3a,$10,$5f,$2e
1967
        dc.b    $2e,$2e,$22,$2e,$7b,$2b,$2e,$2e
1968
        dc.b    $2e,$2e,$0d,$7d,$2e,$7c,$2e,$2e
1969
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$08,$2e
1970
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1971
        dc.b    $2e,$7f,$2e,$2e,$2e,$2e,$1b,$2e
1972
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1973
 
1974
_keybdExtendedCodes:
1975
        dc.b    $2e,$2e,$2e,$2e,$a3,$a1,$a2,$2e
1976
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1977
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1978
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1979
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1980
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1981
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1982
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1983
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1984
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1985
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1986
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1987
        dc.b    $2e,$2e,$2e,$2e,$2e,$2e,$2e,$2e
1988
        dc.b    $2e,$95,$2e,$93,$94,$2e,$2e,$2e
1989
        dc.b    $98,$99,$92,$2e,$91,$90,$2e,$2e
1990
        dc.b    $2e,$2e,$97,$2e,$2e,$96,$2e,$2e
1991
 
1992
;==============================================================================
1993
;==============================================================================
1994
; Monitor
1995
;==============================================================================
1996
;==============================================================================
1997
 
1998
cmdString:
1999
        dc.b    '?'+$80                                         ; ? display help
2000
        dc.b    'L'+$80                                         ; L load S19 file
2001
        dc.b    'F','B'+$80                             ; FB fill with byte
2002
        dc.b    'F','W'+$80                             ; FW fill with wyde
2003
        dc.b    'F','L'+$80                             ; FL fill with long wyde
2004
        dc.b    'B','A'+$80                             ; BA start Tiny Basic
2005
        dc.b    'B','R'+$80                             ; BR breakpoint
2006
        dc.b    'D','R'+$80                             ; DR dump registers
2007
        dc.b    'D'+$80                                         ; D dump memory
2008
        dc.b    'J'+$80                                         ; J jump to code
2009
        dc.b    ':'+$80                                         ; : edit memory
2010
        dc.b    "CL",'S'+$80                    ; CLS clear screen
2011
        dc.b    "COR",'E'+$80                   ; CORE  switch to core
2012
        dc.b  "TRA",'M'+$80                     ; TRAM test RAM
2013
        dc.b    'T','R'+$80                             ; TR test serial receive
2014
        dc.b    'T'+$80                                         ; T test CPU
2015
        dc.b    'S'+$80                                         ; S send serial
2016
        dc.b    "RESE",'T'+$80          ; RESET 
2017
        dc.b    "CLOC",'K'+$80          ; CLOCK 
2018
        dc.b    'R'+$80                                         ; R receive serial
2019
 
2020
        align   2
2021
cmdTable:
2022
        dc.w    cmdHelp
2023
        dc.w    cmdLoadS19
2024
        dc.w    cmdFillB
2025
        dc.w    cmdFillW
2026
        dc.w    cmdFillL
2027
        dc.w    cmdTinyBasic
2028
        dc.w    cmdBreakpoint
2029
        dc.w    cmdDumpRegs
2030
        dc.w    cmdDumpMemory
2031
        dc.w    cmdJump
2032
        dc.w    cmdEditMemory
2033
        dc.w    cmdClearScreen
2034
        dc.w    cmdCore
2035
        dc.w  cmdTestRAM
2036
        dc.w    cmdTestSerialReceive
2037
        dc.w    cmdTestCPU
2038
        dc.w    cmdSendSerial
2039
        dc.w    cmdReset
2040
        dc.w    cmdClock
2041
        dc.w    cmdReceiveSerial
2042
        dc.w    cmdMonitor
2043
 
2044
; Get a word from screen memory and swap byte order
2045
 
2046
FromScreen:
2047
        move.l  (a0),d1
2048
        bsr                     rbo
2049
        lea                     8(a0),a0        ; increment screen pointer
2050
        rts
2051
 
2052
StartMon:
2053
        clr.w           NumSetBreakpoints
2054
        bsr                     ClearBreakpointList
2055
cmdMonitor:
2056
Monitor:
2057
        ; Reset the stack pointer on each entry into the monitor
2058
        move.l  #$40FFC,sp      ; reset core's stack
2059
        move.w  #$2200,sr               ; enable level 2 and higher interrupts
2060
        movec           coreno,d0
2061
        swap            d0
2062
        moveq           #1,d1
2063
        bsr                     UnlockSemaphore
2064
        clr.b           KeybdEcho               ; turn off keyboard echo
2065
PromptLn:
2066
        bsr                     CRLF
2067
        move.b  #'$',d1
2068
        bsr                     DisplayChar
2069
 
2070
; Get characters until a CR is keyed
2071
;
2072
Prompt3:
2073
        bsr                     GetKey
2074
        cmpi.b  #-1,d1
2075
        beq.s           Prompt3
2076
        cmpi.b  #CR,d1
2077
        beq.s           Prompt1
2078
        bsr                     DisplayChar
2079
        bra.s           Prompt3
2080
 
2081
; Process the screen line that the CR was keyed on
2082
 
2083
Prompt1:
2084
        clr.b           CursorCol                       ; go back to the start of the line
2085
        bsr                     CalcScreenLoc   ; a0 = screen memory location
2086
.0001:
2087
        bsr                     FromScreen              ; grab character off screen
2088
        cmpi.b  #'$',d1                         ; skip over '$' prompt character
2089
        beq.s           .0001
2090
 
2091
; Dispatch based on command string
2092
 
2093
cmdDispatch:
2094
        lea                     cmdString,a2
2095
        clr.l           d4                                              ; command counter
2096
        lea                     -8(a0),a0                       ; backup a character
2097
        move.l  a0,a3                                   ; a3 = start of command on screen
2098
.checkNextCmd:
2099
        bsr                     FromScreen              ; d1 = char from input screen
2100
        move.b  (a2)+,d5
2101
        eor.b           d5,d1                                   ; does it match with command string?
2102
        beq.s           .checkNextCmd   ; If it does, keep matching for longest match
2103
        cmpi.b  #$80,d1                         ; didn't match, was it the end of the command?
2104
        beq.s           .foundCmd
2105
        tst.b           -1(a2)                          ; was end of table hit?
2106
        beq.s           .endOfTable
2107
        addi.w  #2,d4                                   ; increment command counter
2108
        move.l  a3,a0                                   ; reset input pointer
2109
        tst.b           -1(a2)                          ; were we at the end of the command?
2110
        bmi.s           .checkNextCmd   ; if were at end continue, otherwise scan for enf of cmd
2111
.scanToEndOfCmd
2112
        tst.b           (a2)+                                   ; scan to end of command
2113
        beq.s           .endOfTable
2114
        bpl.s           .scanToEndOfCmd
2115
        bmi.s           .checkNextCmd
2116
.endOfTable
2117
        lea                     msgUnknownCmd,a1
2118
        bsr                     DisplayStringCRLF
2119
        bra                     Monitor
2120
.foundCmd:
2121
        lea                     cmdTable,a1             ; a1 = pointer to command address table
2122
        move.w  (a1,d4.w),a1    ; fetch command routine address from table
2123
        jmp                     (a1)                                    ; go execute command
2124
 
2125
cmdBreakpoint:
2126
        bsr                     ignBlanks
2127
        bsr                     FromScreen
2128
        cmpi.b  #'+',d1
2129
        beq                     ArmBreakpoint
2130
        cmpi.b  #'-',d1
2131
        beq                     DisarmBreakpoint
2132
        cmpi.b  #'L',d1
2133
        beq                     ListBreakpoints
2134
        bra                     Monitor
2135
 
2136
cmdTinyBasic:
2137
        bra                     CSTART
2138
 
2139
cmdTestCPU:
2140
        bsr                     cpu_test
2141
        lea                     msg_test_done,a1
2142
        bsr                     DisplayStringCRLF
2143
        bra                     Monitor
2144
 
2145
cmdClearScreen:
2146
        bsr                     ClearScreen
2147
        bsr                     HomeCursor
2148
        bra                     Monitor
2149
 
2150
cmdCore:
2151
        bsr                     ignBlanks
2152
        bsr                     FromScreen
2153
        cmpi.b  #'2',d1                                 ; check range
2154
        blo                     Monitor
2155
        cmpi.b  #'9',d1
2156
        bhi                     Monitor
2157
        subi.b  #'0',d1                                 ; convert ascii to binary
2158
        bsr                     select_iofocus
2159
        bra                     Monitor
2160
 
2161
;-------------------------------------------------------------------------------
2162
; CLOCK 
2163
;    Set the clock register to n which will turn off or on clocks to the CPUs.
2164
;-------------------------------------------------------------------------------
2165
 
2166
cmdClock:
2167
        bsr                     ignBlanks
2168
        bsr                     GetHexNumber
2169
        tst.b           d0                                                      ; was there a number?
2170
        beq                     Monitor
2171
        ori.w           #4,d0                                           ; primary core's clock cannot be turned off
2172
        rol.w           #8,d1                                           ; switch byte order
2173
        move.w  d1,RST_REG+2
2174
        bra                     Monitor
2175
 
2176
;-------------------------------------------------------------------------------
2177
; RESET 
2178
;    Reset the specified core. Resetting the core automatically turns on the
2179
; core's clock.
2180
;-------------------------------------------------------------------------------
2181
 
2182
cmdReset:
2183
        bsr                     ignBlanks
2184
        bsr                     FromScreen
2185
        cmpi.b  #'2',d1                                 ; check range
2186
        blo                     Monitor
2187
        cmpi.b  #'9',d1
2188
        bhi                     Monitor
2189
        subi.b  #'0',d1                                 ; convert ascii to binary
2190
        lsl.w           #1,d1                                           ; make into index
2191
        lea                     tblPow2,a1
2192
        move.w  (a1,d1.w),d1
2193
        rol.w           #8,d1                                           ; reverse byte order
2194
        move.w  d1,RST_REG
2195
        bra                     Monitor
2196
 
2197
tblPow2:
2198
        dc.w            1
2199
        dc.w            2
2200
        dc.w            4
2201
        dc.w            8
2202
        dc.w            16
2203
        dc.w            32
2204
        dc.w            64
2205
        dc.w            128
2206
        dc.w            256
2207
        dc.w            512
2208
        dc.w            1024
2209
        dc.w            2048
2210
        dc.w            4096
2211
        dc.w            8192
2212
        dc.w            16384
2213
        dc.w            32768
2214
        even
2215
 
2216
cmdHelp:
2217
DisplayHelp:
2218
        lea                     HelpMsg,a1
2219
        bsr                     DisplayString
2220
        bra                     Monitor
2221
 
2222
HelpMsg:
2223
        dc.b    "? = Display help",LF,CR
2224
        dc.b  "CORE n = switch to core n, n = 2 to 7",LF,CR
2225
        dc.b  "RESET n = reset core n",LF,CR
2226
        dc.b    "CLS = clear screen",LF,CR
2227
        dc.b    ": = Edit memory bytes",LF,CR
2228
        dc.b    "FB = Fill memory bytes, FW, FL",LF,CR
2229
        dc.b    "L = Load S19 file",LF,CR
2230
        dc.b    "D = Dump memory, DR = dump registers",LF,CR
2231
        dc.b    "BA = start tiny basic",LF,CR
2232
        dc.b  "BR = set breakpoint",LF,CR
2233
        dc.b    "J = Jump to code",LF,CR
2234
        dc.b  "S = send to serial port",LF,CR
2235
        dc.b    "T = cpu test program",LF,CR
2236
        dc.b    "TRAM = test RAM",LF,CR,0
2237
 
2238
msgUnknownCmd:
2239
        dc.b    "command unknown",0
2240
 
2241
msgHello:
2242
        dc.b    LF,CR,"Hello World!",LF,CR,0
2243
        even
2244
 
2245
;------------------------------------------------------------------------------
2246
; This routine borrowed from Gordo's Tiny Basic interpreter.
2247
; Used to fetch a command line. (Not currently used).
2248
;
2249
; d0.b  - command prompt
2250
;------------------------------------------------------------------------------
2251
 
2252
GetCmdLine:
2253
                bsr             DisplayChar             ; display prompt
2254
                move.b  #' ',d0
2255
                bsr             DisplayChar
2256
                lea             CmdBuf,a0
2257
.0001:
2258
                bsr             GetKey
2259
                cmp.b   #CTRLH,d0
2260
                beq.s   .0003
2261
                cmp.b   #CTRLX,d0
2262
                beq.s   .0004
2263
                cmp.b   #CR,d0
2264
                beq.s   .0002
2265
                cmp.b   #' ',d0
2266
                bcs.s   .0001
2267
.0002:
2268
                move.b  d0,(a0)
2269
                lea                     8(a0),a0
2270
                bsr             DisplayChar
2271
                cmp.b   #CR,d0
2272
                beq             .0007
2273
                cmp.l   #CmdBufEnd-1,a0
2274
                bcs.s   .0001
2275
.0003:
2276
                move.b  #CTRLH,d0
2277
                bsr             DisplayChar
2278
                move.b  #' ',d0
2279
                bsr             DisplayChar
2280
                cmp.l   #CmdBuf,a0
2281
                bls.s   .0001
2282
                move.b  #CTRLH,d0
2283
                bsr             DisplayChar
2284
                subq.l  #1,a0
2285
                bra.s   .0001
2286
.0004:
2287
                move.l  a0,d1
2288
                sub.l   #CmdBuf,d1
2289
                beq.s   .0006
2290
                subq    #1,d1
2291
.0005:
2292
                move.b  #CTRLH,d0
2293
                bsr             DisplayChar
2294
                move.b  #' ',d0
2295
                bsr             DisplayChar
2296
                move.b  #CTRLH,d0
2297
                bsr             DisplayChar
2298
                dbra    d1,.0005
2299
.0006:
2300
                lea             CmdBuf,a0
2301
                bra             .0001
2302
.0007:
2303
                move.b  #LF,d0
2304
                bsr             DisplayChar
2305
                rts
2306
 
2307
;------------------------------------------------------------------------------
2308
; S 
2309
; Send data buffer to serial port
2310
; S 40000 40
2311
;------------------------------------------------------------------------------
2312
 
2313
cmdSendSerial:
2314
        bsr                     ignBlanks
2315
        bsr                     GetHexNumber
2316
        beq                     Monitor
2317
        move.l  d1,d6                                   ; d6 points to buffer
2318
        bsr                     ignBlanks
2319
        bsr                     GetHexNumber
2320
        bne.s           .0003
2321
        moveq           #16,d1
2322
.0003:
2323
        move.l  d6,a1                                   ; a1 points to buffer
2324
        move.l  d1,d2                                   ; d2 = count of bytes to send
2325
        bra.s           .0002                                   ; enter loop at bottom
2326
.0001:
2327
        move.b  (a1)+,d1
2328
        move.w  #34,d0                          ; serial putchar
2329
        trap            #15
2330
.0002:
2331
        dbra            d2,.0001
2332
        bra                     Monitor
2333
 
2334
;------------------------------------------------------------------------------
2335
; R 
2336
; Send data buffer to serial port
2337
; R 10000 40
2338
;------------------------------------------------------------------------------
2339
 
2340
cmdReceiveSerial:
2341
        bsr                     ignBlanks
2342
        bsr                     GetHexNumber
2343
        beq                     Monitor
2344
        move.l  d1,d6                                   ; d6 points to buffer
2345
        bsr                     ignBlanks
2346
        bsr                     GetHexNumber
2347
        bne.s           .0003
2348
        moveq           #16,d1
2349
.0003:
2350
        move.l  d6,a1                                   ; a1 points to buffer
2351
        move.l  d1,d2                                   ; d2 = count of bytes to send
2352
        bra.s           .0002                                   ; enter loop at bottom
2353
.0001:
2354
        move.w  #36,d0                          ; serial peek char
2355
        trap            #15
2356
        tst.l           d1
2357
        bmi.s           .0001
2358
        move.b  d1,(a1)+
2359
.0002:
2360
        dbra            d2,.0001
2361
        bra                     Monitor
2362
 
2363
;------------------------------------------------------------------------------
2364
; Fill memory
2365
;
2366
; FB = fill bytes               FB 00000010 100 FF      ; fill starting at 10 for 256 bytes
2367
; FW = fill words
2368
; FL = fill longs
2369
; F = fill bytes
2370
;------------------------------------------------------------------------------
2371
 
2372
cmdFillB:
2373
        bsr                     ignBlanks
2374
        bsr                     GetHexNumber
2375
        move.l  d1,a1                                   ; a1 = start
2376
        bsr                     ignBlanks
2377
        bsr                     GetHexNumber
2378
        move.l  d1,d3                                   ; d3 = count
2379
        beq                     Monitor
2380
        bsr                     ignBlanks
2381
        bsr                     GetHexNumber    ; fill value
2382
.fmem:
2383
        move.b  d1,(a1)+
2384
        sub.l           #1,d3
2385
        bne.s           .fmem
2386
        bra                     Monitor
2387
 
2388
cmdFillW:
2389
        bsr                     ignBlanks
2390
        bsr                     GetHexNumber
2391
        move.l  d1,a1                                   ; a1 = start
2392
        bsr                     ignBlanks
2393
        bsr                     GetHexNumber
2394
        move.l  d1,d3                                   ; d3 = count
2395
        beq                     Monitor
2396
        bsr                     ignBlanks
2397
        bsr                     GetHexNumber    ; fill value
2398
.fmem:
2399
        move.w  d1,(a1)+
2400
        sub.l           #1,d3
2401
        bne.s           .fmem
2402
        bra                     Monitor
2403
 
2404
cmdFillL:
2405
        bsr                     ignBlanks
2406
        bsr                     GetHexNumber
2407
        move.l  d1,a1                                   ; a1 = start
2408
        bsr                     ignBlanks
2409
        bsr                     GetHexNumber
2410
        move.l  d1,d3                                   ; d3 = count
2411
        beq                     Monitor
2412
        bsr                     ignBlanks
2413
        bsr                     GetHexNumber    ; fill value
2414
.fmem:
2415
        move.l  d1,(a1)+
2416
        sub.l           #1,d3
2417
        bne.s           .fmem
2418
        bra                     Monitor
2419
 
2420
;------------------------------------------------------------------------------
2421
; Modifies:
2422
;       a0      - text pointer
2423
;------------------------------------------------------------------------------
2424
 
2425
ignBlanks:
2426
        move.l  d1,-(a7)
2427
.0001:
2428
        bsr                     FromScreen
2429
        cmpi.b  #' ',d1
2430
        beq.s           .0001
2431
        lea                     -8(a0),a0
2432
        move.l  (a7)+,d1
2433
        rts
2434
 
2435
;------------------------------------------------------------------------------
2436
; Edit memory byte.
2437
;    Bytes are built into long words in case the memory is only longword
2438
; accessible.
2439
;------------------------------------------------------------------------------
2440
 
2441
cmdEditMemory:
2442
        bsr                     ignBlanks
2443
        bsr                     GetHexNumber
2444
        move.l  d1,a1
2445
edtmem1:
2446
        clr.l           d2
2447
        bsr                     ignBlanks
2448
        bsr                     GetHexNumber
2449
        move.b  d1,d2
2450
;       move.b  d1,(a1)+
2451
        bsr                     ignBlanks
2452
        bsr                     GetHexNumber
2453
        lsl.l           #8,d2
2454
        move.b  d1,d2
2455
;       move.b  d1,(a1)+
2456
        bsr                     ignBlanks
2457
        bsr                     GetHexNumber
2458
        lsl.l           #8,d2
2459
        move.b  d1,d2
2460
;       move.b  d1,(a1)+
2461
        bsr                     ignBlanks
2462
        bsr                     GetHexNumber
2463
        lsl.l           #8,d2
2464
        move.b  d1,d2
2465
        move.l  d2,(a1)+
2466
;       move.b  d1,(a1)+
2467
        clr.l           d2
2468
        bsr                     ignBlanks
2469
        bsr                     GetHexNumber
2470
        move.b  d1,d2
2471
;       move.b  d1,(a1)+
2472
        bsr                     ignBlanks
2473
        bsr                     GetHexNumber
2474
        lsl.l           #8,d2
2475
        move.b  d1,d2
2476
;       move.b  d1,(a1)+
2477
        bsr                     ignBlanks
2478
        bsr                     GetHexNumber
2479
        lsl.l           #8,d2
2480
        move.b  d1,d2
2481
;       move.b  d1,(a1)+
2482
        bsr                     ignBlanks
2483
        bsr                     GetHexNumber
2484
        lsl.l           #8,d2
2485
        move.b  d1,d2
2486
;       move.b  d1,(a1)+
2487
        move.l  d2,(a1)+
2488
        bra                     Monitor
2489
 
2490
;------------------------------------------------------------------------------
2491
; Execute code at the specified address.
2492
;------------------------------------------------------------------------------
2493
 
2494
cmdJump:
2495
ExecuteCode:
2496
        bsr                     ignBlanks
2497
        bsr                     GetHexNumber
2498
        move.l  d1,a0
2499
        jsr                     (a0)
2500
        bra     Monitor
2501
 
2502
;------------------------------------------------------------------------------
2503
; Do a memory dump of the requested location.
2504
; D 0800 0850
2505
;------------------------------------------------------------------------------
2506
 
2507
cmdDumpMemory:
2508
        bsr                     ignBlanks
2509
        bsr                     GetHexNumber
2510
        beq                     Monitor                 ; was there a number ? no, other garbage, just ignore
2511
        move.l  d1,d3                           ; save off start of range
2512
        bsr                     ignBlanks
2513
        bsr                     GetHexNumber
2514
        bne.s           DumpMem1
2515
        move.l  d3,d1
2516
        addi.l  #64,d1                  ; no end specified, just dump 64 bytes
2517
DumpMem1:
2518
        move.l  d3,a0
2519
        move.l  d1,a1
2520
        bsr                     CRLF
2521
.0001:
2522
        cmpa.l  a0,a1
2523
        bls                     Monitor
2524
        bsr                     DisplayMem
2525
        bra.s           .0001
2526
 
2527
;------------------------------------------------------------------------------
2528
; Display memory dump in a format suitable for edit.
2529
;
2530
;       :12345678 00 11 22 33 44 55 66 77  "........"
2531
;
2532
; Modifies:
2533
;               d1,d2,a0
2534
;------------------------------------------------------------------------------
2535
 
2536
DisplayMem:
2537
        move.b  #':',d1
2538
        bsr                     DisplayChar
2539
        move.l  a0,d1
2540
        bsr                     DisplayTetra
2541
        moveq           #7,d2
2542
dspmem1:
2543
        move.b  #' ',d1
2544
        bsr                     DisplayChar
2545
        move.b  (a0)+,d1
2546
        bsr                     DisplayByte
2547
        dbra            d2,dspmem1
2548
        bsr                     DisplayTwoSpaces
2549
        move.b  #34,d1
2550
        bsr                     DisplayChar
2551
        lea                     -8(a0),a0
2552
        moveq           #7,d2
2553
.0002:
2554
        move.b  (a0)+,d1
2555
        cmp.b           #' ',d1
2556
        blo.s           .0003
2557
        cmp.b           #127,d1
2558
        bls.s           .0001
2559
.0003:
2560
        move.b  #'.',d1
2561
.0001:
2562
        bsr                     DisplayChar
2563
        dbra            d2,.0002
2564
        move.b  #34,d1
2565
        bsr                     DisplayChar
2566
        bsr                     CheckForCtrlC
2567
        bra                     CRLF
2568
 
2569
;------------------------------------------------------------------------------
2570
; Dump Registers
2571
;    The dump is in a format that allows the register value to be edited.
2572
;
2573
; RegD0 12345678
2574
; RegD1 77777777
2575
;       ... etc
2576
;------------------------------------------------------------------------------
2577
 
2578
cmdDumpRegs:
2579
        bsr                     CRLF
2580
        move.w  #15,d0                                  ; number of registers-1
2581
        lea                     msg_reglist,a0  ;
2582
        lea                     msg_regs,a1
2583
        lea                     Regsave,a2                      ; a2 points to register save area
2584
.0001:
2585
        bsr                     DisplayString
2586
        move.b  (a0)+,d1
2587
        bsr                     DisplayChar
2588
        move.b  (a0)+,d1
2589
        bsr                     DisplayChar
2590
        bsr                     DisplaySpace
2591
        move.l  (a2)+,d1
2592
        bsr                     DisplayTetra
2593
        bsr                     CRLF
2594
        dbra            d0,.0001
2595
        bsr                     DisplayString
2596
        move.b  (a0)+,d1
2597
        bsr                     DisplayChar
2598
        move.b  (a0)+,d1
2599
        bsr                     DisplayChar
2600
        bsr                     DisplaySpace
2601
        move.l  Regsave+$44,d1
2602
        bsr                     DisplayTetra
2603
        bsr                     CRLF
2604
        bsr                     DisplayString
2605
        move.b  (a0)+,d1
2606
        bsr                     DisplayChar
2607
        move.b  (a0)+,d1
2608
        bsr                     DisplayChar
2609
        bsr                     DisplaySpace
2610
        move.w  Regsave+$40,d1
2611
        bsr                     DisplayWyde
2612
        bsr                     CRLF
2613
        bra                     Monitor
2614
 
2615
msg_regs:
2616
        dc.b    "Reg",0
2617
msg_reglist:
2618
        dc.b    "D0D1D2D3D4D5D6D7A0A1A2A3A4A5A6A7PCSR",0
2619
 
2620
        align   1
2621
 
2622
;------------------------------------------------------------------------------
2623
;------------------------------------------------------------------------------
2624
 
2625
cmdTestSerialReceive:
2626
.0002:
2627
        moveq           #36,d0                          ; serial get char from buffer
2628
        trap            #15
2629
;       bsr                     SerialPeekCharDirect
2630
        tst.w           d1
2631
        bmi.s           .0001
2632
        cmpi.b  #CTRLZ,d1
2633
        beq                     .0003
2634
        bsr                     DisplayChar
2635
.0001:
2636
        bsr                     CheckForCtrlC
2637
        bra                     .0002
2638
.0003:
2639
        bsr                     _KeybdInit
2640
        bra                     Monitor
2641
 
2642
;------------------------------------------------------------------------------
2643
; Get a hexidecimal number. Maximum of eight digits.
2644
;
2645
; Returns:
2646
;               d0 = number of digits
2647
;               d1 = value of number
2648
;               zf = number of digits == 0
2649
;------------------------------------------------------------------------------
2650
 
2651
GetHexNumber:
2652
        move.l  d2,-(a7)
2653
        clr.l           d2
2654
        moveq           #0,d0
2655
.0002:
2656
        bsr                     FromScreen
2657
        bsr                     AsciiToHexNybble
2658
        cmp.b           #$ff,d1
2659
        beq.s           .0001
2660
        lsl.l           #4,d2
2661
        andi.l  #$0f,d1
2662
        or.l            d1,d2
2663
        addq            #1,d0
2664
        cmpi.b  #8,d0
2665
        blo.s           .0002
2666
.0001:
2667
        move.l  d2,d1
2668
        move.l  (a7)+,d2
2669
        tst.b           d0
2670
        rts
2671
 
2672
;------------------------------------------------------------------------------
2673
; Convert ASCII character in the range '0' to '9', 'a' tr 'f' or 'A' to 'F'
2674
; to a hex nybble.
2675
;------------------------------------------------------------------------------
2676
 
2677
AsciiToHexNybble:
2678
        cmpi.b  #'0',d1
2679
        blo.s           gthx3
2680
        cmpi.b  #'9',d1
2681
        bhi.s           gthx5
2682
        subi.b  #'0',d1
2683
        rts
2684
gthx5:
2685
        cmpi.b  #'A',d1
2686
        blo.s           gthx3
2687
        cmpi.b  #'F',d1
2688
        bhi.s           gthx6
2689
        addi.b  #10-'A',d1
2690
        rts
2691
gthx6:
2692
        cmpi.b  #'a',d1
2693
        blo.s           gthx3
2694
        cmpi.b  #'f',d1
2695
        bhi.s           gthx3
2696
        addi.b  #10-'a',d1
2697
        rts
2698
gthx3:
2699
        moveq   #-1,d1          ; not a hex number
2700
        rts
2701
 
2702
;------------------------------------------------------------------------------
2703
;------------------------------------------------------------------------------
2704
 
2705
DisplayTwoSpaces:
2706
        move.l  d1,-(a7)
2707
        move.b  #' ',d1
2708
        bsr                     DisplayChar
2709
dspspc1:
2710
        bsr                     DisplayChar
2711
        move.l  (a7)+,d1
2712
        rts
2713
 
2714
DisplaySpace:
2715
        move.l  d1,-(a7)
2716
        move.b  #' ',d1
2717
        bra                     dspspc1
2718
 
2719
;------------------------------------------------------------------------------
2720
; Display the 32 bit word in D1.L
2721
;------------------------------------------------------------------------------
2722
 
2723
DisplayTetra:
2724
        swap    d1
2725
        bsr             DisplayWyde
2726
        swap    d1
2727
 
2728
;------------------------------------------------------------------------------
2729
; Display the byte in D1.W
2730
;------------------------------------------------------------------------------
2731
 
2732
DisplayWyde:
2733
        ror.w           #8,d1
2734
        bsr                     DisplayByte
2735
        rol.w           #8,d1
2736
 
2737
;------------------------------------------------------------------------------
2738
; Display the byte in D1.B
2739
;------------------------------------------------------------------------------
2740
 
2741
DisplayByte:
2742
        ror.b           #4,d1
2743
        bsr                     DisplayNybble
2744
        rol.b           #4,d1
2745
 
2746
;------------------------------------------------------------------------------
2747
; Display nybble in D1.B
2748
;------------------------------------------------------------------------------
2749
 
2750
DisplayNybble:
2751
        move.l  d1,-(a7)
2752
        andi.b  #$F,d1
2753
        addi.b  #'0',d1
2754
        cmpi.b  #'9',d1
2755
        bls.s           .0001
2756
        addi.b  #7,d1
2757
.0001:
2758
        bsr                     DisplayChar
2759
        move.l  (a7)+,d1
2760
        rts
2761
 
2762
;------------------------------------------------------------------------------
2763
;------------------------------------------------------------------------------
2764
;
2765
;DisplayHexNumber:
2766
;       move.w  #$A6A6,leds             ; diagnostics
2767
;       move.l  #VDGREG,a6
2768
;       move.w  #7,d2           ; number-1 of digits to display
2769
;disphnum1:
2770
;       move.b  d1,d0           ; get digit into d0.b
2771
;       andi.w  #$0f,d0
2772
;       cmpi.w  #$09,d0
2773
;       bls.s   disphnum2
2774
;       addi.w  #7,d0
2775
;disphnum2:
2776
;       addi.w  #$30,d0 ; convert to display char
2777
;       move.w  d2,d3           ; char count into d3
2778
;       asl.w   #3,d3           ; scale * 8
2779
;disphnum3:
2780
;       move.w  $42C(a6),d4                     ; read character queue index into d4
2781
;       cmp.w   #28,d4                                  ; allow up 28 entries to be in progress
2782
;       bhs.s   disphnum3                               ; branch if too many chars queued
2783
;       ext.w   d0                                              ; zero out high order bits
2784
;       move.w  d0,$420(a6)                     ; set char code
2785
;       move.w  #WHITE,$422(a6)         ; set fg color
2786
;       move.w  #DARK_BLUE,$424(a6)     ; set bk color
2787
;       move.w  d3,$426(a6)                     ; set x pos
2788
;       move.w  #8,$428(a6)                     ; set y pos
2789
;       move.w  #$0707,$42A(a6)         ; set font x,y extent
2790
;       move.w  #0,$42E(a6)                     ; pulse character queue write signal
2791
;       ror.l   #4,d1                                   ; rot to next digit
2792
;       dbeq    d2,disphnum1
2793
;       jmp             (a5)
2794
 
2795
;===============================================================================
2796
;    Perform ram test. (Uses checkerboard testing).
2797
;
2798
;    Local ram, which does not get tested, is used for the stack.
2799
;===============================================================================
2800
 
2801
DisplayAddr:
2802
        move.l a0,d1
2803
        lsr.l #8,d1
2804
        lsr.l #8,d1
2805
        lsr.l #4,d1
2806
        subi.w #512,d1
2807
        bin2bcd d1
2808
        bsr     DisplayWyde
2809
        move.b #CR,d1
2810
        bra DisplayChar
2811
        btst #$83,d0
2812
 
2813
cmdTestRAM:
2814
ramtest:
2815
        move.w  #$A5A5,leds             ; diagnostics
2816
  move.l #$aaaaaaaa,d3
2817
  move.l #$55555555,d4
2818
  bsr ramtest0
2819
  ; switch checkerboard pattern and repeat test.
2820
  exg d3,d4
2821
  bsr ramtest0
2822
        ; Save last ram address in end of memory pointer.
2823
rmtst5:
2824
        moveq #37,d0                                    ; lock semaphore
2825
        moveq #MEMORY_SEMA,d1
2826
        trap #15
2827
  move.l a0,memend
2828
        ; Create very first memory block.
2829
  suba.l #12,a0
2830
  move.l a0,$20000004           ; length of block
2831
  move.l #$46524545,$20000000
2832
        moveq #38,d0                                    ; unlock semaphore
2833
        moveq #MEMORY_SEMA,d1
2834
        trap #15
2835
  rts
2836
 
2837
ramtest0:
2838
        move.l d3,d0
2839
  movea.l #$20000000,a0
2840
;-----------------------------------------------------------
2841
;   Write checkerboard pattern to ram then read it back to
2842
; find the highest usable ram address (maybe). This address
2843
; must be lower than the start of the rom (0xe00000).
2844
;-----------------------------------------------------------
2845
ramtest1:
2846
  move.l d3,(a0)+
2847
  move.l d4,(a0)+
2848
  move.l a0,d1
2849
  tst.w d1
2850
  bne.s rmtst1
2851
  bsr DisplayAddr
2852
  bsr CheckForCtrlC
2853
rmtst1:
2854
  cmpa.l #$3FFFFFF8,a0
2855
  blo.s ramtest1
2856
  bsr   CRLF
2857
;------------------------------------------------------
2858
;   Save maximum useable address for later comparison.
2859
;------------------------------------------------------
2860
ramtest6:
2861
        move.w  #$A7A7,leds             ; diagnostics
2862
  movea.l a0,a2
2863
  movea.l #$20000000,a0
2864
;--------------------------------------------
2865
;   Read back checkerboard pattern from ram.
2866
;--------------------------------------------
2867
ramtest2
2868
  move.l (a0)+,d5
2869
  move.l (a0)+,d6
2870
  cmpa.l a2,a0
2871
  bhs.s ramtest3
2872
  move.l a0,d1
2873
  tst.w d1
2874
  bne.s rmtst2
2875
  bsr   DisplayAddr
2876
        bsr CheckForCtrlC
2877
rmtst2
2878
  cmp.l d3,d5
2879
  bne.s rmtst3
2880
  cmp.l d4,d6
2881
  beq.s ramtest2
2882
;----------------------------------
2883
; Report error in ram.
2884
;----------------------------------
2885
rmtst3
2886
        bsr CRLF
2887
        moveq   #'E',d1
2888
        bsr DisplayChar
2889
        bsr DisplaySpace
2890
        move.l a0,d1
2891
        bsr DisplayTetra
2892
        bsr DisplaySpace
2893
        move.l d5,d1
2894
        bsr DisplayTetra
2895
        bsr CheckForCtrlC
2896
        bra ramtest2
2897
ramtest3
2898
        rts
2899
 
2900
;==============================================================================
2901
; Load an S19 format file
2902
;==============================================================================
2903
 
2904
cmdLoadS19:
2905
        bsr                     CRLF
2906
        bra                     ProcessRec
2907
NextRec:
2908
        bsr                     sGetChar
2909
        cmpi.b  #LF,d1
2910
        bne                     NextRec
2911
        move.b  #'.',d1
2912
        bsr                     DisplayChar
2913
ProcessRec:
2914
        bsr                     CheckForCtrlC   ; check for CTRL-C once per record
2915
        bsr                     sGetChar
2916
        cmpi.b  #CR,d1
2917
        beq.s           ProcessRec
2918
        clr.b           S19Checksum
2919
        move.b  d1,d4
2920
        cmpi.b  #CTRLZ,d4                       ; CTRL-Z ?
2921
        beq                     Monitor
2922
        cmpi.b  #'S',d4                         ; All records must begin with an 'S'
2923
        bne.s           NextRec
2924
        bsr                     sGetChar
2925
        move.b  d1,d4
2926
        cmpi.b  #'0',d4                         ; Record type must be between '0' and '9'
2927
        blo.s           NextRec
2928
        cmpi.b  #'9',d4                         ; d4 = record type
2929
        bhi.s           NextRec
2930
        bsr                     sGetChar                        ; get byte count for record
2931
        bsr                     AsciiToHexNybble
2932
        move.b  d1,d2
2933
        bsr                     sGetChar
2934
        bsr                     AsciiToHexNybble
2935
        lsl.b           #4,d2
2936
        or.b            d2,d1                                   ; d1 = byte count
2937
        move.b  d1,d3                                   ; d3 = byte count
2938
        add.b           d3,S19Checksum
2939
        cmpi.b  #'0',d4                         ; manufacturer ID record, ignore
2940
        beq                     NextRec
2941
        cmpi.b  #'1',d4
2942
        beq                     ProcessS1
2943
        cmpi.b  #'2',d4
2944
        beq                     ProcessS2
2945
        cmpi.b  #'3',d4
2946
        beq                     ProcessS3
2947
        cmpi.b  #'5',d4                         ; record count record, ignore
2948
        beq                     NextRec
2949
        cmpi.b  #'7',d4
2950
        beq                     ProcessS7
2951
        cmpi.b  #'8',d4
2952
        beq                     ProcessS8
2953
        cmpi.b  #'9',d4
2954
        beq                     ProcessS9
2955
        bra                     NextRec
2956
 
2957
pcssxa:
2958
        move.l  a1,d1
2959
        bsr                     DisplayTetra
2960
        move.b  #CR,d1
2961
        bsr                     DisplayChar
2962
        andi.w  #$ff,d3
2963
        subi.w  #1,d3                   ; one less for dbra
2964
.0001:
2965
        clr.l           d2
2966
        bsr                     sGetChar
2967
        bsr                     AsciiToHexNybble
2968
        lsl.l           #4,d2
2969
        or.b            d1,d2
2970
        bsr                     sGetChar
2971
        bsr                     AsciiToHexNybble
2972
        lsl.l           #4,d2
2973
        or.b            d1,d2
2974
        add.b           d2,S19Checksum
2975
        move.b  d2,(a1)+                        ; move byte to memory
2976
        dbra            d3,.0001
2977
        ; Get the checksum byte
2978
        clr.l           d2
2979
        bsr                     sGetChar
2980
        bsr                     AsciiToHexNybble
2981
        lsl.l           #4,d2
2982
        or.b            d1,d2
2983
        bsr                     sGetChar
2984
        bsr                     AsciiToHexNybble
2985
        lsl.l           #4,d2
2986
        or.b            d1,d2
2987
        eor.b           #$FF,d2
2988
        cmp.b           S19Checksum,d2
2989
        beq                     NextRec
2990
        move.b  #'E',d1
2991
        bsr                     DisplayChar
2992
        bra                     NextRec
2993
 
2994
ProcessS1:
2995
        bsr                     S19Get16BitAddress
2996
        bra                     pcssxa
2997
ProcessS2:
2998
        bsr                     S19Get24BitAddress
2999
        bra                     pcssxa
3000
ProcessS3:
3001
        bsr                     S19Get32BitAddress
3002
        bra                     pcssxa
3003
ProcessS7:
3004
        bsr                     S19Get32BitAddress
3005
        move.l  a1,S19StartAddress
3006
        bsr                     _KeybdInit
3007
        bra                     Monitor
3008
ProcessS8:
3009
        bsr                     S19Get24BitAddress
3010
        move.l  a1,S19StartAddress
3011
        bsr                     _KeybdInit
3012
        bra                     Monitor
3013
ProcessS9:
3014
        bsr                     S19Get16BitAddress
3015
        move.l  a1,S19StartAddress
3016
        bsr                     _KeybdInit
3017
        bra                     Monitor
3018
 
3019
S19Get16BitAddress:
3020
        clr.l           d2
3021
        bsr                     sGetChar
3022
        bsr                     AsciiToHexNybble
3023
        move.b  d1,d2
3024
        bra                     S1932b
3025
 
3026
S19Get24BitAddress:
3027
        clr.l           d2
3028
        bsr                     sGetChar
3029
        bsr                     AsciiToHexNybble
3030
        move.b  d1,d2
3031
        bra                     S1932a
3032
 
3033
S19Get32BitAddress:
3034
        clr.l           d2
3035
        bsr                     sGetChar
3036
        bsr                     AsciiToHexNybble
3037
        move.b  d1,d2
3038
        bsr                     sGetChar
3039
        bsr                     AsciiToHexNybble
3040
        lsl.l           #4,d2
3041
        or.b            d1,d2
3042
        bsr                     sGetChar
3043
        bsr                     AsciiToHexNybble
3044
        lsl.l           #4,d2
3045
        or.b            d1,d2
3046
S1932a:
3047
        bsr                     sGetChar
3048
        bsr                     AsciiToHexNybble
3049
        lsl.l           #4,d2
3050
        or.b            d1,d2
3051
        bsr                     sGetChar
3052
        bsr                     AsciiToHexNybble
3053
        lsl.l           #4,d2
3054
        or.b            d1,d2
3055
S1932b:
3056
        bsr                     sGetChar
3057
        bsr                     AsciiToHexNybble
3058
        lsl.l           #4,d2
3059
        or.b            d1,d2
3060
        bsr                     sGetChar
3061
        bsr                     AsciiToHexNybble
3062
        lsl.l           #4,d2
3063
        or.b            d1,d2
3064
        bsr                     sGetChar
3065
        bsr                     AsciiToHexNybble
3066
        lsl.l           #4,d2
3067
        or.b            d1,d2
3068
        clr.l           d4
3069
        move.l  d2,a1
3070
        ; Add bytes from address value to checksum
3071
        add.b           d2,S19Checksum
3072
        lsr.l           #8,d2
3073
        add.b           d2,S19Checksum
3074
        lsr.l           #8,d2
3075
        add.b           d2,S19Checksum
3076
        lsr.l           #8,d2
3077
        add.b           d2,S19Checksum
3078
        rts
3079
 
3080
;------------------------------------------------------------------------------
3081
; Get a character from auxillary input. Waiting for a character is limited to
3082
; 32000 tries. If a character is not available within the limit, then a return
3083
; to the monitor is done.
3084
;
3085
;       Parameters:
3086
;               none
3087
; Returns:
3088
;               d1 = character from receive buffer or -1 if no char available
3089
;------------------------------------------------------------------------------
3090
 
3091
sGetChar:
3092
        movem.l d0/d2,-(a7)
3093
        move.w  #32000,d2
3094
.0001:
3095
        moveq           #36,d0                          ; serial get char from buffer
3096
        trap            #15
3097
        tst.w           d1                                              ; was there a char available?
3098
        bpl.s           .0002
3099
        dbra            d2,.0001                        ; no - try again
3100
        movem.l (a7)+,d0/d2
3101
.0003:
3102
        bsr                     _KeybdInit
3103
        bra                     Monitor                         ; ran out of tries
3104
.0002:
3105
        movem.l (a7)+,d0/d2
3106
        cmpi.b  #CTRLZ,d1                       ; receive end of file?
3107
        beq                     .0003
3108
        rts
3109
 
3110
AudioInputTest:
3111
        rts
3112
BouncingBalls:
3113
        rts
3114
GraphicsDemo:
3115
        rts
3116
ClearScreen:
3117
        bra             clear_screen
3118
        rts
3119
 
3120
;------------------------------------------------------------------------------
3121
; Reverse the order of bytes in d1.
3122
;------------------------------------------------------------------------------
3123
 
3124
rbo:
3125
        rol.w           #8,d1
3126
        swap            d1
3127
        rol.w           #8,d1
3128
        rts
3129
 
3130
;==============================================================================
3131
; Serial I/O routines
3132
;==============================================================================
3133
 
3134
;------------------------------------------------------------------------------
3135
; Initialize the serial port an enhanced 6551 circuit.
3136
;
3137
; Select internal baud rate clock divider for 9600 baud
3138
; Reset fifos, set threshold to 3/4 full on transmit and 3/4 empty on receive
3139
; Note that the byte order is swapped.
3140
;------------------------------------------------------------------------------
3141
 
3142
SerialInit:
3143
        clr.w           SerHeadRcv                                      ; clear receive buffer indexes
3144
        clr.w           SerTailRcv
3145
        clr.b           SerRcvXon                                               ; and Xon,Xoff flags
3146
        clr.b           SerRcvXoff
3147
        move.l  #$09000000,d0                           ; dtr,rts active, rxint enabled, no parity
3148
        move.l  d0,ACIA+ACIA_CMD
3149
;       move.l  #$1E00F700,d0                           ; fifos enabled
3150
        move.l  #$1E000000,d0                           ; fifos disabled
3151
        move.l  d0,ACIA+ACIA_CTRL
3152
        rts
3153
;       move.l  #$0F000000,d0                           ; transmit a break for a while
3154
;       move.l  d0,ACIA+ACIA_CMD
3155
;       move.l  #300000,d2                                      ; wait 100 ms
3156
;       bra                     .0001
3157
;.0003:
3158
;       swap            d2
3159
;.0001:
3160
;       nop
3161
;       dbra            d2,.0001
3162
;.0002:
3163
;       swap            d2
3164
;       dbra            d2,.0003
3165
;       move.l  #$07000000,d0                           ; clear break
3166
;       move.l  d0,ACIA+ACIA_CMD
3167
;       rts
3168
 
3169
;------------------------------------------------------------------------------
3170
; SerialGetChar
3171
;
3172
; Check the serial port buffer to see if there's a char available. If there's
3173
; a char available then return it. If the buffer is almost empty then send an
3174
; XON.
3175
;
3176
; Stack Space:
3177
;               2 long words
3178
; Parameters:
3179
;               none
3180
; Modifies:
3181
;               d0,a0
3182
; Returns:
3183
;               d1 = character or -1
3184
;------------------------------------------------------------------------------
3185
 
3186
SerialGetChar:
3187
        move.l          d2,-(a7)
3188
        movec                   coreno,d0
3189
        swap                    d0
3190
        moveq                   #SERIAL_SEMA,d1
3191
        bsr                             LockSemaphore
3192
        bsr                             SerialRcvCount                  ; check number of chars in receive buffer
3193
        cmpi.w          #8,d0                                                           ; less than 8?
3194
        bhi                             .sgc2
3195
        tst.b                   SerRcvXon                                               ; skip sending XON if already sent
3196
        bne                     .sgc2                           ; XON already sent?
3197
        move.b          #XON,d1                                                 ; if <8 send an XON
3198
        clr.b                   SerRcvXoff                                      ; clear XOFF status
3199
        move.b          d1,SerRcvXon                            ; flag so we don't send it multiple times
3200
        bsr                             SerialPutChar                           ; send it
3201
.sgc2:
3202
        move.w          SerHeadRcv,d1                           ; check if anything is in buffer
3203
        cmp.w                   SerTailRcv,d1
3204
        beq                             .NoChars                                                ; no?
3205
        lea                             SerRcvBuf,a0
3206
        move.b          (a0,d1.w),d1                            ; get byte from buffer
3207
        addi.w          #1,SerHeadRcv
3208
        andi.w          #$FFF,SerHeadRcv                ; 4k wrap around
3209
        andi.l          #$FF,d1
3210
        bra                             .Xit
3211
.NoChars:
3212
        moveq                   #-1,d1
3213
.Xit:
3214
        exg                             d1,d2
3215
        movec                   coreno,d0
3216
        swap                    d0
3217
        moveq                   #SERIAL_SEMA,d1
3218
        bsr                             UnlockSemaphore
3219
        exg                             d2,d1
3220
        move.l          (a7)+,d2
3221
        rts
3222
 
3223
;------------------------------------------------------------------------------
3224
; SerialPeekChar
3225
;
3226
; Check the serial port buffer to see if there's a char available. If there's
3227
; a char available then return it. But don't update the buffer indexes. No need
3228
; to send an XON here.
3229
;
3230
; Stack Space:
3231
;               0 words
3232
; Parameters:
3233
;               none
3234
; Modifies:
3235
;               d0,d2,a0
3236
; Returns:
3237
;               d1 = character or -1
3238
;------------------------------------------------------------------------------
3239
 
3240
SerialPeekChar:
3241
        movec           coreno,d0
3242
        swap            d0
3243
        moveq           #SERIAL_SEMA,d1
3244
        bsr                     LockSemaphore
3245
        move.w  SerHeadRcv,d2           ; check if anything is in buffer
3246
        cmp.w           SerTailRcv,d2
3247
        beq                     .NoChars                                ; no?
3248
        lea                     SerRcvBuf,a0
3249
        move.b  (a0,d2.w),d2            ; get byte from buffer
3250
        bra                     .Xit
3251
.NoChars:
3252
        moveq           #-1,d2
3253
.Xit:
3254
        movec           coreno,d0
3255
        swap            d0
3256
        moveq           #SERIAL_SEMA,d1
3257
        bsr                     LockSemaphore
3258
        move            d2,d1
3259
        rts
3260
 
3261
;------------------------------------------------------------------------------
3262
; SerialPeekChar
3263
;               Get a character directly from the I/O port. This bypasses the input
3264
; buffer.
3265
;
3266
; Stack Space:
3267
;               0 words
3268
; Parameters:
3269
;               none
3270
; Modifies:
3271
;               d
3272
; Returns:
3273
;               d1 = character or -1
3274
;------------------------------------------------------------------------------
3275
 
3276
SerialPeekCharDirect:
3277
        move.b  ACIA+ACIA_STAT,d1       ; get serial status
3278
        btst            #3,d1                                                   ; look for Rx not empty
3279
        beq.s           .0001
3280
        moveq.l #0,d1                                                   ; clear upper bits of return value
3281
        move.b  ACIA+ACIA_RX,d1         ; get data from ACIA
3282
        rts                                                                                             ; return
3283
.0001:
3284
        moveq           #-1,d1
3285
        rts
3286
 
3287
;------------------------------------------------------------------------------
3288
; SerialPutChar
3289
;    Put a character to the serial transmitter. This routine blocks until the
3290
; transmitter is empty.
3291
;
3292
; Stack Space
3293
;               0 words
3294
; Parameters:
3295
;               d1.b = character to put
3296
; Modifies:
3297
;               none
3298
;------------------------------------------------------------------------------
3299
 
3300
SerialPutChar:
3301
        movem.l d0/d1,-(a7)                             ; push d0,d1
3302
.0001:
3303
        move.b  ACIA+ACIA_STAT,d0       ; wait until the uart indicates tx empty
3304
        btst            #4,d0                                                   ; bit #4 of the status reg
3305
        beq.s           .0001                                   ; branch if transmitter is not empty
3306
        move.b  d1,ACIA+ACIA_TX         ; send the byte
3307
        movem.l (a7)+,d0/d1                             ; pop d0,d1
3308
        rts
3309
 
3310
;------------------------------------------------------------------------------
3311
; Reverse the order of bytes in d1.
3312
;------------------------------------------------------------------------------
3313
 
3314
SerialRbo:
3315
        rol.w           #8,d1
3316
        swap            d1
3317
        rol.w           #8,d1
3318
        rts
3319
 
3320
;------------------------------------------------------------------------------
3321
; Calculate number of character in input buffer
3322
;
3323
; Returns:
3324
;               d0 = number of bytes in buffer.
3325
;------------------------------------------------------------------------------
3326
 
3327
SerialRcvCount:
3328
        move.w  SerTailRcv,d0
3329
        sub.w           SerHeadRcv,d0
3330
        bge                     .0001
3331
        move.w  #$1000,d0
3332
        sub.w           SerHeadRcv,d0
3333
        add.w           SerTailRcv,d0
3334
.0001:
3335
        rts
3336
 
3337
;------------------------------------------------------------------------------
3338
; Serial IRQ routine
3339
;
3340
; Keeps looping as long as it finds characters in the ACIA recieve buffer/fifo.
3341
; Received characters are buffered. If the buffer becomes full, new characters
3342
; will be lost.
3343
;
3344
; Parameters:
3345
;               none
3346
; Modifies:
3347
;               none
3348
; Returns:
3349
;               d1 = -1 if IRQ handled, otherwise zero
3350
;------------------------------------------------------------------------------
3351
 
3352
SerialIRQ:
3353
        move.w  #$2300,sr                                               ; disable lower level IRQs
3354
        movem.l d0/d1/d2/a0,-(a7)
3355
        movec           coreno,d0
3356
        swap            d0
3357
        moveq           #SERIAL_SEMA,d1
3358
        bsr                     LockSemaphore
3359
sirqNxtByte:
3360
        move.b  ACIA+ACIA_STAT,d1               ; check the status
3361
        btst            #3,d1                                                           ; bit 3 = rx full
3362
        beq                     notRxInt
3363
        move.b  ACIA+ACIA_RX,d1
3364
sirq0001:
3365
        move.w  SerTailRcv,d0                           ; check if recieve buffer full
3366
        addi.w  #1,d0
3367
        andi.w  #$FFF,d0
3368
        cmp.w           SerHeadRcv,d0
3369
        beq                     sirqRxFull
3370
        move.w  d0,SerTailRcv                           ; update tail pointer
3371
        subi.w  #1,d0                                                           ; backup
3372
        andi.w  #$FFF,d0
3373
        lea                     SerRcvBuf,a0                            ; a0 = buffer address
3374
        move.b  d1,(a0,d0.w)                            ; store recieved byte in buffer
3375
        tst.b           SerRcvXoff                                      ; check if xoff already sent
3376
        bne                     sirqNxtByte
3377
        bsr                     SerialRcvCount                  ; if more than 4080 chars in buffer
3378
        cmpi.w  #4080,d0
3379
        blo                     sirqNxtByte
3380
        move.b  #XOFF,d1                                                ; send an XOFF
3381
        clr.b           SerRcvXon                                               ; clear XON status
3382
        move.b  d1,SerRcvXoff                           ; set XOFF status
3383
        bsr                     SerialPutChar                           ; send XOFF
3384
        bra                     sirqNxtByte                     ; check the status for another byte
3385
sirqRxFull:
3386
notRxInt:
3387
        movec           coreno,d0
3388
        swap            d0
3389
        moveq           #SERIAL_SEMA,d1
3390
        bsr                     UnlockSemaphore
3391
        movem.l (a7)+,d0/d1/d2/a0
3392
        rte
3393
 
3394
nmeSerial:
3395
        dc.b            "Serial",0
3396
 
3397
 
3398
;------------------------------------------------------------------------------
3399
;------------------------------------------------------------------------------
3400
        even
3401
 
3402
bus_err:
3403
.0001:
3404
        nop
3405
        bra                     .0001
3406
 
3407
trap3:
3408
        ; First save all registers
3409
        movem.l         d0/d1/d2/d3/d4/d5/d6/d7/a0/a1/a2/a3/a4/a5/a6/a7,Regsave
3410
        move.w          (a7)+,Regsave+$40
3411
        move.l          (a7)+,Regsave+$44
3412
        move.l          #$40FFC,a7                      ; reset stack pointer
3413
        move.w          #$2500,sr                               ; enable interrupts
3414
        move.w          NumSetBreakpoints,d0
3415
        subi.w          #1,d0
3416
        lea                             Breakpoints,a0
3417
        move.l          Regsave+$44,d1
3418
.0001:
3419
        cmp.l                   (a0)+,d1
3420
        beq.s                   ProcessBreakpoint
3421
        dbra                    d0,.0001
3422
        bra                             Monitor                                 ; not a breakpoint
3423
ProcessBreakpoint:
3424
        bsr                             DisarmAllBreakpoints
3425
        bra                             cmdDumpRegs
3426
 
3427
;------------------------------------------------------------------------------
3428
; DisarmAllBreakpoints, used when entering the monitor.
3429
;------------------------------------------------------------------------------
3430
 
3431
DisarmAllBreakpoints:
3432
        movem.l d0/a0/a1/a2,-(a7)                       ; stack some regs
3433
        move.w  NumSetBreakpoints,d0    ; d0 = number of breakpoints that are set
3434
        cmpi.w  #numBreakpoints,d0              ; check for valid number
3435
        bhs.s           .0001
3436
        lea                     Breakpoints,a2                          ; a2 = pointer to breakpoint address table
3437
        lea                     BreakpointWords,a0              ; a0 = pointer to breakpoint instruction word table
3438
        bra.s           .0003                                                                   ; enter loop at bottom
3439
.0002:
3440
        move.l  (a2)+,a1                                                        ; a1 = address of breakpoint
3441
        move.w  (a0)+,(a1)                                              ; copy instruction word back to code
3442
.0003:
3443
        dbra            d0,.0002
3444
        movem.l (a7)+,d0/a0/a1/a2                       ; restore regs
3445
.0001:
3446
        rts
3447
 
3448
;------------------------------------------------------------------------------
3449
; ArmAllBreakpoints, used when entering the monitor.
3450
;------------------------------------------------------------------------------
3451
 
3452
ArmAllBreakpoints:
3453
        movem.l         d0/a0/a1/a2,-(a7)                       ; stack some regs
3454
        move.w          NumSetBreakpoints,d0    ; d0 = number of breakpoints
3455
        cmpi.w          #numBreakpoints,d0              ; is the number valid?
3456
        bhs.s                   .0001
3457
        lea                             Breakpoints,a2                          ; a2 = pointer to breakpoint address table
3458
        lea                             BreakpointWords,a0              ; a0 = pointer to instruction word table
3459
        bra.s                   .0003                                                                   ; enter loop at bottom
3460
.0002:
3461
        move.l          (a2)+,a1                                                        ; a1 = address of breakpoint
3462
        move.w          (a1),(a0)                                                       ; copy instruction word to table
3463
        move.w          #$4E43,(a0)+                                    ; set instruction = TRAP3
3464
.0003:
3465
        dbra                    d0,.0002
3466
        movem.l         (a7)+,d0/a0/a1/a2                       ; restore regs
3467
.0001:
3468
        rts
3469
 
3470
;------------------------------------------------------------------------------
3471
;------------------------------------------------------------------------------
3472
 
3473
ArmBreakpoint:
3474
        movem.l         d0/d1/d2/a0/a1/a2,-(a7)
3475
        move.w          NumSetBreakpoints,d0    ; d0 = number of breakpoints
3476
        cmpi.w          #numBreakpoints,d0              ; check if too many
3477
        bhs.s                   .0001
3478
        addi.w          #1,NumSetBreakpoints    ; increment number of breakpoints
3479
        move.l          d0,d2
3480
        bsr                             ignBlanks
3481
        bsr                             GetHexNumber
3482
        beq.s                   .0001                                                                   ; was there an address?
3483
        btst                    #0,d1                                                                   ; address value must be even
3484
        bne.s                   .0001
3485
        ; See if the breakpoint is in the table already
3486
        lea                             Breakpoints,a1                          ; a1 points to breakpoint table
3487
        move.w          #numBreakpoints-1,d2
3488
.0002:
3489
        cmp.l                   (a1)+,d1
3490
        beq.s                   .0003                                                                   ; breakpoint is in table already
3491
        dbra                    d2,.0002
3492
        ; Add breakpoint to table
3493
        ; Search for empty entry
3494
        lea                             Breakpoints,a1                          ; a1 = pointer to breakpoint address table
3495
        clr.w                   d2                                                                              ; d2 = count
3496
.0006:
3497
        tst.l                   (a1)                                                                    ; is the entry empty?
3498
        beq.s                   .0005                                                                   ; branch if found empty entry
3499
        lea                             4(a1),a1                                                        ; point to next entry
3500
        addi.w          #1,d2                                                                   ; increment count
3501
        cmpi.w          #numBreakpoints,d2              ; safety: check against max number
3502
        blo.s                   .0006
3503
        bra.s                   .0001                                                                   ; what? no empty entries found, table corrupt?
3504
.0005:
3505
        asl.w                   #2,d2                                                                   ; d2 = long word index
3506
        move.l          d1,(a1,d2.w)                                    ; move breakpoint address to table
3507
        move.l          d1,a2
3508
        lsr.w                   #1,d2                                                                   ; d2 = word index
3509
.0004:
3510
        lea                             BreakpointWords,a1
3511
        move.w          (a2),(a1,d2.w)                          ; copy instruction word to table
3512
        move.w          #$4E43,(a2)                                             ; replace word with TRAP3
3513
.0001:
3514
        movem.l         (a7)+,d0/d1/d2/a0/a1/a2
3515
        rts
3516
.0003:
3517
        move.l          -4(a1),a2                                                       ; a2 = pointer to breakpoint address from table
3518
        cmpi.w          #$4E43,(a2)                                             ; see if breakpoint already armed
3519
        beq.s                   .0001
3520
        asl.l                   #1,d2                                                                   ; d2 = word index
3521
        bra.s                   .0004
3522
 
3523
 
3524
;------------------------------------------------------------------------------
3525
;------------------------------------------------------------------------------
3526
 
3527
DisarmBreakpoint:
3528
        movem.l         d0/d1/d2/a0/a1/a2,-(a7)
3529
        move.w          NumSetBreakpoints,d0    ; d0 = number of breakpoints
3530
        cmpi.w          #numBreakpoints,d0              ; check if too many
3531
        bhi.s                   .0001
3532
        move.l          d0,d2
3533
        bsr                             ignBlanks
3534
        bsr                             GetHexNumber
3535
        beq.s                   .0001                                                                   ; was there an address?
3536
        btst                    #0,d1                                                                   ; address value must be even
3537
        bne.s                   .0001
3538
        ; See if the breakpoint is in the table already
3539
        lea                             Breakpoints,a1                          ; a1 points to breakpoint table
3540
        subi.w          #1,d2
3541
.0002:
3542
        cmp.l                   (a1)+,d1
3543
        beq.s                   .0003                                                                   ; breakpoint is in table already
3544
        dbra                    d2,.0002
3545
        bra                             .0001                                                                   ; breakpoint was not in table
3546
.0003:
3547
        ; Remove breakpoint from table
3548
        subi.w          #1,NumSetBreakpoints    ; decrement number of breakpoints
3549
        move.l          -4(a1),a2                                                       ; a2 = pointer to breakpoint address from table
3550
        clr.l                   -4(a1)                                                          ; empty out breakpoint
3551
        lea                             BreakpointWords,a1
3552
        asl.l                   #1,d2                                                                   ; d2 = word index
3553
        move.w          (a1,d2.w),(a2)                          ; copy instruction from table back to code
3554
.0001:
3555
        movem.l         (a7)+,d0/d1/d2/a0/a1/a2
3556
        rts
3557
 
3558
;------------------------------------------------------------------------------
3559
;------------------------------------------------------------------------------
3560
 
3561
ListBreakpoints:
3562
        bsr                     CRLF
3563
        move.w  #numBreakpoints,d2
3564
        lea                     Breakpoints,a1
3565
.0001:
3566
        move.l  (a1)+,d1
3567
        bsr                     DisplayTetra
3568
        bsr                     CRLF
3569
        dbra            d2,.0001
3570
        bra                     Monitor
3571
 
3572
;------------------------------------------------------------------------------
3573
;------------------------------------------------------------------------------
3574
 
3575
ClearBreakpointList:
3576
        move.w  #numBreakpoints,d2
3577
        lea                     Breakpoints,a1
3578
.0001:
3579
        clr.l           (a1)+
3580
        dbra            d2,.0001
3581
        rts
3582
 
3583
;------------------------------------------------------------------------------
3584
; SendMsg
3585
; 00100xy0
3586
;
3587
; Parameters:
3588
;               d1 = target core number
3589
;               d2 = argument 1
3590
;               d3 = argument 2
3591
;               d4 = argument 3
3592
;
3593
;------------------------------------------------------------------------------
3594
 
3595
SendMsg:
3596
        movem.l d5/a1,-(a7)
3597
        lsl.w           #8,d1
3598
        movec           coreno,d5
3599
        lsl.w           #4,d5
3600
        or.w            d5,d1
3601
        lea                     $00100000,a1
3602
        tst.l           0(a1,d1.w)
3603
        bne                     .msgFull
3604
        movec           coreno,d5
3605
        move.l  d5,0(a1,d1.w)
3606
        move.l  d2,4(a1,d1.w)
3607
        move.l  d3,8(a1,d1.w)
3608
        move.l  d4,12(a1,d1.w)
3609
        movem.l (a7)+,d5/a1
3610
        moveq           #0,d1
3611
        rts
3612
.msgFull:
3613
        movem.l (a7)+,d5/a1
3614
        moveq           #-1,d1
3615
        rts
3616
 
3617
;------------------------------------------------------------------------------
3618
; ReceiveMsg
3619
;               Scan the message table for messages and dispatch them.
3620
; 00100xy0
3621
;
3622
; Parameters:
3623
;------------------------------------------------------------------------------
3624
 
3625
ReceiveMsg:
3626
        movem.l         d1/d2/d3/d4/d5/d6/d7/a1,-(a7)
3627
        lea                             $00100000,a1
3628
        movec                   coreno,d5
3629
        lsl.w                   #8,d5
3630
        moveq                   #2,d6
3631
.nextCore:
3632
        move.w          d6,d7
3633
        lsl.w                   #4,d7
3634
        add.w                   d5,d7
3635
        tst.l                   0(a1,d7.w)                      ; Is there a message from core d6?
3636
        beq                             .noMsg
3637
        move.l          0(a1,d7.w),d1
3638
        move.l          4(a1,d7.w),d2
3639
        move.l          8(a1,d7.w),d3
3640
        move.l          12(a1,d7.w),d4
3641
        clr.l                   0(a1,d7.w)                      ; indicate message was received
3642
        bsr                             DispatchMsg
3643
.noMsg:
3644
        addq                    #1,d6
3645
        cmp.w                   #9,d6
3646
        bls                             .nextCore
3647
        movem.l         (a7)+,d1/d2/d3/d4/d5/d6/d7/a1
3648
        rts
3649
 
3650
;------------------------------------------------------------------------------
3651
;------------------------------------------------------------------------------
3652
 
3653
DispatchMsg:
3654
        rts
3655
 
3656
 
3657
;------------------------------------------------------------------------------
3658
;------------------------------------------------------------------------------
3659
 
3660
InitIRQ:
3661
        moveq           #6,d0
3662
        lea                     KeybdIRQ,a0
3663
        bsr                     InstallIRQ
3664
        lea                     TickIRQ,a0
3665
        bsr                     InstallIRQ
3666
        moveq           #3,d0
3667
        lea                     SerialIRQ,a0
3668
        ; fall through
3669
 
3670
;------------------------------------------------------------------------------
3671
; Install an IRQ handler.
3672
;
3673
; Parameters:
3674
;               d0 = IRQ level
3675
;               a0 = pointer to IRQ routine
3676
; Returns:
3677
;               d1 = -1 if successfully added, 0 otherwise
3678
;               nf = 1, zf = 0 if successfully added, otherwise nf = 0, zf = 1
3679
;------------------------------------------------------------------------------
3680
 
3681
InstallIRQ:
3682
        move.l  d0,-(a7)                                        ; save working register
3683
        lea                     InstalledIRQ,a1         ; a1 points to installed IRQ list
3684
        lsl.w           #5,d0                                                   ; multiply by 8 long words per IRQ level
3685
.nextSpot:
3686
        cmpa.l  (a1,d0.w),a0                    ; Is the IRQ already installed?
3687
        beq.s           .found
3688
        tst.l           (a1,d0.w)                                       ; test for an empty spot
3689
        beq.s           .foundSpot
3690
        addi.w  #4,d0                                                   ; increment to next slot
3691
        move.w  d0,d1
3692
        andi.w  #$1F,d1                                         ; check to see if spots exhausted
3693
        beq.s           .noEmpties
3694
        bra.s           .nextSpot
3695
.foundSpot:
3696
        move.l  a0,(a1,d0.w)                    ; add IRQ routine to table
3697
.found:
3698
        move.l  (a7)+,d0
3699
        moveq           #-1,d1                                          ; return success
3700
        rts
3701
.noEmpties:
3702
        move.l  (a7)+,d0
3703
        moveq           #0,d1                                                   ; return failed to add
3704
        rts
3705
 
3706
 
3707
;------------------------------------------------------------------------------
3708
;------------------------------------------------------------------------------
3709
 
3710
TickIRQ:
3711
        move.w  #$2600,sr                                       ; disable lower level IRQs
3712
        movem.l d1/d2/a0,-(a7)
3713
        ; ToDo: detect a tick interrupt
3714
;       move.l  PLIC+$00,d1
3715
;       rol.l           #8,d1
3716
;       cmpi.b  #29,d1
3717
;       bne.s           .notTick
3718
        movec           coreno,d1                                       ; d1 = core number
3719
        cmpi.b  #2,d1
3720
        bne.s           .0001
3721
        move.l  #$1D000000,PLIC+$14     ; reset edge sense circuit
3722
.0001:
3723
        move.l  TextScr,a0                              ; a0 = screen address
3724
        move.l  (a0),d2
3725
        rol.w           #8,d2                                                   ; reverse byte order of d2
3726
        swap            d2
3727
        rol.w           #8,d2
3728
        addi.b  #'0',d1                                         ; binary to ascii core number
3729
        add.b           d2,d1
3730
        rol.w           #8,d1                                                   ; put bytes back in order
3731
        swap            d1
3732
        rol.w           #8,d1
3733
        move.l  d1,4(a0)                                        ; update onscreen IRQ flag
3734
        addi.l  #1,(a0)                                         ; flashy colors
3735
; addi.l        #1,40(a0)                                       ; nice effect
3736
        bsr                     ReceiveMsg
3737
        movem.l (a7)+,d1/d2/a0
3738
        rte
3739
;.notTick:
3740
;       movem.l (a7)+,d1/a0
3741
;       rte
3742
;------------------------------------------------------------------------------
3743
;------------------------------------------------------------------------------
3744
 
3745
irq3_rout:
3746
        movem.l d0/d1/a0/a1,-(a7)
3747
        lea                     InstalledIRQ+8*4*3,a0
3748
        bra                     irq_rout
3749
 
3750
irq6_rout:
3751
        movem.l d0/d1/a0/a1,-(a7)
3752
        lea                     InstalledIRQ+8*4*6,a0
3753
irq_rout:
3754
        moveq           #7,d0
3755
.nextHandler:
3756
        move.l  (a0)+,a1
3757
        beq.s           .0003
3758
        jsr                     (a1)
3759
        tst.l           d1                                                              ; was IRQ handled?
3760
        bmi.s           .0002                                                   ; first one to return handled quits loop
3761
.0003:
3762
        dbra            d0,.nextHandler
3763
.0002:
3764
        movem.l (a7)+,d0/d1/a0/a1       ; return
3765
 
3766
SpuriousIRQ:
3767
        rte
3768
 
3769
;       bsr                     KeybdIRQ
3770
;       tst.l           d1                                                              ; handled by KeybdIRQ?
3771
;       bmi.s           .0002                                                   ; if yes, go return
3772
;.0001:
3773
;       move.l  #$1D000000,PLIC+$14     ; reset edge sense circuit
3774
;       move.l  TextScr,a0                              ; a0 = screen address
3775
;       addi.l  #1,40(a0)                                       ; update onscreen IRQ flag
3776
;.0002:
3777
;       movem.l (a7)+,d0/d1/a0/a1       ; return
3778
;       rte
3779
 
3780
nmi_rout:
3781
        movem.l d0/d1/a0,-(a7)
3782
        move.b  #'N',d1
3783
        bsr                     DisplayChar
3784
        movem.l (a7)+,d0/d1/a0          ; return
3785
        rte
3786
 
3787
brdisp_trap:
3788
        movem.l d0/d1/d2/d3/d4/d5/d6/d7/a0/a1/a2/a3/a4/a5/a6/a7,Regsave
3789
        move.w  (a7)+,Regsave+$40
3790
        move.l  (a7)+,Regsave+$44
3791
        move.l  #$40FFC,a7                      ; reset stack pointer
3792
        move.w  #$2500,sr                               ; enable interrupts
3793
        lea                     msg_bad_branch_disp,a1
3794
        bsr                     DisplayString
3795
        bsr                     DisplaySpace
3796
        move.l  Regsave+$44,d1  ; exception address
3797
        bsr                     DisplayTetra            ; and display it
3798
;       move.l  (sp)+,d1                                ; pop format word 68010 mode only
3799
        bra                     cmdDumpRegs
3800
 
3801
illegal_trap:
3802
        addq            #2,sp                                           ; get rid of sr
3803
        move.l  (sp)+,d1                                ; pop exception address
3804
        bsr                     DisplayTetra            ; and display it
3805
        lea                     msg_illegal,a1  ; followed by message
3806
        bsr                     DisplayString
3807
.0001:
3808
        bra                     .0001
3809
        bra                     Monitor
3810
 
3811
io_irq:
3812
        addq #2,sp
3813
        move.l (sp)+,d1
3814
        bsr DisplayTetra
3815
        lea msg_io_access,a1
3816
        bsr DisplayString
3817
        bra cmdDumpRegs
3818
 
3819
; -----------------------------------------------------------------------------
3820
; -----------------------------------------------------------------------------
3821
 
3822
msg_start:
3823
        dc.b    "Femtiki rf68k Multi-core OS Starting",LF,CR,0
3824
;       dc.b    "rf68k System Starting",CR,LF,0
3825
msg_core_start:
3826
        dc.b    " core starting",CR,LF,0
3827
msg_illegal:
3828
        dc.b    " illegal opcode",CR,LF,0
3829
msg_bad_branch_disp:
3830
        dc.b    " branch selfref: ",0
3831
msg_test_done:
3832
        dc.b    " CPU test done.",0
3833
msg_io_access
3834
        dc.b " unpermitted access to I/O",0
3835
 
3836
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.