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

Subversion Repositories rf68000

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

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

powered by: WebSVN 2.1.0

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