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

Subversion Repositories rtf65002

[/] [rtf65002/] [trunk/] [software/] [asm/] [bootrom.asm] - Blame information for rev 39

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 34 robfinch
 
2 11 robfinch
; ============================================================================
3
;        __
4 39 robfinch
;   \\__/ o\    (C) 2013, 2014  Robert Finch, Stratford
5 11 robfinch
;    \  __ /    All rights reserved.
6
;     \/_//     robfinch@opencores.org
7
;       ||
8
;
9
;
10
; This source file is free software: you can redistribute it and/or modify
11
; it under the terms of the GNU Lesser General Public License as published
12
; by the Free Software Foundation, either version 3 of the License, or
13
; (at your option) any later version.
14
;
15
; This source file is distributed in the hope that it will be useful,
16
; but WITHOUT ANY WARRANTY; without even the implied warranty of
17
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
; GNU General Public License for more details.
19
;
20
; You should have received a copy of the GNU General Public License
21
; along with this program.  If not, see .
22
;
23
; ============================================================================
24
;
25 39 robfinch
        cpu             RTF65002
26
 
27 11 robfinch
CR      EQU     0x0D            ;ASCII equates
28
LF      EQU     0x0A
29
TAB     EQU     0x09
30
CTRLC   EQU     0x03
31 39 robfinch
BELL    EQU     0x07
32 11 robfinch
CTRLH   EQU     0x08
33
CTRLI   EQU     0x09
34
CTRLJ   EQU     0x0A
35
CTRLK   EQU     0x0B
36
CTRLM   EQU 0x0D
37
CTRLS   EQU     0x13
38
CTRLX   EQU     0x18
39 39 robfinch
ESC             EQU     0x1b
40 11 robfinch
XON             EQU     0x11
41
XOFF    EQU     0x13
42
 
43 26 robfinch
; error codes
44
E_Ok            =               0x00
45
E_Arg           =               0x01
46
E_BadMbx        =               0x04
47
E_QueFull       =               0x05
48
E_NoThread      =               0x06
49
E_NotAlloc      =               0x09
50
E_NoMsg         =               0x0b
51
E_Timeout       =               0x10
52
E_BadAlarm      =               0x11
53
E_NotOwner      =               0x12
54 39 robfinch
E_QueStrategy =         0x13
55
E_BadDevNum     =               0x18
56
E_DCBInUse      =               0x19
57
; Device driver errors
58
E_BadDevNum     =               0x20
59
E_NoDev         =               0x21
60
E_BadDevOp      =               0x22
61
E_ReadError     =               0x23
62
E_WriteError =          0x24
63
E_BadBlockNum   =       0x25
64
E_TooManyBlocks =       0x26
65
 
66 26 robfinch
; resource errors
67
E_NoMoreMbx     =               0x40
68
E_NoMoreMsgBlks =       0x41
69
E_NoMoreAlarmBlks       =0x44
70
E_NoMoreTCBs    =       0x45
71 39 robfinch
E_NoMem         = 12
72 26 robfinch
 
73
; task status
74
TS_NONE     =0
75
TS_TIMEOUT      =1
76
TS_WAITMSG      =2
77 28 robfinch
TS_PREEMPT      =4
78 26 robfinch
TS_RUNNING      =8
79
TS_READY        =16
80 31 robfinch
TS_SLEEP        =32
81 26 robfinch
 
82 39 robfinch
TS_TIMEOUT_BIT  =0
83
TS_WAITMSG_BIT  =1
84
TS_RUNNING_BIT  =3
85
TS_READY_BIT    =4
86 26 robfinch
 
87 39 robfinch
PRI_HIGHEST     =0
88
PRI_HIGH        =1
89
PRI_NORMAL      =2
90
PRI_LOW         =3
91
PRI_LOWEST      =4
92
 
93
MAX_TASKNO      = 63
94
DRAM_BASE       = $04000000
95
 
96 31 robfinch
DIRENT_NAME             =0x00   ; file name
97
DIRENT_EXT              =0x1C   ; file name extension
98
DIRENT_ATTR             =0x20   ; attributes
99
DIRENT_DATETIME =0x28
100
DIRENT_CLUSTER  =0x30   ; starting cluster of file
101
DIRENT_SIZE             =0x34   ; file size (6 bytes)
102
 
103
; One FCB is allocated and filled out for each file that is open.
104
;
105
nFCBs   = 128
106
FCB_DE_NAME             =0x00
107
FCB_DE_EXT              =0x1C
108
FCB_DE_ATTR             =0x20
109
FCB_DE_DATETIME =0x28
110
FCB_DE_CLUSTER  =0x30   ; starting cluster of file
111
FCB_DE_SIZE             =0x34   ; 6 byte file size
112 34 robfinch
 
113 31 robfinch
FCB_DIR_SECTOR  =0x40   ; LBA directory sector this is from
114
FCB_DIR_ENT             =0x44   ; offset in sector for dir entry
115
FCB_LDRV                =0x48   ; logical drive this is on
116
FCB_MODE                =0x49   ; 0 read, 1=modify
117
FCB_NUSERS              =0x4A   ; number of users of this file
118
FCB_FMOD                =0x4B   ; flag: this file was modified
119
FCB_RESV                =0x4C   ; padding out to 80 bytes
120
FCB_SIZE                =0x50
121
 
122
FUB_JOB         =0x00   ; User's job umber
123
FUB_iFCB        =0x02   ; FCB number for this file
124
FUB_CrntLFA     =0x04   ; six byte current logical file address
125
FUB_pBuf        =0x0C   ; pointer to buffer if in stream mode
126
FUB_sBuf        =0x10   ; size of buffer for stream file
127
FUB_LFABuf      =0x14   ; S-First LFA in Clstr Buffer
128
FUB_LFACluster  =0x18   ; LFA of cluster
129
FUB_Clstr       = 0x20          ; The last cluster read
130
FUB_fModified   = 0x24  ; data in buffer was modified
131
FUB_fStream             = 0x25  ; non-zero for stream mode
132
FUB_PAD         =0x26
133
FUB_SIZE        =0x30
134
 
135
; Boot sector info (62 byte structure) */
136
BSI_JMP         = 0x00
137
BSI_OEMName     = 0x03
138
BSI_bps         = 0x0B
139
BSI_SecPerCluster       = 0x0D
140
BSI_ResSectors  = 0x0E
141
BSI_FATS        = 0x10
142
BSI_RootDirEnts = 0x11
143
BSI_Sectors     = 0x13
144
BSI_Media       = 0x15
145
BSI_SecPerFAT   = 0x16
146
BSI_SecPerTrack = 0x18
147
BSI_Heads       = 0x1A
148
BSI_HiddenSecs  = 0x1C
149
BSI_HugeSecs    = 0x1E
150
 
151
BSI_DriveNum    = 0x24
152
BSI_Rsvd1               = 0x25
153
BSI_BootSig             = 0x26
154
BSI_VolID               = 0x27
155
BSI_VolLabel    = 0x2B
156
BSI_FileSysType = 0x36
157
 
158
 
159
MEM_CHK         =0
160
MEM_FLAG        =1
161
MEM_PREV        =2
162
MEM_NEXT        =3
163
 
164 26 robfinch
; message queuing strategy
165
MQS_UNLIMITED   =0      ; unlimited queue size
166
MQS_NEWEST              =1      ; buffer queue size newest messages
167
MQS_OLDEST              =2      ; buffer queue size oldest messages
168
 
169 31 robfinch
LEDS            EQU             0xFFDC0600
170 11 robfinch
TEXTSCR         EQU             0xFFD00000
171
COLORSCR        EQU             0xFFD10000
172
TEXTREG         EQU             0xFFDA0000
173
TEXT_COLS       EQU             0x0
174
TEXT_ROWS       EQU             0x1
175
TEXT_CURPOS     EQU             11
176 39 robfinch
TEXT_CURCTL     EQU             8
177
BMP_CLUT        EQU             $FFDC5800
178 11 robfinch
KEYBD           EQU             0xFFDC0000
179
KEYBDCLR        EQU             0xFFDC0001
180 15 robfinch
PIC                     EQU             0xFFDC0FF0
181
PIC_IE          EQU             0xFFDC0FF1
182 31 robfinch
PIC_ES          EQU             0xFFDC0FF4
183
PIC_RSTE        EQU             0xFFDC0FF5
184 26 robfinch
TASK_SELECT     EQU             0xFFDD0008
185 39 robfinch
 
186 26 robfinch
RQ_SEMA         EQU             0xFFDB0000
187 39 robfinch
to_sema         EQU             0xFFDB0010
188 26 robfinch
SERIAL_SEMA     EQU             0xFFDB0020
189 39 robfinch
keybd_sema      EQU             0xFFDB0030
190
iof_sema        EQU             0xFFDB0040
191
mbx_sema        EQU             0xFFDB0050
192
freembx_sema    EQU             0xFFDB0060
193
mem_sema        EQU             0xFFDB0070
194
freemsg_sema    EQU     0xFFDB0080
195
tcb_sema        EQU             0xFFDB0090
196
readylist_sema  EQU     0xFFDB00A0
197
tolist_sema             EQU     0xFFDB00B0
198
msg_sema                EQU     0xFFDB00C0
199
freetcb_sema    EQU     0xFFDB00D0
200
freejcb_sema    EQU     0xFFDB00E0
201
jcb_sema                EQU     0xFFDB00F0
202
device_semas    EQU     0xFFDB1000
203
device_semas_end        EQU     0xFFDB1200
204 11 robfinch
 
205
SPIMASTER       EQU             0xFFDC0500
206
SPI_MASTER_VERSION_REG  EQU     0x00
207
SPI_MASTER_CONTROL_REG  EQU     0x01
208
SPI_TRANS_TYPE_REG      EQU             0x02
209
SPI_TRANS_CTRL_REG      EQU             0x03
210
SPI_TRANS_STATUS_REG    EQU     0x04
211
SPI_TRANS_ERROR_REG             EQU     0x05
212
SPI_DIRECT_ACCESS_DATA_REG              EQU     0x06
213
SPI_SD_SECT_7_0_REG             EQU     0x07
214
SPI_SD_SECT_15_8_REG    EQU     0x08
215
SPI_SD_SECT_23_16_REG   EQU     0x09
216
SPI_SD_SECT_31_24_REG   EQU     0x0a
217
SPI_RX_FIFO_DATA_REG    EQU     0x10
218
SPI_RX_FIFO_DATA_COUNT_MSB      EQU     0x12
219
SPI_RX_FIFO_DATA_COUNT_LSB  EQU 0x13
220
SPI_RX_FIFO_CTRL_REG            EQU     0x14
221
SPI_TX_FIFO_DATA_REG    EQU     0x20
222
SPI_TX_FIFO_CTRL_REG    EQU     0x24
223
SPI_RESP_BYTE1                  EQU     0x30
224
SPI_RESP_BYTE2                  EQU     0x31
225
SPI_RESP_BYTE3                  EQU     0x32
226
SPI_RESP_BYTE4                  EQU     0x33
227
SPI_INIT_SD                     EQU             0x01
228
SPI_TRANS_START         EQU             0x01
229
SPI_TRANS_BUSY          EQU             0x01
230
SPI_INIT_NO_ERROR       EQU             0x00
231
SPI_READ_NO_ERROR       EQU             0x00
232 15 robfinch
SPI_WRITE_NO_ERROR      EQU             0x00
233 11 robfinch
RW_READ_SD_BLOCK        EQU             0x02
234
RW_WRITE_SD_BLOCK       EQU             0x03
235
 
236 26 robfinch
CONFIGREC       EQU             0xFFDCFFF0
237
CR_CLOCK        EQU             0xFFDCFFF4
238
GACCEL          EQU             0xFFDAE000
239 34 robfinch
GA_X0           EQU             0xFFDAE002
240
GA_Y0           EQU             0xFFDAE003
241
GA_PEN          EQU             0xFFDAE000
242
GA_X1           EQU             0xFFDAE004
243
GA_Y1           EQU             0xFFDAE005
244
GA_STATE        EQU             0xFFDAE00E
245
GA_CMD          EQU             0xFFDAE00F
246
 
247 28 robfinch
AC97            EQU             0xFFDC1000
248
PSG                     EQU             0xFFD50000
249
PSGFREQ0        EQU             0xFFD50000
250
PSGPW0          EQU             0xFFD50001
251
PSGCTRL0        EQU             0xFFD50002
252
PSGADSR0        EQU             0xFFD50003
253 26 robfinch
 
254
ETHMAC          EQU             0xFFDC2000
255
ETH_MODER               EQU             0x00
256
ETH_INT_SOURCE  EQU             0x01
257
ETH_INT_MASK    EQU             0x02
258
ETH_IPGT                EQU             0x03
259
ETH_IPGR1               EQU             0x04
260
ETH_IPGR2               EQU             0x05
261
ETH_PACKETLEN   EQU             0x06
262
ETH_COLLCONF    EQU             0x07
263
ETH_TX_BD_NUM   EQU             0x08
264
ETH_CTRLMODER   EQU             0x09
265
ETH_MIIMODER    EQU             0x0A
266
ETH_MIICOMMAND  EQU             0x0B
267
ETH_MIIADDRESS  EQU             0x0C
268
ETH_MIITX_DATA  EQU             0x0D
269
ETH_MIIRX_DATA  EQU             0x0E
270
ETH_MIISTATUS   EQU             0x0F
271
ETH_MAC_ADDR0   EQU             0x10
272
ETH_MAC_ADDR1   EQU             0x11
273
ETH_HASH0_ADDR  EQU             0x12
274
ETH_HASH1_ADDR  EQU             0x13
275
ETH_TXCTRL              EQU             0x14
276
 
277 34 robfinch
ETH_WCTRLDATA   EQU             4
278
ETH_MIICOMMAND_RSTAT    EQU     2
279
ETH_MIISTATUS_BUSY      EQU             2
280
ETH_MIIMODER_RST        EQU             $200
281
ETH_MODER_RST       EQU         $800
282
ETH_MII_BMCR            EQU             0                ; basic mode control register
283
ETH_MII_ADVERTISE       EQU             4
284
ETH_MII_EXPANSION       =6
285
ETH_MII_CTRL1000        =9
286
ETH_ADVERTISE_ALL       EQU             $1E0
287
ETH_ADVERTISE_1000FULL      =0x0200  ; Advertise 1000BASE-T full duplex
288
ETH_ADVERTISE_1000HALF      =0x0100  ; Advertise 1000BASE-T half duplex
289
ETH_ESTATUS_1000_TFULL  =0x2000 ; Can do 1000BT Full
290
ETH_ESTATUS_1000_THALF  =0x1000 ; Can do 1000BT Half
291
ETH_BMCR_ANRESTART      =    0x0200  ; Auto negotiation restart
292
ETH_BMCR_ISOLATE        =    0x0400  ; Disconnect DP83840 from MII
293
ETH_BMCR_PDOWN          =    0x0800  ; Powerdown the DP83840
294
ETH_BMCR_ANENABLE       =    0x1000  ; Enable auto negotiation
295
 
296
ETH_PHY         =7
297
 
298
MMU                     EQU             0xFFDC4000
299
MMU_KVMMU       EQU             0xFFDC4800
300
MMU_FUSE        EQU             0xFFDC4811
301
MMU_AKEY        EQU             0xFFDC4812
302
MMU_OKEY        EQU             0xFFDC4813
303
MMU_MAPEN       EQU             0xFFDC4814
304
 
305
DATETIME        EQU             0xFFDC0400
306
DATETIME_TIME           EQU             0xFFDC0400
307
DATETIME_DATE           EQU             0xFFDC0401
308
DATETIME_ALMTIME        EQU             0xFFDC0402
309
DATETIME_ALMDATE        EQU             0xFFDC0403
310
DATETIME_CTRL           EQU             0xFFDC0404
311
DATETIME_SNAPSHOT       EQU             0xFFDC0405
312
 
313 26 robfinch
SPRITEREGS      EQU             0xFFDAD000
314
SPRRAM          EQU             0xFFD80000
315
 
316 39 robfinch
THRD_AREA       EQU             0x00000000      ; threading area 0x04000000-0x40FFFFF
317
BITMAPSCR       EQU             0x00100000
318
SECTOR_BUF      EQU             0x01FBEC00
319 26 robfinch
 
320 15 robfinch
BYTE_SECTOR_BUF EQU     SECTOR_BUF<<2
321 39 robfinch
PROG_LOAD_AREA  EQU             0x0300000<<2
322 11 robfinch
 
323 39 robfinch
FCBs                    EQU             0x1F40000       ; room for 128 FCB's
324 28 robfinch
 
325 39 robfinch
FATOFFS                 EQU             0x1F50000       ; offset into FAT on card
326
FATBUF                  EQU             0x1F60000
327
DIRBUF                  EQU             0x1F70000
328
eth_rx_buffer   EQU             0x1F80000
329
eth_tx_buffer   EQU             0x1F84000
330 11 robfinch
 
331 26 robfinch
; Mailboxes, room for 2048
332 39 robfinch
                        .bss
333
                        .org            0x01F90000
334
NR_MBX          EQU             $800
335
MBX_LINK                fill.w  NR_MBX,0        ; link to next mailbox in list (free list)
336
MBX_TQ_HEAD             fill.w  NR_MBX,0        ; head of task queue
337
MBX_TQ_TAIL             fill.w  NR_MBX,0
338
MBX_MQ_HEAD             fill.w  NR_MBX,0        ; head of message queue
339
MBX_MQ_TAIL             fill.w  NR_MBX,0
340
MBX_TQ_COUNT    fill.w  NR_MBX,0        ; count of queued threads
341
MBX_MQ_SIZE             fill.w  NR_MBX,0        ; number of messages that may be queued
342
MBX_MQ_COUNT    fill.w  NR_MBX,0        ; count of messages that are queued
343
MBX_MQ_MISSED   fill.w  NR_MBX,0        ; number of messages dropped from queue
344
MBX_OWNER               fill.w  NR_MBX,0        ; job handle of mailbox owner
345
MBX_MQ_STRATEGY fill.w  NR_MBX,0        ; message queueing strategy
346
MBX_RESV                fill.w  NR_MBX,0
347 11 robfinch
 
348 39 robfinch
; Messages, room for 64kW (16,384) messages
349
                        .bss
350
                        .org            0x01FA0000
351
NR_MSG          EQU             16384
352
MSG_LINK        fill.w  NR_MSG,0        ; link to next message in queue or free list
353
MSG_D1          fill.w  NR_MSG,0        ; message data 1
354
MSG_D2          fill.w  NR_MSG,0        ; message data 2
355
MSG_TYPE        fill.w  NR_MSG,0        ; message type
356
MSG_END         EQU             MSG_TYPE + NR_MSG
357 26 robfinch
 
358 39 robfinch
MT_SEMA         EQU             0xFFFFFFFF
359
MT_IRQ          EQU             0xFFFFFFF0
360
MT_GETCHAR      EQU             0xFFFFFFEF
361
 
362
NR_JCB                  EQU             32
363
JCB_Number              EQU             0
364
JCB_Name                EQU             1               ; 32 bytes (1 len + 31)
365
JCB_Map                 EQU             9               ; memory map number associated with job
366
JCB_pCode               EQU             10
367
JCB_nCode               EQU             11              ; size of code
368
JCB_pData               EQU             12
369
JCB_nData               EQU             13              ; size of data
370
JCB_pStack              EQU             14
371
JCB_nStack              EQU             15
372
JCB_UserName    EQU             16              ; 32 bytes
373
JCB_Path                EQU             24              ; 80 bytes
374
JCB_ExitRF              EQU             44              ; 80 bytes
375
JCB_CmdLine             EQU             84              ; 240 bytes
376
JCB_SysIn               EQU             140             ; 40 chars
377
JCB_SysOut              EQU             150             ; 40 chars
378
JCB_ExitError   EQU             160
379
JCB_pVidMem             EQU             161             ; pointer to video memory
380
JCB_pVidMemAttr EQU             162
381
JCB_pVirtVid    EQU             163             ; pointer to virtual video buffer
382
JCB_pVirtVidAttr        EQU             164
383
JCB_VideoMode   EQU             165
384
JCB_VideoRows   EQU             166
385
JCB_VideoCols   EQU             167
386
JCB_CursorRow   EQU             168
387
JCB_CursorCol   EQU             169
388
JCB_CursorOn    EQU             170
389
JCB_CursorFlash EQU             171
390
JCB_CursorType  EQU             172
391
JCB_NormAttr    EQU             173
392
JCB_CurrAttr    EQU             174
393
JCB_ScrlCnt             EQU             175
394
JCB_fVidPause   EQU             176
395
JCB_Next                EQU             177
396
JCB_iof_next    EQU             178             ; I/O focus list
397
JCB_iof_prev    EQU             179
398
JCB_VMP_bitmap_b0       EQU             180             ; 512 bits      - virtual memory page bitmap
399
JCB_VMP_bitmap_b1       EQU             196             ; 512 bits      - virtual memory page bitmap
400
JCB_KeybdHead   EQU             212
401
JCB_KeybdTail   EQU             213
402
JCB_KeybdEcho   EQU             214
403
JCB_KeybdBad    EQU             215
404
JCB_KeybdAck    EQU             216
405
JCB_KeybdLocks  EQU             217
406
JCB_KeybdBuffer EQU             218             ; buffer is 16 words (chars = words)
407
JCB_esc                 EQU             234             ; escape flag for DisplayChar processing
408
JCB_Size                EQU             256
409
JCB_LogSize             EQU             8
410
 
411
                .bss
412
JCBs                    fill.w  NR_JCB * JCB_Size,0
413
FreeJCB         dw              0
414
 
415
                        .bss
416
                        .org            0x01FBA000
417
 
418 26 robfinch
; Task control blocks, room for 256 tasks
419 39 robfinch
NR_TCB                  EQU             256
420
TCB_NxtRdy              fill.w  NR_TCB,0        ;       EQU             0x01FBE100      ; next task on ready / timeout list
421
TCB_PrvRdy              fill.w  NR_TCB,0        ;       EQU             0x01FBE200      ; previous task on ready / timeout list
422
TCB_NxtTCB              fill.w  NR_TCB,0        ;       EQU             0x01FBE300
423
TCB_Timeout             fill.w  NR_TCB,0        ;       EQU             0x01FBE400
424
TCB_Priority    fill.w  NR_TCB,0        ;       EQU             0x01FBE500
425
TCB_MSG_D1              fill.w  NR_TCB,0        ;       EQU             0x01FBE600
426
TCB_MSG_D2              fill.w  NR_TCB,0        ;       EQU             0x01FBE700
427
TCB_hJCB                fill.w  NR_TCB,0        ;       EQU             0x01FBE800
428
TCB_Status              fill.w  NR_TCB,0        ;       EQU             0x01FBE900
429
TCB_CursorRow   fill.w  NR_TCB,0        ;       EQU             0x01FBD100
430
TCB_CursorCol   fill.w  NR_TCB,0        ;       EQU             0x01FBD200
431
TCB_hWaitMbx    fill.w  NR_TCB,0        ;       EQU             0x01FBD300      ; handle of mailbox task is waiting at
432
TCB_mbq_next    fill.w  NR_TCB,0        ;       EQU             0x01FBD400      ; mailbox queue next
433
TCB_mbq_prev    fill.w  NR_TCB,0        ;       EQU             0x01FBD500      ; mailbox queue previous
434
TCB_SP8Save             fill.w  NR_TCB,0        ;       EQU             0x01FBD800      ; TCB_SP8Save area
435
TCB_SPSave              fill.w  NR_TCB,0        ;       EQU             0x01FBD900      ; TCB_SPSave area
436
TCB_StackTop    fill.w  NR_TCB,0
437
TCB_ABS8Save    fill.w  NR_TCB,0        ;       EQU             0x01FBDA00
438
TCB_mmu_map             fill.w  NR_TCB,0        ;       EQU             0x01FBDB00
439
TCB_npages              fill.w  NR_TCB,0        ;       EQU             0x01FBDC00
440
TCB_ASID                fill.w  NR_TCB,0        ;       EQU             0x01FBDD00
441
TCB_errno               fill.w  NR_TCB,0        ;       EQU             0x01FBDE00
442
TCB_NxtTo               fill.w  NR_TCB,0        ;       EQU             0x01FBDF00
443
TCB_PrvTo               fill.w  NR_TCB,0        ;       EQU             0x01FBE000
444
TCB_MbxList             fill.w  NR_TCB,0        ;       EQU             0x01FBCF00      ; head pointer to list of mailboxes associated with task
445
TCB_mbx                 fill.w  NR_TCB,0        ;       EQU             0x01FBCE00
446
TCB_HeapStart   fill.w  NR_TCB,0        ;       Starting address of heap in task's memory space
447
TCB_HeapEnd             fill.w  NR_TCB,0        ;       Ending addres of heap in task's memory space
448 26 robfinch
 
449 39 robfinch
;include "jcb.inc"
450 26 robfinch
 
451 39 robfinch
NR_MMU_MAP              EQU             32
452
VPM_bitmap_b0   fill.w  NR_MMU_MAP * 16,0
453
VPM_bitmap_b1   fill.w  NR_MMU_MAP * 16,0
454
nPagesFree              dw              0
455 31 robfinch
 
456 39 robfinch
message "cachInvRout"
457
                        .bss
458
                        .align          4096
459
cacheInvRout:
460
                        fill.w          4096,0
461
cacheLineInvRout:
462
                        fill.w          4096,0
463
 
464
message "SCREEN_SIZE"
465
                        .bss
466
                        .org            0x01D00000
467
SCREEN_SIZE             EQU             8192
468
BIOS_SCREENS    fill.w  SCREEN_SIZE * NR_JCB    ; 0x01D00000 to 0x01EFFFFF
469
 
470 28 robfinch
; Bitmap of tasks requesting the I/O focus
471
;
472 39 robfinch
IOFocusTbl      fill.w  8,0
473 26 robfinch
 
474 39 robfinch
MAX_DEV_OP                      EQU             31
475
 
476
; Device Control Block
477
;
478
DCB_NAME                        EQU             0
479
DCB_NAME_LEN            EQU             3
480
DCB_TYPE                        EQU             4
481
DCB_nBPB                        EQU             5
482
DCB_last_erc            EQU             6
483
DCB_nBlocks                     EQU             7
484
DCB_pDevOp                      EQU             8
485
DCB_pDevInit            EQU             9
486
DCB_pDevStat            EQU             10
487
DCB_ReentCount          EQU             11
488
DCB_fSingleUser         EQU             12
489
DCB_hJob                        EQU             13
490
DCB_Mbx                         EQU             14
491
DCB_Sema                        EQU             15
492
DCB_OSD3                        EQU             16
493
DCB_OSD4                        EQU             17
494
DCB_OSD5                        EQU             18
495
DCB_OSD6                        EQU             19
496
DCB_SIZE                        EQU             20
497
 
498
;Standard Devices are:
499
 
500
;#              Device                                  Standard name
501
 
502
;0              NULL device                     NUL             (OS built-in)
503
;1              Keyboard (sequential)   KBD             (OS built-in)
504
;2              Video (sequential)              VID             (OS built-in)
505
;3              Printer (parallel 1)    LPT
506
;4              Printer (parallel 2)    LPT2
507
;5              RS-232 1                                COM1    (OS built-in)
508
;6              RS-232 2                                COM2
509
;7              RS-232 3                                COM3
510
;8              RS-232 4                                COM4
511
;9
512
;10             Floppy                                  FD0
513
;11             Floppy                                  FD1
514
;12             Hard disk                               HD0
515
;13             Hard disk                               HD1
516
;14
517
;15
518
;16             SDCard                                  CARD1   (OS built-in)
519
;17
520
;18
521
;19
522
;20
523
;21
524
;22
525
;23
526
;24
527
;25
528
;26
529
;27
530
;28             Audio                                   PSG1    (OS built-in)
531
;29
532
;30
533
;31
534
 
535
NR_DCB          EQU             32
536
DCBs            fill    NR_DCB * DCB_SIZE,0             ;       EQU             MSG_END
537
DCBs_END        EQU             DCBs + DCB_SIZE * NR_DCB
538
 
539
; preallocated stacks for TCBs
540
                        .bss
541
                        .org            0x01FC0000                              ; to 0x01FFFFFF
542
STACK_SIZE              EQU             $400                                    ; 1kW
543
BIOS_STACKS             fill.w  STACK_SIZE * NR_TCB             ; room for 256 1kW stacks
544
 
545
 
546
HeapStart       EQU             0x00540000
547
HeapEnd         EQU             BIOS_SCREENS-1
548
 
549 28 robfinch
; EhBASIC vars:
550 15 robfinch
;
551 26 robfinch
NmiBase         EQU             0xDC
552
IrqBase         EQU             0xDF
553
 
554 28 robfinch
; BIOS vars at the top of the 8kB scratch memory
555
;
556 39 robfinch
; TinyBasic AREA = 0x6C0 to 0x77F
557 26 robfinch
 
558 39 robfinch
PageMap         EQU             0x600
559
PageMapEnd      EQU             0x63F
560
PageMap2        EQU             0x640
561
PageMap2End     EQU             0x67F
562
mem_pages_free  EQU             0x680
563 26 robfinch
 
564 39 robfinch
                        bss
565
                        org     0x780
566
 
567
QNdx0           dw              0
568
QNdx1           dw              0
569
QNdx2           dw              0
570
QNdx3           dw              0
571
QNdx4           dw              0
572
FreeTCB         dw              0
573
TimeoutList     dw              0
574
RunningTCB      dw              0
575
FreeMbxHandle           dw              0
576
nMailbox        dw              0
577
FreeMsg         dw              0
578
nMsgBlk         dw              0
579
missed_ticks    dw              0
580
keybdmsg_d1             dw              0
581
keybdmsg_d2             dw              0
582
keybd_mbx               dw              0
583
keybd_char              dw              0
584
keybdIsSetup    dw              0
585
keybdLock               dw              0
586
keybdInIRQ              dw              0
587
iof_switch              dw              0
588
clockmsg_d1             dw              0
589
clockmsg_d2             dw              0
590
tcbsema_d1              dw              0
591
tcbsema_d2              dw              0
592
mmu_acc_save    dw              0
593
 
594 28 robfinch
; The IO focus list is a doubly linked list formed into a ring.
595
;
596 39 robfinch
IOFocusNdx      dw              0                ; really a pointer to the JCB owning the IO focus
597
;
598
test_mbx        dw              0
599
test_D1         dw              0
600
test_D2         dw              0
601
tone_cnt        dw              0
602 26 robfinch
 
603 39 robfinch
IrqSource       EQU             0x79F
604 15 robfinch
 
605 39 robfinch
                        .align  0x10
606
JMPTMP          dw              0
607
SP8Save         dw              0
608
SRSave          dw              0
609
R1Save          dw              0
610
R2Save          dw              0
611
R3Save          dw              0
612
R4Save          dw              0
613
R5Save          dw              0
614
R6Save          dw              0
615
R7Save          dw              0
616
R8Save          dw              0
617
R9Save          dw              0
618
R10Save         dw              0
619
R11Save         dw              0
620
R12Save         dw              0
621
R13Save         dw              0
622
R14Save         dw              0
623
R15Save         dw              0
624
SPSave          dw              0
625 15 robfinch
 
626 39 robfinch
                        .align  0x10
627
CharColor       dw              0
628
ScreenColor     dw              0
629
CursorRow       dw              0
630
CursorCol       dw              0
631
CursorFlash     dw              0
632
Milliseconds    dw              0
633
IRQFlag         dw              0
634
UserTick        dw              0
635
eth_unique_id   dw              0
636
LineColor       dw              0
637
QIndex          dw              0
638
ROMcs           dw              0
639
mmu_present     dw              0
640
TestTask        dw              0
641
BASIC_SESSION   dw              0
642
gr_cmd          dw              0
643
 
644
                        .align  0x10
645
startSector     dw              0
646
disk_size       dw              0
647 28 robfinch
 
648 39 robfinch
;
649
; CAUTION:
650
; - do not use these macros.
651
; - there is currently a bug in the assembler that causes it to lose the
652
;   macro text
653
;
654
macro mStartTask pri,flags,start_addr,param,job
655
        lda             pri
656
        ldx             flags
657
        ldy             start_addr
658
        ld              r4,param
659
        ld              r5,job
660
        int             #4
661
        db              1
662
endm
663 15 robfinch
 
664 39 robfinch
macro mSleep tm
665
        lda             tm
666
        int             #4
667
        db              5
668
endm
669 15 robfinch
 
670 39 robfinch
macro mAllocMbx
671
        int             #4
672
        db              6
673
endm
674 15 robfinch
 
675 39 robfinch
macro mWaitMsg mbx,tmout
676
        lda             mbx
677
        ldx             tmout
678
        int             #4
679
        db              10
680
endm
681
 
682
macro mPostMsg  mbx,d1,d2
683
        lda             mbx
684
        ldx             d1
685
        ldy             d2
686
        int             #4
687
        db              8
688
endm
689
 
690
macro DisTimer
691
        pha
692
        lda             #3
693
        sta             PIC+2
694
        pla
695
endm
696
 
697
macro EnTimer
698
        pha
699
        lda             #3
700
        sta             PIC+3
701
        pla
702
endm
703
 
704
macro DisTmrKbd
705
        pha
706
        lda             #3
707
        sta             PIC+2
708
        lda             #15
709
        sta             PIC+2
710
        pla
711
endm
712
 
713
macro EnTmrKbd
714
        pha
715
        lda             #3
716
        sta             PIC+3
717
        lda             #15
718
        sta             PIC+3
719
        pla
720
endm
721
 
722
macro GoReschedule
723
        int             #2
724
endm
725
 
726
;------------------------------------------------------------------------------
727
; Wait for the TCB array to become available
728
;------------------------------------------------------------------------------
729
;
730
macro mAquireTCB
731
        lda             #33
732
        ldx             #0
733
        txy
734
        ld              r4,#-1
735
        jsr             WaitMsg
736
endm
737
 
738
macro mReleaseTCB
739
        lda             #33
740
        ldx             #$FFFFFFFE
741
        txy
742
        jsr             SendMsg
743
endm
744
 
745
macro mAquireMBX
746
        lda             #34
747
        ldx             #0
748
        txy
749
        ld              r4,#-1
750
        jsr             WaitMsg
751
endm
752
 
753
macro mReleaseMBX
754
        lda             #34
755
        ldx             #$FFFFFFFE
756
        txy
757
        jsr             SendMsg
758
endm
759
 
760
 
761 11 robfinch
        cpu             rtf65002
762
        code
763 15 robfinch
 
764 26 robfinch
message "jump table"
765 15 robfinch
        ; jump table of popular BIOS routines
766 31 robfinch
        org             $FFFF8000
767 34 robfinch
ROMStart:
768 15 robfinch
        dw      DisplayChar
769
        dw      KeybdCheckForKeyDirect
770
        dw      KeybdGetCharDirect
771 26 robfinch
        dw      KeybdGetChar
772
        dw      KeybdCheckForKey
773
        dw      RequestIOFocus
774
        dw      ReleaseIOFocus
775
        dw      ClearScreen
776
        dw      HomeCursor
777
        dw      ExitTask
778
        dw      SetKeyboardEcho
779 28 robfinch
        dw      Sleep
780 31 robfinch
        dw      do_load
781
        dw      do_save
782 39 robfinch
        dw              ICacheInvalidateAll
783
        dw              ICacheInvalidateLine
784 15 robfinch
 
785 31 robfinch
        org             $FFFF8400               ; leave room for 256 vectors
786 26 robfinch
message "cold start point"
787 15 robfinch
KeybdRST
788 11 robfinch
start
789
        sei                                             ; disable interrupts
790
        cld                                             ; disable decimal mode
791 31 robfinch
        lda             #1
792
        sta             LEDS
793 26 robfinch
        ldx             #BIOS_STACKS+0x03FF     ; setup stack pointer top of memory
794 11 robfinch
        txs
795 31 robfinch
        trs             r0,abs8                 ; set 8 bit mode absolute address offset
796 34 robfinch
        lda             #3
797
        trs             r1,cc                   ; enable dcache and icache
798
        jsr             ROMChecksum
799
        sta             ROMcs
800 39 robfinch
        jsr             SetupCacheInvalidate
801
        jsr             InitDevices
802 34 robfinch
        stz             mmu_present             ; assume no mmu
803
        lda             CONFIGREC
804
        bit             #4096
805
        beq             st_nommu
806
        jsr             InitMMU                 ; setup the maps and enable the mmu
807
        lda             #1
808
        sta             mmu_present
809
st_nommu:
810 31 robfinch
        jsr             MemInit                 ; Initialize the heap
811 39 robfinch
        stz             iof_switch
812 31 robfinch
 
813
        lda             #2
814
        sta             LEDS
815
 
816 15 robfinch
        ; setup interrupt vectors
817 39 robfinch
        ldx             #$01FB8001              ; interrupt vector table from $5FB0000 to $5FB01FF
818 18 robfinch
                                                        ; also sets nmoi policy (native mode on interrupt)
819 15 robfinch
        trs             r2,vbr
820 39 robfinch
        and             r2,r2,#-2               ; mask off policy bit
821 34 robfinch
        phx
822
        txy                                             ; y = pointer to vector table
823
        lda             #511                    ; 512 vectors to setup
824
        ldx             #brk_rout               ; point vector to brk routine
825
        stos
826
 
827
        plx
828 15 robfinch
        lda             #brk_rout
829
        sta             (x)
830
        lda             #slp_rout
831
        sta             1,x
832 39 robfinch
        lda             #reschedule             ; must be initialized after vectors are initialized to the break vector
833 34 robfinch
        sta             2,x
834 39 robfinch
        lda             #spinlock_irq
835
        sta             3,x
836
        lda             #syscall_int
837
        sta             4,x
838 15 robfinch
        lda             #KeybdRST
839
        sta             448+1,x
840
        lda             #p1000Hz
841
        sta             448+2,x
842 39 robfinch
        lda             #MTKTick
843 15 robfinch
        sta             448+3,x
844
        lda             #KeybdIRQ
845
        sta             448+15,x
846 26 robfinch
        lda             #SerialIRQ
847
        sta             448+8,x
848 31 robfinch
        lda             #InvalidOpIRQ
849
        sta             495,x
850 26 robfinch
        lda             #bus_err_rout
851
        sta             508,x
852
        sta             509,x
853 15 robfinch
 
854 31 robfinch
        lda             #3
855
        sta             LEDS
856
 
857
        ; stay in native mode in case emulation is not supported.
858
        ldx             #$1FF                   ; set 8 bit stack pointer
859
        trs             r2,sp8
860 26 robfinch
 
861
        ldx             #0
862
        stz             IrqBase                 ; support for EhBASIC's interrupt mechanism
863
        stz             NmiBase
864 31 robfinch
 
865 39 robfinch
        jsr             ($FFFFC000>>2)          ; Initialize multi-tasking
866
        lda             #TickRout               ; setup tick routine
867
        sta             UserTick
868 26 robfinch
 
869 39 robfinch
        lda             #1
870
        sta             iof_sema
871 31 robfinch
 
872 39 robfinch
        lda             #(DCB_SIZE * NR_DCB)-1
873 34 robfinch
        ldx             #0
874 39 robfinch
        ldy             #DCBs
875 34 robfinch
        stos
876 26 robfinch
 
877 11 robfinch
        lda             #$CE                    ; CE =blue on blue FB = grey on grey
878
        sta             ScreenColor
879
        sta             CharColor
880 26 robfinch
        sta             CursorFlash
881 11 robfinch
        jsr             ClearScreen
882 39 robfinch
        jsr             InitBMP
883 15 robfinch
        jsr             ClearBmpScreen
884 34 robfinch
        jsr             PICInit
885
        ; Enable interrupts
886
        ; This will likely cause an interrupt right away because the timer
887
        ; pulses run since power-up.
888
        cli
889 39 robfinch
;       mStartTask      #PRI_LOWEST,#0,#IdleTask,#0,#0
890
        lda             #PRI_LOWEST
891 31 robfinch
        ldx             #0
892
        ldy             #IdleTask
893 39 robfinch
        ld              r4,#0
894
        ld              r5,#0
895
        int             #4
896
        db              1
897 31 robfinch
        lda             CONFIGREC               ; do we have a serial port ?
898
        bit             #32
899
        beq             st7
900
        ; 19200 * 16
901
        ;-------------
902
        ; 25MHz / 2^32
903
        lda             #$03254E6E              ; constant for 19,200 baud at 25MHz
904
        jsr             SerialInit
905
st7:
906
        lda             #5
907
        sta             LEDS
908 28 robfinch
        lda             CONFIGREC               ; do we have sprites ?
909
        bit             #1
910
        beq             st8
911 26 robfinch
        lda             #$3FFF                  ; turn on sprites
912
        sta             SPRITEREGS+120
913
        jsr             RandomizeSprram
914 28 robfinch
st8:
915 31 robfinch
        ; Enable interrupts.
916
        ; Keyboard initialization must take place after interrupts are
917
        ; enabled.
918
        cli
919
        lda             #14
920
        sta             LEDS
921 39 robfinch
        stz             keybdIsSetup
922
;       mStartTask      #PRI_NORMAL,#0,#KeybdSetup,#0
923
        lda             #PRI_NORMAL
924
        ldx             #0
925
        ldy             #KeybdSetup
926
        ld              r4,#0
927
        ld              r5,#0
928
        int             #4
929
        db              1
930
;       lea             r3,KeybdStatusLEDs
931
;       jsr             StartTask
932 31 robfinch
        lda             #6
933
        sta             LEDS
934
 
935 28 robfinch
        ; The following must be after interrupts are enabled.
936 31 robfinch
        lda             #9
937
        sta             LEDS
938
        jsr             HomeCursor
939
        lda             #msgStart
940
        jsr             DisplayStringB
941
        jsr             ReportMemFree
942 34 robfinch
        lda             #msgChecksum
943
        jsr             DisplayStringB
944
        lda             ROMcs
945
        jsr             DisplayWord
946
        jsr             CRLF
947 31 robfinch
        lda             #10
948
        sta             LEDS
949
 
950 28 robfinch
        ; The AC97 setup uses the millisecond counter and the
951
        ; keyboard.
952
        lda             CONFIGREC               ; do we have a sound generator ?
953
        bit             #4
954
        beq             st6
955
        jsr             SetupAC97
956 34 robfinch
        lda             #4
957 31 robfinch
        ldx             #0
958
        ldy             #Beep
959 34 robfinch
;       jsr             StartTask
960 28 robfinch
st6:
961 31 robfinch
        lda             #11
962
        sta             LEDS
963 39 robfinch
        stz             BASIC_SESSION
964 15 robfinch
        jmp             Monitor
965
st1
966
        jsr             KeybdGetCharDirect
967
        bra             st1
968 11 robfinch
        stp
969
        bra             start
970
 
971
msgStart
972
        db              "RTF65002 system starting.",$0d,$0a,00
973
 
974 34 robfinch
;------------------------------------------------------------------------------
975 39 robfinch
; SetupCacheInvalidate:
976 34 robfinch
;
977 39 robfinch
;       Setup the cache invalidate routines. Cache's in the FPGA don't have
978
; invalidate logic as it cannot be efficiently implemented. So we handle
979
; cache invalidations using software. By calling a software routine, or
980
; accessing data in the setup cache invalidate area, the cache will be
981
; effectively invalidated. This works for caches up to 16kB. (4kW)
982 34 robfinch
;------------------------------------------------------------------------------
983 39 robfinch
 
984
message "SetupCacheInvalidate"
985
SetupCacheInvalidate:
986
        lda             #4095
987
        ldx             #$EAEAEAEA                      ; fill memory with NOP's
988
        ldy             #cacheInvRout
989
        stos
990
        lda             #4095
991
        ldx             #$60606060                      ; fill memory with RTS's
992
        ldy             #cacheLineInvRout
993
        stos
994
        rts
995
 
996
;------------------------------------------------------------------------------
997
; ICacheInvalidateAll:
998
;
999
; Call to invalidate the entire ICache
1000
;------------------------------------------------------------------------------
1001
 
1002
ICacheInvalidateAll:
1003
        jml             cacheInvRout<<2
1004
 
1005
;------------------------------------------------------------------------------
1006
; ICacheInvalidateLine:
1007
;
1008
; Call to invalidate a specific cache line
1009
;
1010
; Parameters:
1011
;       r1 = code address in line to invalidate
1012
;------------------------------------------------------------------------------
1013
;
1014
ICacheInvalidateLine:
1015
        and             #$3FFF
1016
        add             #cacheLineInvRout<<2
1017
        jmp             (r1)                            ; this will touch the cache line then RTS
1018
 
1019
;------------------------------------------------------------------------------
1020
; DCacheInvalidateAll:
1021
;
1022
; Call to invalidate the entire DCache. Works by performing a data fetch from
1023
; dummy data at each possible cache address. Works for caches up to 16kB in
1024
; size.
1025
;------------------------------------------------------------------------------
1026
 
1027
DCacheInvalidateAll:
1028
        phx
1029 34 robfinch
        ldx             #0
1030 39 robfinch
.0001:
1031
        ld              r0,cacheInvRout,x
1032 34 robfinch
        inx
1033 39 robfinch
        cpx             #$FFF
1034
        bls             .0001
1035
        plx
1036
        rts
1037 34 robfinch
 
1038 39 robfinch
;------------------------------------------------------------------------------
1039
; DCacheInvalidateLine:
1040
;
1041
; Call to invalidate a specific cache line in the data cache.
1042
;
1043
; Parameters:
1044
;       r1 = data address in line to invalidate
1045
;------------------------------------------------------------------------------
1046
;
1047
DCacheInvalidateLine:
1048 34 robfinch
        pha
1049 39 robfinch
        and             #$FFF
1050
        ld              r0,cacheInvRout,r1
1051 34 robfinch
        pla
1052
        rts
1053 39 robfinch
 
1054
;------------------------------------------------------------------------------
1055
;------------------------------------------------------------------------------
1056
InitBMP:
1057
        ldx             #0
1058
ibmp1:
1059
        tsr             LFSR,r1
1060
        sta             BMP_CLUT,x
1061
        inx
1062
        cpx             #512
1063
        bne             ibmp1
1064 34 robfinch
        rts
1065
 
1066 39 robfinch
 
1067 34 robfinch
;------------------------------------------------------------------------------
1068
; The ROM contents are summed up to ensure the ROM is okay.
1069
;------------------------------------------------------------------------------
1070
ROMChecksum:
1071
        lda             #0
1072
        ldx             #ROMStart>>2
1073
idc1:
1074
        add             (x)
1075
        inx
1076
        cpx             #$100000000>>2
1077
        bne             idc1
1078
        cmp             #0                      ; The sum of all the words in the
1079
                                                ; ROM should be zero.
1080
        rts
1081
 
1082
msgChecksum:
1083
        db      CR,LF,"ROM checksum: ",0
1084
 
1085 15 robfinch
;----------------------------------------------------------
1086
; Initialize programmable interrupt controller (PIC)
1087
;  0 = nmi (parity error)
1088
;  1 = keyboard reset
1089 31 robfinch
;  2 = 1000Hz pulse
1090 15 robfinch
;  3 = 100Hz pulse (cursor flash)
1091
;  4 = ethmac
1092
;  8 = uart
1093
; 13 = raster interrupt
1094
; 15 = keyboard char
1095
;----------------------------------------------------------
1096 26 robfinch
message "PICInit"
1097 15 robfinch
PICInit:
1098 31 robfinch
        ;
1099
        lda             #$000C                  ; clock pulses are edge sensitive
1100
        sta             PIC_ES
1101
        lda             #$000F                  ; enable nmi,kbd_rst
1102 15 robfinch
        ; A10F enable serial IRQ
1103
        sta             PIC_IE
1104
PICret:
1105
        rts
1106
 
1107 11 robfinch
;------------------------------------------------------------------------------
1108 26 robfinch
;------------------------------------------------------------------------------
1109
message "DumpTaskList"
1110
DumpTaskList:
1111
        pha
1112
        phx
1113
        phy
1114
        push    r4
1115
        lda             #msgTaskList
1116
        jsr             DisplayStringB
1117
        ldy             #0
1118 39 robfinch
        spl             tcb_sema + 1
1119 26 robfinch
dtl2:
1120 34 robfinch
        lda             QNdx0,y
1121 26 robfinch
        ld              r4,r1
1122
        bmi             dtl1
1123
dtl3:
1124
        ldx             #3
1125
        tya
1126
        jsr             PRTNUM
1127
        lda             #' '
1128
        jsr             DisplayChar
1129
        ld              r1,r4
1130
        ldx             #3
1131
        jsr             PRTNUM
1132
        lda             #' '
1133
        jsr             DisplayChar
1134
        jsr             DisplayChar
1135
        jsr             DisplayChar
1136
        ld              r1,r4
1137
        lda             TCB_Status,r1
1138
        jsr             DisplayByte
1139
        lda             #' '
1140
        jsr             DisplayChar
1141
        ldx             #3
1142
        lda             TCB_PrvRdy,r4
1143
        jsr             PRTNUM
1144
        lda             #' '
1145
        jsr             DisplayChar
1146
        ldx             #3
1147
        lda             TCB_NxtRdy,r4
1148
        jsr             PRTNUM
1149
        lda             #' '
1150
        jsr             DisplayChar
1151
        lda             TCB_Timeout,r4
1152
        jsr             DisplayWord
1153
        jsr             CRLF
1154
        ld              r4,TCB_NxtRdy,r4
1155 34 robfinch
        cmp             r4,QNdx0,y
1156
        bne             dtl3
1157 26 robfinch
dtl1:
1158
        iny
1159
        cpy             #5
1160
        bne             dtl2
1161 39 robfinch
        stz             tcb_sema + 1
1162 26 robfinch
        pop             r4
1163
        ply
1164
        plx
1165
        pla
1166
        rts
1167
 
1168
msgTaskList:
1169
        db      CR,LF,"Pri Task Stat Prv Nxt Timeout",CR,LF,0
1170
 
1171
;------------------------------------------------------------------------------
1172 28 robfinch
;------------------------------------------------------------------------------
1173 34 robfinch
message "DumpTimeoutList"
1174
DumpTimeoutList:
1175
        pha
1176
        phx
1177
        phy
1178
        push    r4
1179
        lda             #msgTimeoutList
1180
        jsr             DisplayStringB
1181 39 robfinch
        ldy             #11
1182 34 robfinch
dtol2:
1183
        lda             TimeoutList
1184
        ld              r4,r1
1185
        bmi             dtol1
1186 39 robfinch
        spl             tcb_sema + 1
1187 34 robfinch
dtol3:
1188 39 robfinch
        dey
1189
        beq             dtol1
1190 34 robfinch
        ld              r1,r4
1191
        ldx             #3
1192
        jsr             PRTNUM
1193
        lda             #' '
1194
        jsr             DisplayChar
1195
        jsr             DisplayChar
1196
        jsr             DisplayChar
1197
        ld              r1,r4
1198
        ldx             #3
1199 39 robfinch
        lda             TCB_PrvTo,r4
1200 34 robfinch
        jsr             PRTNUM
1201
        lda             #' '
1202
        jsr             DisplayChar
1203
        ldx             #3
1204 39 robfinch
        lda             TCB_NxtTo,r4
1205 34 robfinch
        jsr             PRTNUM
1206
        lda             #' '
1207
        jsr             DisplayChar
1208
        lda             TCB_Timeout,r4
1209
        jsr             DisplayWord
1210
        jsr             CRLF
1211 39 robfinch
        ld              r4,TCB_NxtTo,r4
1212 34 robfinch
        bpl             dtol3
1213
dtol1:
1214 39 robfinch
        stz             tcb_sema + 1
1215 34 robfinch
        pop             r4
1216
        ply
1217
        plx
1218
        pla
1219
        rts
1220
 
1221
msgTimeoutList:
1222
        db      CR,LF,"Task Prv Nxt Timeout",CR,LF,0
1223
 
1224
;------------------------------------------------------------------------------
1225
;------------------------------------------------------------------------------
1226 28 robfinch
message "DumpIOFocusList"
1227
DumpIOFocusList:
1228
        pha
1229
        phx
1230
        phy
1231
        lda             #msgIOFocusList
1232
        jsr             DisplayStringB
1233 39 robfinch
        spl             iof_sema + 1
1234 28 robfinch
        lda             IOFocusNdx
1235
diofl2:
1236 39 robfinch
        beq             diofl1
1237 28 robfinch
        tay
1238
        ldx             #3
1239
        jsr             PRTNUM
1240
        lda             #' '
1241
        jsr             DisplayChar
1242 39 robfinch
        lda             JCB_iof_prev,y
1243 28 robfinch
        ldx             #3
1244
        jsr             PRTNUM
1245
        lda             #' '
1246
        jsr             DisplayChar
1247 39 robfinch
        lda             JCB_iof_next,y
1248 28 robfinch
        ldx             #3
1249
        jsr             PRTNUM
1250
        jsr             CRLF
1251 39 robfinch
        lda             JCB_iof_next,y
1252 28 robfinch
        cmp             IOFocusNdx
1253
        bne             diofl2
1254
 
1255
diofl1:
1256 39 robfinch
        stz             iof_sema + 1
1257 28 robfinch
        ply
1258
        plx
1259
        pla
1260
        rts
1261
 
1262
msgIOFocusList:
1263
        db      CR,LF,"Task Prv Nxt",CR,LF,0
1264 31 robfinch
 
1265
RunningTCBErr:
1266 34 robfinch
;       lda             #$FF
1267
;       sta             LEDS
1268 31 robfinch
        lda             #msgRunningTCB
1269
        jsr             DisplayStringB
1270
rtcberr1:
1271
        jsr             KeybdGetChar
1272
        cmp             #-1
1273
        beq             rtcberr1
1274
        jmp             start
1275
 
1276
msgRunningTCB:
1277
        db      CR,LF,"RunningTCB is bad.",CR,LF,0
1278
 
1279 28 robfinch
;------------------------------------------------------------------------------
1280 39 robfinch
; Get the handle of the currently running job.
1281 26 robfinch
;------------------------------------------------------------------------------
1282 34 robfinch
;
1283 39 robfinch
GetCurrentJob:
1284
        ld              r1,RunningTCB
1285
        ld              r1,TCB_hJCB,r1          ; get the handle
1286 26 robfinch
        rts
1287
 
1288
;------------------------------------------------------------------------------
1289 39 robfinch
; Get a pointer to the JCB for the currently running task.
1290 26 robfinch
;------------------------------------------------------------------------------
1291 34 robfinch
;
1292 39 robfinch
GetPtrCurrentJCB:
1293
        jsr             GetCurrentJob
1294
        and             r1,r1,#NR_JCB-1         ; and convert it to a pointer
1295
;       mul             r1,r1,#JCB_Size
1296
        asl             r1,r1,#JCB_LogSize      ; 256 words
1297
        add             r1,r1,#JCBs
1298 26 robfinch
        rts
1299
 
1300
;------------------------------------------------------------------------------
1301 31 robfinch
; Get the location of the screen and screen attribute memory. The location
1302
; depends on whether or not the task has the output focus.
1303 26 robfinch
;------------------------------------------------------------------------------
1304
GetScreenLocation:
1305 39 robfinch
        jsr             GetPtrCurrentJCB
1306
        lda             JCB_pVidMem,r1
1307 26 robfinch
        rts
1308
 
1309
GetColorCodeLocation:
1310 39 robfinch
        jsr             GetPtrCurrentJCB
1311
        lda             JCB_pVidMemAttr,r1
1312 26 robfinch
        rts
1313 39 robfinch
 
1314
GetNormAttr:
1315
        jsr             GetPtrCurrentJCB
1316
        lda             JCB_NormAttr,r1
1317 26 robfinch
        rts
1318
 
1319 39 robfinch
GetCurrAttr:
1320
        jsr             GetPtrCurrentJCB
1321
        lda             JCB_CurrAttr,r1
1322
        rts
1323
 
1324 26 robfinch
;------------------------------------------------------------------------------
1325
;------------------------------------------------------------------------------
1326
message "CopyVirtualScreenToScreen"
1327
CopyVirtualScreenToScreen
1328
        pha
1329
        phx
1330
        phy
1331 28 robfinch
        push    r4
1332 39 robfinch
        ldx             IOFocusNdx                      ; compute virtual screen location
1333
        beq             cvss3
1334
        ; copy screen chars
1335 26 robfinch
        lda             #4095                           ; number of words to copy-1
1336 39 robfinch
        ldx             JCB_pVirtVid,x
1337 26 robfinch
        ldy             #TEXTSCR
1338 31 robfinch
        mvn
1339 26 robfinch
        ; now copy the color codes
1340
        lda             #4095
1341 28 robfinch
        ldx             IOFocusNdx
1342 39 robfinch
        ldx             JCB_pVirtVidAttr,x
1343 26 robfinch
        ldy             #TEXTSCR+$10000
1344 31 robfinch
        mvn
1345 28 robfinch
cvss3:
1346
        ; reset the cursor position in the text controller
1347
        ldy             IOFocusNdx
1348 39 robfinch
        ldx             JCB_CursorRow,y
1349 28 robfinch
        lda             TEXTREG+TEXT_COLS
1350
        mul             r2,r2,r1
1351 39 robfinch
        add             r2,r2,JCB_CursorCol,y
1352 28 robfinch
        stx             TEXTREG+TEXT_CURPOS
1353
        pop             r4
1354 26 robfinch
        ply
1355
        plx
1356
        pla
1357
        rts
1358
message "CopyScreenToVirtualScreen"
1359
CopyScreenToVirtualScreen
1360
        pha
1361
        phx
1362
        phy
1363 28 robfinch
        push    r4
1364 26 robfinch
        lda             #4095
1365
        ldx             #TEXTSCR
1366 28 robfinch
        ldy             IOFocusNdx
1367 39 robfinch
        beq             csvs3
1368
        ldy             JCB_pVirtVid,y
1369 31 robfinch
        mvn
1370 26 robfinch
        lda             #4095
1371
        ldx             #TEXTSCR+$10000
1372 28 robfinch
        ldy             IOFocusNdx
1373 39 robfinch
        ldy             JCB_pVirtVidAttr,y
1374 31 robfinch
        mvn
1375 28 robfinch
csvs3:
1376
        pop             r4
1377 26 robfinch
        ply
1378
        plx
1379
        pla
1380
        rts
1381
 
1382
;------------------------------------------------------------------------------
1383 11 robfinch
; Clear the screen and the screen color memory
1384
; We clear the screen to give a visual indication that the system
1385
; is working at all.
1386
;------------------------------------------------------------------------------
1387
;
1388 26 robfinch
message "ClearScreen"
1389 11 robfinch
ClearScreen:
1390
        pha                                                     ; holds a space character
1391
        phx                                                     ; loop counter
1392
        phy                                                     ; memory addressing
1393
        lda             TEXTREG+TEXT_COLS       ; calc number to clear
1394
        ldx             TEXTREG+TEXT_ROWS
1395 34 robfinch
        mul             r1,r1,r2                        ; r1 = # chars to clear
1396
        pha
1397 26 robfinch
        jsr             GetScreenLocation
1398 34 robfinch
        tay                                                     ; y = target address
1399 11 robfinch
        lda             #' '                            ; space char
1400
        jsr             AsciiToScreen
1401 34 robfinch
        tax                                                     ; x is value to store
1402
        pla                                                     ; a is count
1403
        pha
1404
        stos                                            ; clear the memory
1405 39 robfinch
        jsr             GetCurrAttr
1406
        tax                                                     ; x = value to use
1407 34 robfinch
        jsr             GetColorCodeLocation
1408 39 robfinch
        tay                                                     ; y = target address
1409 34 robfinch
        pla                                                     ; a = count
1410
        stos
1411 11 robfinch
        ply
1412
        plx
1413
        pla
1414
        rts
1415
 
1416
;------------------------------------------------------------------------------
1417
; Scroll text on the screen upwards
1418
;------------------------------------------------------------------------------
1419
;
1420 26 robfinch
message "ScrollUp"
1421 11 robfinch
ScrollUp:
1422
        pha
1423
        phx
1424
        phy
1425
        push    r4
1426
        push    r5
1427 26 robfinch
        push    r6
1428 11 robfinch
        lda             TEXTREG+TEXT_COLS       ; acc = # text columns
1429
        ldx             TEXTREG+TEXT_ROWS
1430
        mul             r2,r1,r2                        ; calc number of chars to scroll
1431
        sub             r2,r2,r1                        ; one less row
1432 26 robfinch
        pha
1433
        jsr             GetScreenLocation
1434
        tay
1435
        jsr             GetColorCodeLocation
1436
        ld              r6,r1
1437
        pla
1438 11 robfinch
scrup1:
1439
        add             r5,r3,r1
1440
        ld              r4,(r5)                         ; move character
1441
        st              r4,(y)
1442 26 robfinch
        add             r5,r6,r1
1443
        ld              r4,(r5)                         ; and move color code
1444
        st              r4,(r6)
1445 11 robfinch
        iny
1446 26 robfinch
        inc             r6
1447 11 robfinch
        dex
1448
        bne             scrup1
1449
        lda             TEXTREG+TEXT_ROWS
1450
        dea
1451
        jsr             BlankLine
1452 26 robfinch
        pop             r6
1453 11 robfinch
        pop             r5
1454
        pop             r4
1455
        ply
1456
        plx
1457
        pla
1458
        rts
1459
 
1460
;------------------------------------------------------------------------------
1461
; Blank out a line on the display
1462
; line number to blank is in acc
1463
;------------------------------------------------------------------------------
1464
;
1465
BlankLine:
1466
        pha
1467
        phx
1468
        phy
1469 26 robfinch
        push    r4
1470 39 robfinch
        push    r5
1471 11 robfinch
        ldx             TEXTREG+TEXT_COLS       ; x = # chars to blank out from video controller
1472
        mul             r3,r2,r1                        ; y = screen index (row# * #cols)
1473 39 robfinch
        ld              r5,r3                           ; r5 = screen index
1474 26 robfinch
        pha
1475
        jsr             GetScreenLocation
1476
        ld              r4,r1
1477
        pla
1478
        add             r3,r3,r4                ; y = screen address
1479 11 robfinch
        lda             #' '
1480 26 robfinch
        jsr             AsciiToScreen
1481 11 robfinch
blnkln1:
1482
        sta             (y)
1483
        iny
1484
        dex
1485
        bne             blnkln1
1486 39 robfinch
        ; reset the color codes on the display line to the normal attribute
1487
        jsr             GetColorCodeLocation
1488
        tay                                                     ; y = destination
1489
        add             r3,r3,r5                        ; add in index
1490
        jsr             GetNormAttr                     ; get the value to set
1491
        tax
1492
        lda             TEXTREG+TEXT_COLS       ; number of columns to blank out
1493
        dea                                                     ; acc is one less
1494
        stos
1495
        pop             r5
1496 26 robfinch
        pop             r4
1497 11 robfinch
        ply
1498
        plx
1499
        pla
1500
        rts
1501
 
1502
;------------------------------------------------------------------------------
1503
; Convert ASCII character to screen display character.
1504
;------------------------------------------------------------------------------
1505
;
1506 39 robfinch
        align   8
1507 11 robfinch
AsciiToScreen:
1508
        and             #$FF
1509
        or              #$100
1510 39 robfinch
        bit             #%00100000      ; if bit 5 isn't set
1511
        beq             .00001
1512
        bit             #%01000000      ; or bit 6 isn't set
1513
        beq             .00001
1514
        and             #%110011111
1515
.00001:
1516 11 robfinch
        rts
1517
 
1518
;------------------------------------------------------------------------------
1519
; Convert screen character to ascii character
1520
;------------------------------------------------------------------------------
1521
;
1522
ScreenToAscii:
1523
        and             #$FF
1524 15 robfinch
        cmp             #26+1
1525 11 robfinch
        bcs             stasc1
1526
        add             #$60
1527
stasc1:
1528
        rts
1529
 
1530
;------------------------------------------------------------------------------
1531 26 robfinch
; HomeCursor
1532
; Set the cursor location to the top left of the screen.
1533
;------------------------------------------------------------------------------
1534
HomeCursor:
1535 39 robfinch
        pha
1536 26 robfinch
        phx
1537 39 robfinch
        phy
1538
        spl             jcb_sema + 1
1539
        jsr             GetPtrCurrentJCB
1540
        tax
1541
        stz             JCB_CursorRow,x
1542
        stz             JCB_CursorCol,x
1543
        stz             jcb_sema + 1
1544 31 robfinch
        cpx             IOFocusNdx
1545
        bne             hc1
1546
        stz             TEXTREG+TEXT_CURPOS
1547
hc1:
1548 39 robfinch
        ply
1549 26 robfinch
        plx
1550 39 robfinch
        pla
1551 26 robfinch
        rts
1552
 
1553
;------------------------------------------------------------------------------
1554 31 robfinch
; Update the cursor position in the text controller based on the
1555
;  CursorRow,CursorCol.
1556
;------------------------------------------------------------------------------
1557
;
1558
UpdateCursorPos:
1559
        pha
1560 39 robfinch
        jsr             GetPtrCurrentJCB
1561
        cmp             IOFocusNdx                              ; update cursor position in text controller
1562
        bne             .ucp1                                   ; only for the task with the output focus
1563
        ld              r0,JCB_CursorOn,r4              ; only update if cursor is showing
1564
        beq             .ucp2
1565
        jsr             CursorOn
1566 31 robfinch
        phx
1567
        push    r4
1568 39 robfinch
        ld              r4,r1
1569
        lda             JCB_CursorRow,r4
1570 31 robfinch
        and             #$3F                                    ; limit of 63 rows
1571
        ldx             TEXTREG+TEXT_COLS
1572
        mul             r2,r2,r1
1573 39 robfinch
        lda             JCB_CursorCol,r4
1574 31 robfinch
        and             #$7F                                    ; limit of 127 cols
1575
        add             r2,r2,r1
1576
        stx             TEXTREG+TEXT_CURPOS
1577
        pop             r4
1578
        plx
1579 39 robfinch
.ucp1:
1580 31 robfinch
        pla
1581
        rts
1582 39 robfinch
.ucp2:
1583
        jsr             CursorOff
1584
        pla
1585
        rts
1586 31 robfinch
 
1587 39 robfinch
CursorOff:
1588
        pha
1589
        lda             #5
1590
        bms             TEXTREG+TEXT_CURCTL
1591
        lda             #6
1592
        bmc             TEXTREG+TEXT_CURCTL
1593
        pla
1594
        rts
1595
 
1596
CursorOn:
1597
        pha
1598
        lda             #5
1599
        bmc             TEXTREG+TEXT_CURCTL
1600
        lda             #6
1601
        bms             TEXTREG+TEXT_CURCTL
1602
        pla
1603
        rts
1604
 
1605 31 robfinch
;------------------------------------------------------------------------------
1606 11 robfinch
; Calculate screen memory location from CursorRow,CursorCol.
1607
; Also refreshes the cursor location.
1608
; Returns:
1609
; r1 = screen location
1610
;------------------------------------------------------------------------------
1611
;
1612
CalcScreenLoc:
1613
        phx
1614 26 robfinch
        push    r4
1615 39 robfinch
        jsr             GetPtrCurrentJCB
1616
        ld              r4,r1
1617
        lda             JCB_CursorRow,r4
1618 31 robfinch
        and             #$3F                                    ; limit to 63 rows
1619 11 robfinch
        ldx             TEXTREG+TEXT_COLS
1620
        mul             r2,r2,r1
1621 39 robfinch
        lda             JCB_CursorCol,r4
1622 31 robfinch
        and             #$7F                                    ; limit to 127 cols
1623
        add             r2,r2,r1
1624 28 robfinch
        cmp             r4,IOFocusNdx                   ; update cursor position in text controller
1625 26 robfinch
        bne             csl1                                    ; only for the task with the output focus
1626 11 robfinch
        stx             TEXTREG+TEXT_CURPOS
1627 26 robfinch
csl1:
1628
        jsr             GetScreenLocation
1629 39 robfinch
        add             r1,r1,r2
1630 31 robfinch
        pop             r4
1631
        plx
1632
        rts
1633 11 robfinch
 
1634
;------------------------------------------------------------------------------
1635 26 robfinch
; Display a character on the screen.
1636
; If the task doesn't have the I/O focus then the character is written to
1637
; the virtual screen.
1638 39 robfinch
;
1639
; Parameters:
1640
;       r1 = char to display
1641 11 robfinch
;------------------------------------------------------------------------------
1642
;
1643 26 robfinch
message "DisplayChar"
1644 11 robfinch
DisplayChar:
1645 26 robfinch
        push    r4
1646 39 robfinch
        pha
1647
        jsr             GetPtrCurrentJCB
1648
        ld              r4,r1
1649
        lda             JCB_esc,r4                      ; are we building an escape sequence ?
1650
        bne             .processEsc
1651
        pla
1652 26 robfinch
        and             #$FF                            ; mask off any higher order bits (called from eight bit mode).
1653 39 robfinch
        cmp             #ESC
1654
        bne             .0001
1655
        sta             JCB_esc,r4                      ; begin the esc sequence
1656
        pop             r4
1657
        rts
1658
.0001
1659
        cmp             #BELL
1660
        bne             .noBell
1661
        jsr             Beep
1662
        pop             r4
1663
        rts
1664
.noBell
1665 11 robfinch
        cmp             #'\r'                           ; carriage return ?
1666 39 robfinch
        bne             .dccr
1667
        stz             JCB_CursorCol,r4        ; just set cursor column to zero on a CR
1668 31 robfinch
        jsr             UpdateCursorPos
1669 39 robfinch
.dcx14:
1670 26 robfinch
        pop             r4
1671 11 robfinch
        rts
1672 39 robfinch
.dccr:
1673 11 robfinch
        cmp             #$91                            ; cursor right ?
1674 39 robfinch
        bne             .dcx6
1675 11 robfinch
        pha
1676 39 robfinch
        lda             JCB_CursorCol,r4
1677 11 robfinch
        ina
1678 39 robfinch
        cmp             JCB_VideoCols,r4
1679
        bhs             .dcx7
1680
        sta             JCB_CursorCol,r4
1681
.dcx7:
1682 31 robfinch
        jsr             UpdateCursorPos
1683 11 robfinch
        pla
1684 26 robfinch
        pop             r4
1685 11 robfinch
        rts
1686 39 robfinch
.dcx6:
1687 11 robfinch
        cmp             #$90                            ; cursor up ?
1688 39 robfinch
        bne             .dcx8
1689 11 robfinch
        pha
1690 39 robfinch
        lda             JCB_CursorRow,r4
1691
        beq             .dcx7
1692 11 robfinch
        dea
1693 39 robfinch
        sta             JCB_CursorRow,r4
1694
        bra             .dcx7
1695
.dcx8:
1696 11 robfinch
        cmp             #$93                            ; cursor left ?
1697 39 robfinch
        bne             .dcx9
1698 11 robfinch
        pha
1699 39 robfinch
        lda             JCB_CursorCol,r4
1700
        beq             .dcx7
1701 11 robfinch
        dea
1702 39 robfinch
        sta             JCB_CursorCol,r4
1703
        bra             .dcx7
1704
.dcx9:
1705 11 robfinch
        cmp             #$92                            ; cursor down ?
1706 39 robfinch
        bne             .dcx10
1707 11 robfinch
        pha
1708 39 robfinch
        lda             JCB_CursorRow,r4
1709 11 robfinch
        ina
1710 39 robfinch
        cmp             JCB_VideoRows,r4
1711
        bhs             .dcx7
1712
        sta             JCB_CursorRow,r4
1713
        bra             .dcx7
1714
.dcx10:
1715 11 robfinch
        cmp             #$94                            ; cursor home ?
1716 39 robfinch
        bne             .dcx11
1717 11 robfinch
        pha
1718 39 robfinch
        lda             JCB_CursorCol,r4
1719
        beq             .dcx12
1720
        stz             JCB_CursorCol,r4
1721
        bra             .dcx7
1722
.dcx12:
1723
        stz             JCB_CursorRow,r4
1724
        bra             .dcx7
1725
.dcx11:
1726 11 robfinch
        pha
1727
        phx
1728
        phy
1729
        cmp             #$99                            ; delete ?
1730 39 robfinch
        bne             .dcx13
1731
.doDel:
1732 11 robfinch
        jsr             CalcScreenLoc
1733
        tay                                                     ; y = screen location
1734 39 robfinch
        lda             JCB_CursorCol,r4        ; acc = cursor column
1735
        bra             .dcx5
1736
.dcx13
1737 11 robfinch
        cmp             #CTRLH                          ; backspace ?
1738 39 robfinch
        bne             .dcx3
1739
        lda             JCB_CursorCol,r4
1740
        beq             .dcx4
1741 11 robfinch
        dea
1742 39 robfinch
        sta             JCB_CursorCol,r4
1743 11 robfinch
        jsr             CalcScreenLoc           ; acc = screen location
1744
        tay                                                     ; y = screen location
1745 39 robfinch
        lda             JCB_CursorCol,r4
1746
.dcx5:
1747 11 robfinch
        ldx             $4,y
1748
        stx             (y)
1749
        iny
1750
        ina
1751 39 robfinch
        cmp             JCB_VideoCols,r4
1752
        blo             .dcx5
1753 11 robfinch
        lda             #' '
1754
        jsr             AsciiToScreen
1755
        dey
1756
        sta             (y)
1757 39 robfinch
        bra             .dcx4
1758
.dcx3:
1759 11 robfinch
        cmp             #'\n'                   ; linefeed ?
1760 39 robfinch
        beq             .dclf
1761 11 robfinch
        tax                                             ; save acc in x
1762
        jsr     CalcScreenLoc   ; acc = screen location
1763
        tay                                             ; y = screen location
1764
        txa                                             ; restore r1
1765
        jsr             AsciiToScreen   ; convert ascii char to screen char
1766
        sta             (y)
1767 26 robfinch
        jsr             GetScreenLocation
1768
        sub             r3,r3,r1                ; make y an index into the screen
1769
        jsr             GetColorCodeLocation
1770
        add             r3,r3,r1
1771 39 robfinch
        jsr             GetCurrAttr
1772 26 robfinch
        sta             (y)
1773 11 robfinch
        jsr             IncCursorPos
1774 39 robfinch
        bra             .dcx4
1775
.dclf:
1776 11 robfinch
        jsr             IncCursorRow
1777 39 robfinch
.dcx4:
1778 11 robfinch
        ply
1779
        plx
1780
        pla
1781 26 robfinch
        pop             r4
1782 11 robfinch
        rts
1783
 
1784 39 robfinch
        ; ESC processing
1785
.processEsc:
1786
        cmp             #(ESC<<24)+('('<<16)+(ESC<<8)+'G'
1787
        beq             .procAttr
1788
        bit             #$FF000000                      ; is it some other five byte escape sequence ?
1789
        bne             .unrecogEsc
1790
        cmp             #(ESC<<16)+('('<<8)+ESC
1791
        beq             .testG
1792
        bit             #$FF0000                        ; is it some other four byte escape sequence ?
1793
        bne             .unrecogEsc                     ; - unrecognized escape sequence
1794
        cmp             #(ESC<<8)+'`'
1795
        beq             .cursOnOff
1796
        cmp             #(ESC<<8)+'('
1797
        beq             .testEsc
1798
        bit             #$FF00                          ; is it some other three byte sequence ?
1799
        bne             .unrecogEsc                     ; - unrecognized escape sequence
1800
        cmp             #ESC                            ; check for single char escapes
1801
        beq             .esc1
1802
        pla                                                     ; some other garbage in the esc buffer ?
1803
        stz             JCB_esc,r4
1804
        pop             r4
1805
        rts
1806
 
1807
.cursOnOff:
1808
        pla
1809
        stz             JCB_CursorOn,r4
1810
        and             #$FF
1811
        cmp             #'0'
1812
        beq             .escRst
1813
        inc             JCB_CursorOn,r4
1814
.escRst:
1815
        stz             JCB_esc,r4                      ; reset escape sequence capture
1816
        pop             r4
1817
        rts
1818
 
1819
.procAttr:
1820
        pla
1821
        and             #$FF
1822
        cmp             #'0'
1823
        bne             .0005
1824
        lda             JCB_NormAttr,r4
1825
        sta             JCB_CurrAttr,r4
1826
        bra             .escRst
1827
.0005:
1828
        cmp             #'4'
1829
        bne             .escRst
1830
        phx
1831
        lda             JCB_NormAttr,r4         ; get the normal attribute
1832
        tax
1833
        lsr             r1,r1,#5                        ; swap foreground and background colors
1834
        and             #$1F
1835
        asl             r2,r2,#5
1836
        or              r1,r1,r2
1837
        plx
1838
        sta             JCB_CurrAttr,r4         ; store in current attribute
1839
        bra             .escRst
1840
 
1841
.esc1:
1842
        pla
1843
        and             #$FF
1844
        cmp             #'W'                            ; esc 'W' - delete char under cursor
1845
        bne             .0006
1846
        stz             JCB_esc,r4
1847
        pha
1848
        phx
1849
        phy
1850
        bra             .doDel
1851
.0006:
1852
        cmp             #'T'                            ; esc 'T' - clear to end of line
1853
        bne             .0009
1854
        phx
1855
        phy
1856
        ldx             JCB_CursorCol,r4
1857
        jsr     CalcScreenLoc           ; acc = screen location
1858
        tay
1859
        lda             #' '
1860
        jsr             AsciiToScreen
1861
.0008:
1862
        sta             (y)
1863
        iny
1864
        inx
1865
        cpx             JCB_VideoCols,r4
1866
        blo             .0008
1867
        ply
1868
        plx
1869
        bra             .escRst
1870
.0009:
1871
        cmp             #'`'
1872
        bne             .0010
1873
        bra             .stuffChar
1874
.0010:
1875
        cmp             #'('
1876
        bne             .escRst
1877
        bra             .stuffChar
1878
 
1879
.unrecogEsc:
1880
        pla
1881
        bra             .escRst
1882
 
1883
.testG:
1884
        pla
1885
        and             #$FF
1886
        cmp             #'G'
1887
        bne             .escRst
1888
 
1889
        ; stuff a character into the escape sequence
1890
.stuffChar:
1891
        pha
1892
        lda             JCB_esc,r4
1893
        asl             r1,r1,#8
1894
        or              r1,r1,0,sp
1895
        sta             JCB_esc,r4
1896
        pla
1897
        pop             r4
1898
        rts
1899
 
1900
.testEsc:
1901
        pla
1902
        and             #$FF
1903
        cmp             #ESC
1904
        bne             .escRst
1905
        bra             .stuffChar
1906
 
1907 11 robfinch
;------------------------------------------------------------------------------
1908
; Increment the cursor position, scroll the screen if needed.
1909
;------------------------------------------------------------------------------
1910
;
1911 39 robfinch
message "IncCursorPos"
1912 11 robfinch
IncCursorPos:
1913
        pha
1914
        phx
1915 26 robfinch
        push    r4
1916 39 robfinch
        jsr             GetPtrCurrentJCB
1917
        ld              r4,r1
1918
        lda             JCB_CursorCol,r4
1919 11 robfinch
        ina
1920 39 robfinch
        sta             JCB_CursorCol,r4
1921
        ldx             JCB_VideoCols,r4
1922 11 robfinch
        cmp             r1,r2
1923 39 robfinch
        blo             icc1
1924
        stz             JCB_CursorCol,r4                ; column = 0
1925 11 robfinch
        bra             icr1
1926
IncCursorRow:
1927
        pha
1928
        phx
1929 26 robfinch
        push    r4
1930 39 robfinch
        jsr             GetPtrCurrentJCB
1931
        ld              r4,r1
1932 11 robfinch
icr1:
1933 39 robfinch
        lda             JCB_CursorRow,r4
1934 11 robfinch
        ina
1935 39 robfinch
        sta             JCB_CursorRow,r4
1936
        ldx             JCB_VideoRows,r4
1937 11 robfinch
        cmp             r1,r2
1938 39 robfinch
        blo             icc1
1939 11 robfinch
        dex                                                     ; backup the cursor row, we are scrolling up
1940 39 robfinch
        stx             JCB_CursorRow,r4
1941 11 robfinch
        jsr             ScrollUp
1942
icc1:
1943 31 robfinch
        jsr             UpdateCursorPos
1944
icc2:
1945 26 robfinch
        pop             r4
1946 11 robfinch
        plx
1947
        pla
1948
        rts
1949
 
1950
;------------------------------------------------------------------------------
1951
; Display a string on the screen.
1952
; The characters are packed 4 per word
1953
;------------------------------------------------------------------------------
1954
;
1955 39 robfinch
message "DisplayStringB"
1956 11 robfinch
DisplayStringB:
1957
        pha
1958
        phx
1959
        tax                                             ; r2 = pointer to string
1960
dspj1B:
1961 15 robfinch
        lb              r1,0,x                  ; move string char into acc
1962 11 robfinch
        inx                                             ; increment pointer
1963
        cmp             #0                              ; is it end of string ?
1964
        beq             dsretB
1965
        jsr             DisplayChar             ; display character
1966 15 robfinch
        bra             dspj1B
1967 11 robfinch
dsretB:
1968
        plx
1969
        pla
1970
        rts
1971
 
1972 31 robfinch
DisplayStringQ:
1973
        pha
1974
        phx
1975
        tax                                             ; r2 = pointer to string
1976
        lda             #TEXTSCR
1977
        sta             QIndex
1978
dspj1Q:
1979
        lb              r1,0,x                  ; move string char into acc
1980
        inx                                             ; increment pointer
1981
        cmp             #0                              ; is it end of string ?
1982
        beq             dsretQ
1983
        jsr             DisplayCharQ    ; display character
1984
        bra             dspj1Q
1985
dsretQ:
1986
        plx
1987
        pla
1988
        rts
1989
 
1990
DisplayCharQ:
1991
        pha
1992
        phx
1993
        jsr             AsciiToScreen
1994
        ldx             #0
1995
        sta             (QIndex,x)
1996
        lda             QIndex
1997
        ina
1998
        sta             QIndex
1999
;       inc             QIndex
2000
        plx
2001
        pla
2002
        rts
2003
 
2004
 
2005 11 robfinch
;------------------------------------------------------------------------------
2006
; Display a string on the screen.
2007
; The characters are packed 1 per word
2008
;------------------------------------------------------------------------------
2009
;
2010 39 robfinch
message "DisplayStringW"
2011 11 robfinch
DisplayStringW:
2012
        pha
2013
        phx
2014
        tax                                             ; r2 = pointer to string
2015
dspj1W:
2016
        lda             (x)                             ; move string char into acc
2017
        inx                                             ; increment pointer
2018
        cmp             #0                              ; is it end of string ?
2019
        beq             dsretW
2020
        jsr             DisplayChar             ; display character
2021
        bra             dspj1W                  ; go back for next character
2022
dsretW:
2023
        plx
2024
        pla
2025
        rts
2026
 
2027
DisplayStringCRLFB:
2028
        jsr             DisplayStringB
2029
CRLF:
2030
        pha
2031
        lda             #'\r'
2032
        jsr             DisplayChar
2033
        lda             #'\n'
2034
        jsr             DisplayChar
2035
        pla
2036
        rts
2037
 
2038
;------------------------------------------------------------------------------
2039 15 robfinch
;------------------------------------------------------------------------------
2040 39 robfinch
message "TickRout"
2041
TickRout:
2042 26 robfinch
        ; support EhBASIC's IRQ functionality
2043
        ; code derived from minimon.asm
2044 39 robfinch
        lda             #3                              ; Timer is IRQ #3
2045
        sta             IrqSource               ; stuff a byte indicating the IRQ source for PEEK()
2046 26 robfinch
        lb              r1,IrqBase              ; get the IRQ flag byte
2047 39 robfinch
        lsr             r4,r1
2048
        or              r1,r1,r4
2049 26 robfinch
        and             #$E0
2050 39 robfinch
        sb              r1,IrqBase
2051 26 robfinch
 
2052 39 robfinch
        inc             TEXTSCR+55              ; update IRQ live indicator on screen
2053
 
2054
        ; flash the cursor
2055
        jsr             GetPtrCurrentJCB
2056
        tax
2057
        cpx             IOFocusNdx              ; only bother to flash the cursor for the task with the IO focus.
2058
        bne             tr1a
2059
        lda             JCB_CursorFlash,x       ; test if we want a flashing cursor
2060
        beq             tr1a
2061
        jsr             CalcScreenLoc   ; compute cursor location in memory
2062
        tay
2063
        lda             $10000,y                ; get color code $10000 higher in memory
2064
        ld              r4,IRQFlag              ; get counter
2065
        lsr             r4,r4
2066
        and             r4,r4,#$0F              ; limit to low order nybble
2067
        and             #$F0                    ; prepare to or in new value, mask off foreground color
2068
        or              r1,r1,r4                ; set new foreground color for cursor
2069
        sta             $10000,y                ; store the color code back to memory
2070
tr1a
2071
        rts
2072 26 robfinch
 
2073 39 robfinch
message "null.asm"
2074
include "null.asm"
2075
message "keyboard.asm"
2076
include "keyboard.asm"
2077
message "iofocus.asm"
2078
include "iofocus.asm"
2079
message "serial.asm"
2080
include "serial.asm"
2081 34 robfinch
 
2082 39 robfinch
message "797"
2083 15 robfinch
;------------------------------------------------------------------------------
2084 39 robfinch
; Display the half-word in r1
2085 15 robfinch
;------------------------------------------------------------------------------
2086 34 robfinch
;
2087 39 robfinch
DisplayWord:
2088 34 robfinch
        pha
2089 39 robfinch
        lsr             r1,r1,#16
2090
        jsr             DisplayHalf
2091 34 robfinch
        pla
2092 26 robfinch
 
2093
;------------------------------------------------------------------------------
2094 39 robfinch
; Display the half-word in r1
2095 26 robfinch
;------------------------------------------------------------------------------
2096
;
2097 39 robfinch
DisplayHalf:
2098 28 robfinch
        pha
2099 39 robfinch
        lsr             r1,r1,#8
2100
        jsr             DisplayByte
2101 28 robfinch
        pla
2102 15 robfinch
 
2103
;------------------------------------------------------------------------------
2104 39 robfinch
; Display the byte in r1
2105 15 robfinch
;------------------------------------------------------------------------------
2106
;
2107 39 robfinch
DisplayByte:
2108 26 robfinch
        pha
2109 39 robfinch
        lsr             r1,r1,#4
2110
        jsr             DisplayNybble
2111 26 robfinch
        pla
2112 39 robfinch
 
2113 26 robfinch
;------------------------------------------------------------------------------
2114 11 robfinch
; Display nybble in r1
2115
;------------------------------------------------------------------------------
2116
;
2117
DisplayNybble:
2118
        pha
2119
        and             #$0F
2120
        add             #'0'
2121 15 robfinch
        cmp             #'9'+1
2122 11 robfinch
        bcc             dispnyb1
2123
        add             #7
2124
dispnyb1:
2125
        jsr             DisplayChar
2126
        pla
2127
        rts
2128
 
2129 15 robfinch
message "810"
2130
;------------------------------------------------------------------------------
2131
; Display memory pointed to by r2.
2132
; destroys r1,r3
2133
;------------------------------------------------------------------------------
2134
;
2135
DisplayMemW:
2136
        pha
2137 39 robfinch
        lda             #'>'
2138 15 robfinch
        jsr             DisplayChar
2139
        txa
2140
        jsr             DisplayWord
2141
        lda             #' '
2142
        jsr             DisplayChar
2143
        lda             (x)
2144
        jsr             DisplayWord
2145
        inx
2146
        lda             #' '
2147
        jsr             DisplayChar
2148
        lda             (x)
2149
        jsr             DisplayWord
2150
        inx
2151
        lda             #' '
2152
        jsr             DisplayChar
2153
        lda             (x)
2154
        jsr             DisplayWord
2155
        inx
2156
        lda             #' '
2157
        jsr             DisplayChar
2158
        lda             (x)
2159
        jsr             DisplayWord
2160
        inx
2161
        jsr             CRLF
2162
        pla
2163
        rts
2164 26 robfinch
 
2165 39 robfinch
;------------------------------------------------------------------------------
2166
; Display memory pointed to by r2.
2167
; destroys r1,r3
2168
;------------------------------------------------------------------------------
2169
;
2170
DisplayMemBytes:
2171
        pha
2172
        phy
2173
        lda             #'>'
2174
        jsr             DisplayChar
2175
        lda             #'B'
2176
        jsr             DisplayChar
2177
        lda             #' '
2178
        jsr             DisplayChar
2179
        txa
2180
        jsr             DisplayWord
2181
        ldy             #0
2182
.001:
2183
        lda             #' '
2184
        jsr             DisplayChar
2185
        lb              r1,0,x
2186
        jsr             DisplayByte
2187
        inx
2188
        iny
2189
        cpy             #8
2190
        blo             .001
2191
        lda             #':'
2192
        jsr             DisplayChar
2193
        ldy             #0
2194
        sub             r2,r2,#8
2195
.002
2196
        lb              r1,0,x
2197
        cmp             #26                     ; convert control characters to '.'
2198
        bhs             .003
2199
        lda             #'.'
2200
.003:
2201
        jsr             DisplayChar
2202
        inx
2203
        iny
2204
        cpy             #8
2205
        blo             .002
2206
        jsr             CRLF
2207
        ply
2208
        pla
2209
        rts
2210
 
2211 26 robfinch
message "Monitor"
2212 15 robfinch
;==============================================================================
2213
; System Monitor Program
2214 26 robfinch
; The system monitor is task#0
2215 15 robfinch
;==============================================================================
2216
;
2217
Monitor:
2218 26 robfinch
        ldx             #BIOS_STACKS+0x03FF     ; setup stack pointer
2219 15 robfinch
        txs
2220 28 robfinch
        lda             #0                                      ; turn off keyboard echo
2221
        jsr             SetKeyboardEcho
2222
        jsr             RequestIOFocus
2223 39 robfinch
.PromptLn:
2224 15 robfinch
        jsr             CRLF
2225
        lda             #'$'
2226
        jsr             DisplayChar
2227
 
2228
; Get characters until a CR is keyed
2229
;
2230 39 robfinch
.Prompt3:
2231 28 robfinch
        jsr             RequestIOFocus
2232 15 robfinch
;       lw              r1,#2                   ; get keyboard character
2233
;       syscall #417
2234 26 robfinch
;       jsr             KeybdCheckForKeyDirect
2235
;       cmp             #0
2236
        jsr             KeybdGetChar
2237
        cmp             #-1
2238 39 robfinch
        beq             .Prompt3
2239 26 robfinch
;       jsr             KeybdGetCharDirect
2240 15 robfinch
        cmp             #CR
2241 39 robfinch
        beq             .Prompt1
2242 15 robfinch
        jsr             DisplayChar
2243 39 robfinch
        bra             .Prompt3
2244 15 robfinch
 
2245
; Process the screen line that the CR was keyed on
2246
;
2247 39 robfinch
.Prompt1:
2248 31 robfinch
        lda             #80
2249
        sta             LEDS
2250 26 robfinch
        ldx             RunningTCB
2251 39 robfinch
        ldx             TCB_hJCB,x
2252
        cpx             #NR_JCB
2253
        bhs             .Prompt3
2254
        mul             r2,r2,#JCB_Size
2255
        add             r2,r2,#JCBs
2256 31 robfinch
        lda             #81
2257
        sta             LEDS
2258 39 robfinch
        stz             JCB_CursorCol,x ; go back to the start of the line
2259 15 robfinch
        jsr             CalcScreenLoc   ; r1 = screen memory location
2260
        tay
2261 31 robfinch
        lda             #82
2262
        sta             LEDS
2263 34 robfinch
        jsr             MonGetch
2264 15 robfinch
        cmp             #'$'
2265 39 robfinch
        bne             .Prompt2                        ; skip over '$' prompt character
2266 31 robfinch
        lda             #83
2267
        sta             LEDS
2268 34 robfinch
        jsr             MonGetch
2269 15 robfinch
 
2270
; Dispatch based on command character
2271
;
2272 39 robfinch
.Prompt2:
2273
        cmp             #'>'
2274 15 robfinch
        beq             EditMem
2275 39 robfinch
        cmp             #'M'
2276
        bne             .testDIR
2277
        jsr             MonGetch
2278
        cmp             #'B'
2279
        beq             DumpMemBytes
2280
        dey
2281
        bra             DumpMem
2282
.testDIR:
2283 15 robfinch
        cmp             #'D'
2284 39 robfinch
        bne             .Prompt8
2285 31 robfinch
        cmp             #'I'
2286
        beq             DoDir
2287 39 robfinch
        bra             Monitor
2288
.Prompt8:
2289 15 robfinch
        cmp             #'F'
2290 39 robfinch
        bne             .Prompt7
2291 34 robfinch
        jsr             MonGetch
2292 28 robfinch
        cmp             #'L'
2293 39 robfinch
        bne             .Prompt8a
2294 28 robfinch
        jsr             DumpIOFocusList
2295
        jmp             Monitor
2296 39 robfinch
.Prompt8a:
2297 34 robfinch
        cmp             #'I'
2298
        beq             DoFig
2299 31 robfinch
        cmp             #'M'
2300
        beq             DoFmt
2301 28 robfinch
        dey
2302
        bra             FillMem
2303 39 robfinch
.Prompt7:
2304 15 robfinch
        cmp             #'B'                    ; $B - start tiny basic
2305 39 robfinch
        bne             .Prompt4
2306
        mStartTask      #PRI_LOW,#0,#CSTART,#0,#4
2307 15 robfinch
        bra             Monitor
2308 39 robfinch
.Prompt4:
2309 15 robfinch
        cmp             #'b'
2310 39 robfinch
        bne             .Prompt5
2311
        lda             BASIC_SESSION
2312
        cmp             #0
2313
        bne             .bsess1
2314
        inc             BASIC_SESSION
2315
;       lda             #3                              ; priority level 3
2316
;       ldy             #$F000                  ; start address $F000
2317
;       ldx             #$00000000              ; flags:
2318
;       jmp             (y)
2319
;       jsr             ($FFFFC004>>2)          ; StartTask
2320
;       mStartTask      #PRI_LOW,#0,#$F000,#0,#0
2321
        lda             #PRI_LOW
2322
        ldx             #0
2323
        ldy             #$F000
2324
        ld              r4,#0
2325
        ld              r5,#3
2326
        int             #4
2327
        db              1
2328 26 robfinch
        bra             Monitor
2329 39 robfinch
.bsess1:
2330
        inc             BASIC_SESSION
2331
        ldx             #$3000
2332
        ldy             #$4303000
2333
        asl             r1,r1,#14               ; * 16kW
2334
        add             r3,r3,r1
2335
        phy
2336
        lda             #4095                   ; 4096 words to copy
2337
        mvn                                             ; copy BASIC ROM
2338
        ply
2339
        asl             r3,r3,#2                ; convert to code address
2340
        add             r3,r3,#$3000    ; xxxx_F000
2341
        lda             #3
2342
        ldx             #$00000000              ; zero flags at startup
2343
        jsr             ($FFFFC004>>2)  ; StartTask
2344
        bra             Monitor
2345 15 robfinch
        emm
2346
        cpu             W65C02
2347
        jml             $0C000
2348
        cpu             rtf65002
2349 39 robfinch
.Prompt5:
2350 15 robfinch
        cmp             #'J'                    ; $J - execute code
2351
        beq             ExecuteCode
2352 26 robfinch
        cmp             #'L'                    ; $L - load dector
2353 39 robfinch
        beq             LoadBlock
2354 26 robfinch
        cmp             #'W'
2355 39 robfinch
        beq             WriteBlock
2356
.Prompt9:
2357 15 robfinch
        cmp             #'?'                    ; $? - display help
2358 39 robfinch
        bne             .Prompt10
2359 15 robfinch
        lda             #HelpMsg
2360
        jsr             DisplayStringB
2361
        jmp             Monitor
2362 39 robfinch
.Prompt10:
2363 15 robfinch
        cmp             #'C'                    ; $C - clear screen
2364
        beq             TestCLS
2365 26 robfinch
        cmp             #'r'
2366 39 robfinch
        bne             .Prompt12
2367 26 robfinch
        lda             #4                              ; priority level 4
2368
        ldx             #0                              ; zero all flags at startup
2369
        ldy             #RandomLines    ; task address
2370 39 robfinch
        jsr             (y)
2371
;       jsr             StartTask
2372
;       jsr             ($FFFFC004>>2)  ; StartTask
2373 26 robfinch
        jmp             Monitor
2374
;       jmp             RandomLinesCall
2375 39 robfinch
.Prompt12:
2376
.Prompt13:
2377 15 robfinch
        cmp             #'P'
2378 39 robfinch
        bne             .Prompt14
2379
        mStartTask      #PRI_NORMAL,#0,#Piano,#0,#2
2380 31 robfinch
        jmp             Monitor
2381 34 robfinch
 
2382 39 robfinch
.Prompt14:
2383 15 robfinch
        cmp             #'T'
2384 39 robfinch
        bne             .Prompt15
2385 34 robfinch
        jsr             MonGetch
2386
        cmp             #'O'
2387 39 robfinch
        bne             .Prompt14a
2388 34 robfinch
        jsr             DumpTimeoutList
2389
        jmp             Monitor
2390 39 robfinch
.Prompt14a:
2391 34 robfinch
        cmp             #'I'
2392 39 robfinch
        bne             .Prompt14b
2393 34 robfinch
        jsr             DisplayDatetime
2394
        jmp             Monitor
2395 39 robfinch
.Prompt14b:
2396 34 robfinch
        cmp             #'E'
2397 39 robfinch
        bne             .Prompt14c
2398 34 robfinch
        jsr             ReadTemp
2399
        jmp             Monitor
2400 39 robfinch
.Prompt14c:
2401 34 robfinch
        dey
2402 26 robfinch
        jsr             DumpTaskList
2403
        jmp             Monitor
2404 34 robfinch
 
2405 39 robfinch
.Prompt15:
2406 15 robfinch
        cmp             #'S'
2407 39 robfinch
        bne             .Prompt16
2408 34 robfinch
        jsr             MonGetch
2409 28 robfinch
        cmp             #'P'
2410 39 robfinch
        bne             .Prompt18
2411 28 robfinch
        jsr             ignBlanks
2412
        jsr             GetHexNumber
2413
        sta             SPSave
2414
        jmp             Monitor
2415 39 robfinch
.Prompt18:
2416
        cmp             #'U'
2417
        bne             .Prompt18a
2418
;       jsl             $F500
2419
        mStartTask      #PRI_HIGH,#0,#$F500,#0,#6
2420
;       lda             #PRI_HIGH
2421
;       ldx             #0
2422
;       ldy             #$F500
2423
;       ld              r4,#0
2424
;       ld              r5,#6
2425
;       int             #4
2426
;       db              1
2427
        jmp             Monitor
2428
.Prompt18a:
2429 28 robfinch
        dey
2430 39 robfinch
        jsr             SDInit
2431 15 robfinch
        cmp             #0
2432
        bne             Monitor
2433 39 robfinch
        jsr             SDReadPart
2434 15 robfinch
        cmp             #0
2435
        bne             Monitor
2436 39 robfinch
        jsr             SDReadBoot
2437 15 robfinch
        cmp             #0
2438
        bne             Monitor
2439
        jsr             loadBootFile
2440
        jmp             Monitor
2441 39 robfinch
.Prompt16:
2442 26 robfinch
        cmp             #'e'
2443 39 robfinch
        bne             .Prompt17
2444
;       lda             #1
2445
;       ldx             #0
2446
;       ldy             #eth_main
2447
;       jsr             StartTask
2448
        mStartTask      #PRI_HIGH,#0,#eth_main,#0,#0
2449 34 robfinch
;       jsr             eth_main
2450
        jmp             Monitor
2451 39 robfinch
.Prompt17:
2452 26 robfinch
        cmp             #'R'
2453 39 robfinch
        bne             .Prompt19
2454 34 robfinch
        jsr             MonGetch
2455 26 robfinch
        cmp             #'S'
2456 39 robfinch
        beq             LoadBlock
2457 26 robfinch
        dey
2458
        bra             SetRegValue
2459 15 robfinch
        jmp             Monitor
2460 39 robfinch
.Prompt19:
2461 34 robfinch
        cmp             #'K'
2462 39 robfinch
        bne             .Prompt20
2463
.Prompt19a:
2464 34 robfinch
        jsr             MonGetch
2465
        cmp             #' '
2466 39 robfinch
        bne             .Prompt19a
2467 34 robfinch
        jsr             ignBlanks
2468
        jsr             GetDecNumber
2469
        jsr             KillTask
2470
        jmp             Monitor
2471 39 robfinch
.Prompt20:
2472
        cmp             #'8'
2473
        bne             .Prompt21
2474
        jsr             Test816
2475
        jmp             Monitor
2476
.Prompt21:
2477
        cmp             #'m'
2478
        bne             Monitor
2479
;       lda             #3
2480
;       ldx             #0
2481
;       ldy             #test_mbx_prg
2482
;       jsr             StartTask
2483
        lda             #PRI_LOW
2484
        ldx             #0
2485
        ldy             #test_mbx_prg
2486
        ld              r4,#0
2487
        ld              r5,#1           ; Job 1!
2488
        int             #4
2489
        db              1
2490
        bra             Monitor
2491 34 robfinch
 
2492 15 robfinch
message "Prompt16"
2493
RandomLinesCall:
2494 26 robfinch
;       jsr             RandomLines
2495 15 robfinch
        jmp             Monitor
2496
 
2497 34 robfinch
MonGetch:
2498
        lda             (y)
2499
        iny
2500
        jsr             ScreenToAscii
2501
        rts
2502
 
2503 31 robfinch
DoDir:
2504
        jsr             do_dir
2505
        jmp             Monitor
2506
DoFmt:
2507
        jsr             do_fmt
2508
        jmp             Monitor
2509 34 robfinch
DoFig:
2510
        lda             #3                              ; priority level 3
2511
        ldy             #$A000                  ; start address $A000
2512
        ldx             #$20000000              ; flags: emmulation mode set
2513
        jsr             StartTask
2514
        bra             Monitor
2515
 
2516 15 robfinch
TestCLS:
2517 34 robfinch
        jsr             MonGetch
2518 15 robfinch
        cmp             #'L'
2519
        bne             Monitor
2520 34 robfinch
        jsr             MonGetch
2521 15 robfinch
        cmp             #'S'
2522
        bne             Monitor
2523
        jsr     ClearScreen
2524 39 robfinch
        jsr             HomeCursor
2525
;       jsr             CalcScreenLoc
2526 15 robfinch
        jmp             Monitor
2527 26 robfinch
message "HelpMsg"
2528 15 robfinch
HelpMsg:
2529
        db      "? = Display help",CR,LF
2530
        db      "CLS = clear screen",CR,LF
2531
        db      "S = Boot from SD Card",CR,LF
2532 39 robfinch
        db      "SU = supermon816",CR,LF
2533
        db      "L = Load Block",CR,LF
2534
        db      "W = Write Block",CR,LF
2535
        db  "DIR = Disk directory",CR,LF
2536
        db      "M = Dump memory words, MB = Dump memory bytes",CR,LF
2537
        db      "> = Edit memory words",CR,LF
2538 15 robfinch
        db      "F = Fill memory",CR,LF
2539 28 robfinch
        db  "FL = Dump I/O Focus List",CR,LF
2540 34 robfinch
;       db  "FIG = start FIG Forth",CR,LF
2541
        db      "KILL n = kill task #n",CR,LF
2542 15 robfinch
        db      "B = start tiny basic",CR,LF
2543
        db      "b = start EhBasic 6502",CR,LF
2544
        db      "J = Jump to code",CR,LF
2545 39 robfinch
        db      "R = Dump registers, Rn = Set register value",CR,LF
2546 26 robfinch
        db      "r = random lines - test bitmap",CR,LF
2547
        db      "e = ethernet test",CR,LF
2548
        db      "T = Dump task list",CR,LF
2549 34 robfinch
        db      "TO = Dump timeout list",CR,LF
2550
        db      "TI = display date/time",CR,LF
2551
        db      "TEMP = display temperature",CR,LF
2552 39 robfinch
        db      "P = Piano",CR,LF
2553
        db      "8 = 816 test",CR,LF,0
2554 15 robfinch
 
2555
;------------------------------------------------------------------------------
2556
; Ignore blanks in the input
2557
; r3 = text pointer
2558
; r1 destroyed
2559
;------------------------------------------------------------------------------
2560
;
2561
ignBlanks:
2562
ignBlanks1:
2563 34 robfinch
        jsr             MonGetch
2564 15 robfinch
        cmp             #' '
2565
        beq             ignBlanks1
2566
        dey
2567
        rts
2568
 
2569
;------------------------------------------------------------------------------
2570
; Edit memory byte(s).
2571
;------------------------------------------------------------------------------
2572
;
2573
EditMem:
2574
        jsr             ignBlanks
2575
        jsr             GetHexNumber
2576 39 robfinch
        ld              r5,r1
2577 15 robfinch
        ld              r4,#3
2578
edtmem1:
2579
        jsr             ignBlanks
2580
        jsr             GetHexNumber
2581
        sta             (r5)
2582
        add             r5,r5,#1
2583
        dec             r4
2584
        bne             edtmem1
2585
        jmp             Monitor
2586
 
2587
;------------------------------------------------------------------------------
2588
; Execute code at the specified address.
2589
;------------------------------------------------------------------------------
2590
;
2591 26 robfinch
message "ExecuteCode"
2592 15 robfinch
ExecuteCode:
2593
        jsr             ignBlanks
2594
        jsr             GetHexNumber
2595 18 robfinch
        st              r1,JMPTMP
2596
        lda             #xcret                  ; push return address so we can do an indirect jump
2597
        pha
2598
        ld              r1,R1Save
2599
        ld              r2,R2Save
2600
        ld              r3,R3Save
2601
        ld              r4,R4Save
2602
        ld              r5,R5Save
2603
        ld              r6,R6Save
2604
        ld              r7,R7Save
2605
        ld              r8,R8Save
2606
        ld              r9,R9Save
2607
        ld              r10,R10Save
2608
        ld              r11,R11Save
2609
        ld              r12,R12Save
2610
        ld              r13,R13Save
2611
        ld              r14,R14Save
2612
        ld              r15,R15Save
2613
        jmp             (JMPTMP)
2614
xcret:
2615
        php
2616
        st              r1,R1Save
2617
        st              r2,R2Save
2618
        st              r3,R3Save
2619
        st              r4,R4Save
2620
        st              r5,R5Save
2621
        st              r6,R6Save
2622
        st              r7,R7Save
2623
        st              r8,R8Save
2624
        st              r9,R9Save
2625
        st              r10,R10Save
2626
        st              r11,R11Save
2627
        st              r12,R12Save
2628
        st              r13,R13Save
2629
        st              r14,R14Save
2630
        st              r15,R15Save
2631
        tsr             sp,r1
2632 28 robfinch
        st              r1,SPSave
2633 18 robfinch
        tsr             sp8,r1
2634 28 robfinch
        st              r1,SP8Save
2635 18 robfinch
        pla
2636
        sta             SRSave
2637 15 robfinch
        jmp     Monitor
2638
 
2639 39 robfinch
LoadBlock:
2640 15 robfinch
        jsr             ignBlanks
2641 26 robfinch
        jsr             GetDecNumber
2642
        pha
2643
        jsr             ignBlanks
2644 15 robfinch
        jsr             GetHexNumber
2645 26 robfinch
        tax
2646
        phx
2647
;       ld              r2,#0x3800
2648 39 robfinch
        lda             #16                             ; SD Card device #
2649
        ldx             #1                              ; Init
2650
        jsr             DeviceOp
2651
;       jsr             SDInit
2652 26 robfinch
        plx
2653
        pla
2654 39 robfinch
        lda             #16                             ; SD Card device #
2655
        ldx             #11                             ; opcode: Read blocks
2656
        pop             r5                              ; r5 = pointer to data storage area
2657
        ply                                             ; y = block number to read
2658
        ld              r4,#1                   ; 1 block to read
2659
        jsr             DeviceOp
2660
;       jsr             SDReadSector
2661 15 robfinch
        jmp             Monitor
2662
 
2663 39 robfinch
WriteBlock:
2664 26 robfinch
        jsr             ignBlanks
2665
        jsr             GetDecNumber
2666
        pha
2667
        jsr             ignBlanks
2668
        jsr             GetHexNumber
2669
        tax
2670
        phx
2671 39 robfinch
        jsr             SDInit
2672 26 robfinch
        plx
2673
        pla
2674 39 robfinch
        jsr             SDWriteSector
2675 26 robfinch
        jmp             Monitor
2676
 
2677 15 robfinch
;------------------------------------------------------------------------------
2678 39 robfinch
; Command 'R'
2679 18 robfinch
; Dump the register set.
2680
;------------------------------------------------------------------------------
2681 26 robfinch
message "DumpReg"
2682 18 robfinch
DumpReg:
2683
        ldy             #0
2684
DumpReg1:
2685
        jsr             CRLF
2686 39 robfinch
        lda             #'$'
2687 18 robfinch
        jsr             DisplayChar
2688
        lda             #'R'
2689
        jsr             DisplayChar
2690 26 robfinch
        ldx             #1
2691 18 robfinch
        tya
2692 26 robfinch
        ina
2693 18 robfinch
        jsr             PRTNUM
2694
        lda             #' '
2695
        jsr             DisplayChar
2696
        lda             R1Save,y
2697
        jsr             DisplayWord
2698
        iny
2699
        cpy             #15
2700
        bne             DumpReg1
2701
        jsr             CRLF
2702
        lda             #':'
2703
        jsr             DisplayChar
2704
        lda             #'S'
2705
        jsr             DisplayChar
2706
        lda             #'P'
2707
        jsr             DisplayChar
2708
        lda             #' '
2709
        jsr             DisplayChar
2710 26 robfinch
        lda             TCB_SPSave
2711 18 robfinch
        jsr             DisplayWord
2712
        jsr             CRLF
2713 26 robfinch
        jmp             Monitor
2714 39 robfinch
 
2715 26 robfinch
;------------------------------------------------------------------------------
2716 39 robfinch
; Command 'Rn'
2717 26 robfinch
;------------------------------------------------------------------------------
2718
SetRegValue:
2719
        jsr             GetDecNumber
2720 39 robfinch
        cmp             #0
2721
        beq             DumpReg
2722 26 robfinch
        cmp             #15
2723
        bpl             Monitor
2724
        pha
2725
        jsr             ignBlanks
2726
        jsr             GetHexNumber
2727
        ply
2728
        sta             R1Save,y
2729
        jmp             Monitor
2730 39 robfinch
 
2731 18 robfinch
;------------------------------------------------------------------------------
2732 15 robfinch
;------------------------------------------------------------------------------
2733 39 robfinch
GetTwoParams:
2734 15 robfinch
        jsr             ignBlanks
2735
        jsr             GetHexNumber    ; get start address of dump
2736
        tax
2737
        jsr             ignBlanks
2738 39 robfinch
        jsr             GetHexNumber    ; get end address of dump
2739
        rts
2740
 
2741
;------------------------------------------------------------------------------
2742
; Get a range, the end must be greater or equal to the start.
2743
;------------------------------------------------------------------------------
2744
GetRange:
2745
        jsr             GetTwoParams
2746
        cmp             r2,r1
2747
        bhi             DisplayErr
2748
        rts
2749
 
2750
;------------------------------------------------------------------------------
2751
; Command 'M'
2752
; Do a memory dump of the requested location.
2753
;------------------------------------------------------------------------------
2754
;
2755
DumpMem:
2756
        jsr             GetRange
2757 15 robfinch
        jsr             CRLF
2758
DumpmemW:
2759 39 robfinch
        jsr             CheckKeys
2760 15 robfinch
        jsr             DisplayMemW
2761 39 robfinch
        cmp             r2,r1
2762
        bls             DumpmemW
2763 15 robfinch
        jmp             Monitor
2764
 
2765 39 robfinch
DumpMemBytes:
2766
        jsr             GetRange
2767
        jsr             CRLF
2768
.001:
2769
        jsr             CheckKeys
2770
        jsr             DisplayMemBytes
2771
        cmp             r2,r1
2772
        bls             .001
2773
        jmp             Monitor
2774 15 robfinch
 
2775 39 robfinch
;------------------------------------------------------------------------------
2776
; CheckKeys:
2777
;       Checks for a CTRLC or a scroll lock during long running dumps.
2778
;------------------------------------------------------------------------------
2779
CheckKeys:
2780
        jsr             CTRLCCheck
2781
        jmp             CheckScrollLock
2782
 
2783
;------------------------------------------------------------------------------
2784
; CTRLCCheck
2785
;       Checks to see if CTRL-C is pressed. If so then the current routine is
2786
; aborted and control is returned to the monitor.
2787
;------------------------------------------------------------------------------
2788
 
2789
CTRLCCheck:
2790
        pha
2791
        jsr             KeybdGetChar
2792
        cmp             #CTRLC
2793
        beq             .0001
2794
        pla
2795
        rts
2796
.0001:
2797
        pla
2798
        pla
2799
        jmp             Monitor
2800
 
2801
;------------------------------------------------------------------------------
2802
; CheckScrollLock:
2803
;       Check for a scroll lock by the user. If scroll lock is active then tasks
2804
; are rescheduled while the scroll lock state is tested in a loop.
2805
;------------------------------------------------------------------------------
2806
 
2807
CheckScrollLock:
2808
        pha
2809
.0002:
2810
        jsr             GetPtrCurrentJCB
2811
        lda             JCB_KeybdLocks,r1
2812
        bit             #$4000                          ; is scroll lock active ?
2813
        beq             .0001
2814
        int             #2                                      ; reschedule tasks
2815
        bra             .0002
2816
.0001:
2817
        pla
2818
        rts
2819
 
2820
 
2821
;------------------------------------------------------------------------------
2822
; Command 'F' or "FB"
2823
; Fill memory with specified value.
2824
;------------------------------------------------------------------------------
2825
 
2826 15 robfinch
FillMem:
2827 39 robfinch
        jsr             GetRange
2828
        txy                                             ; y = start address
2829
        sub             r1,r1,r2                ; acc = count
2830
        pha
2831 15 robfinch
        jsr             ignBlanks
2832 39 robfinch
        jsr             GetHexNumber    ; get the fill byte
2833 15 robfinch
        tax
2834 39 robfinch
        pla
2835
        stos
2836
        jmp             Monitor
2837
 
2838
FillMemBytes:
2839
        jsr             GetRange
2840
        txy
2841
        sub             r2,r1,r2                ; x = count
2842
        inx
2843 15 robfinch
        jsr             ignBlanks
2844 39 robfinch
        jsr             GetHexNumber
2845
.0001:
2846
        sb              r1,0,y
2847
        iny
2848
        dex
2849
        bne             .0001
2850 15 robfinch
        jmp             Monitor
2851
 
2852 39 robfinch
 
2853 15 robfinch
;------------------------------------------------------------------------------
2854
; Get a hexidecimal number. Maximum of eight digits.
2855
; R3 = text pointer (updated)
2856
; R1 = hex number
2857
;------------------------------------------------------------------------------
2858
;
2859
GetHexNumber:
2860
        phx
2861
        push    r4
2862
        ldx             #0
2863
        ld              r4,#8
2864
gthxn2:
2865 34 robfinch
        jsr             MonGetch
2866 15 robfinch
        jsr             AsciiToHexNybble
2867
        cmp             #-1
2868
        beq             gthxn1
2869 18 robfinch
        asl             r2,r2,#4
2870 15 robfinch
        and             #$0f
2871
        or              r2,r2,r1
2872
        dec             r4
2873
        bne             gthxn2
2874
gthxn1:
2875
        txa
2876
        pop             r4
2877
        plx
2878
        rts
2879
 
2880 26 robfinch
GetDecNumber:
2881
        phx
2882
        push    r4
2883
        push    r5
2884
        ldx             #0
2885
        ld              r4,#10
2886
        ld              r5,#10
2887
gtdcn2:
2888 34 robfinch
        jsr             MonGetch
2889 26 robfinch
        jsr             AsciiToDecNybble
2890
        cmp             #-1
2891
        beq             gtdcn1
2892
        mul             r2,r2,r5
2893
        add             r2,r2,r1
2894
        dec             r4
2895
        bne             gtdcn2
2896
gtdcn1:
2897
        txa
2898
        pop             r5
2899
        pop             r4
2900
        plx
2901
        rts
2902
 
2903 15 robfinch
;------------------------------------------------------------------------------
2904
; Convert ASCII character in the range '0' to '9', 'a' to 'f' or 'A' to 'F'
2905
; to a hex nybble.
2906
;------------------------------------------------------------------------------
2907
;
2908
AsciiToHexNybble:
2909
        cmp             #'0'
2910
        bcc             gthx3
2911
        cmp             #'9'+1
2912
        bcs             gthx5
2913
        sub             #'0'
2914
        rts
2915
gthx5:
2916
        cmp             #'A'
2917
        bcc             gthx3
2918
        cmp             #'F'+1
2919
        bcs             gthx6
2920
        sub             #'A'
2921
        add             #10
2922
        rts
2923
gthx6:
2924
        cmp             #'a'
2925
        bcc             gthx3
2926
        cmp             #'z'+1
2927
        bcs             gthx3
2928
        sub             #'a'
2929
        add             #10
2930
        rts
2931
gthx3:
2932
        lda             #-1             ; not a hex number
2933
        rts
2934
 
2935 26 robfinch
AsciiToDecNybble:
2936
        cmp             #'0'
2937
        bcc             gtdc3
2938
        cmp             #'9'+1
2939
        bcs             gtdc3
2940
        sub             #'0'
2941
        rts
2942
gtdc3:
2943
        lda             #-1
2944
        rts
2945
 
2946 39 robfinch
DisplayErr:
2947
        lda             #msgErr
2948
        jsr             DisplayStringB
2949
        jmp             Monitor
2950 26 robfinch
 
2951 39 robfinch
msgErr:
2952
        db      "**Err",CR,LF,0
2953
 
2954
;==============================================================================
2955
;==============================================================================
2956
 
2957 15 robfinch
;------------------------------------------------------------------------------
2958
;------------------------------------------------------------------------------
2959 11 robfinch
ClearBmpScreen:
2960
        pha
2961
        phx
2962
        phy
2963 39 robfinch
        lda             #(680*384)              ; a = # bytes to clear
2964 34 robfinch
        ldx             #0x29292929                     ; acc = color for four pixels
2965 39 robfinch
        ldy             #BITMAPSCR;<<2          ; y = screen address
2966
cbmp1:
2967
;       tsr             LFSR,r2
2968
;       sb              r2,0,y
2969
;       iny
2970
;       dea
2971
;       bne             cbmp1
2972 34 robfinch
        stos
2973 11 robfinch
        ply
2974
        plx
2975
        pla
2976
        rts
2977
 
2978
;==============================================================================
2979
;==============================================================================
2980 28 robfinch
;--------------------------------------------------------------------------
2981
; Setup the AC97/LM4550 audio controller. Check keyboard for a CTRL-C
2982
; interrupt which may be necessary if the audio controller isn't
2983
; responding.
2984
;--------------------------------------------------------------------------
2985 11 robfinch
;
2986 28 robfinch
SetupAC97:
2987
        pha
2988
        phx
2989
        phy
2990
        push    r4
2991
        ld              r4,Milliseconds
2992
sac974:
2993
        stz             AC97+0x26               ; trigger a read of register 26 (status reg)
2994
sac971:                                         ; wait for status to register 0xF (all ready)
2995
        ld              r3,Milliseconds
2996
        sub             r3,r3,r4
2997
        cmp             r3,#1000
2998 34 robfinch
        bhi             sac97Abort
2999 28 robfinch
        jsr             KeybdGetChar    ; see if we needed to CTRL-C
3000
        cmp             #CTRLC
3001
        beq             sac973
3002
        lda             AC97+0x68               ; wait for dirty bit to clear
3003
        bne             sac971
3004
        lda             AC97+0x26               ; check status at reg h26, wait for
3005
        and             #0x0F                   ; analogue to be ready
3006
        cmp             #$0F
3007
        bne             sac974
3008
sac973:
3009
        stz             AC97+2                  ; master volume, 0db attenuation, mute off
3010
        stz             AC97+4                  ; headphone volume, 0db attenuation, mute off
3011
        stz             AC97+0x18               ; PCM gain (mixer) mute off, no attenuation
3012
        stz             AC97+0x0A               ; mute PC beep
3013
        lda             #0x8000                 ; bypass 3D sound
3014
        sta             AC97+0x20
3015
        ld              r4,Milliseconds
3016
sac972:
3017
        ld              r3,Milliseconds
3018
        sub             r3,r3,r4
3019
        cmp             r3,#1000
3020 34 robfinch
        bhi             sac97Abort
3021 28 robfinch
        jsr             KeybdGetChar
3022
        cmp             #CTRLC
3023
        beq             sac975
3024
        lda             AC97+0x68               ; wait for dirty bits to clear
3025
        bne             sac972                  ; wait a while for the settings to take effect
3026
sac975:
3027
        pop             r4
3028
        ply
3029
        plx
3030
        pla
3031
        rts
3032
sac97Abort:
3033
        lda             #msgAC97bad
3034
        jsr             DisplayStringCRLFB
3035
        pop             r4
3036
        ply
3037
        plx
3038
        pla
3039
        rts
3040
 
3041
msgAC97bad:
3042
        db      "The AC97 controller is not responding.",CR,LF,0
3043
 
3044
;--------------------------------------------------------------------------
3045
; Sound a 800 Hz beep
3046
;--------------------------------------------------------------------------
3047
;
3048
Beep:
3049 39 robfinch
        lda             #2                              ; check for a PSG
3050
        bmt             CONFIGREC
3051
        beq             .ret
3052 28 robfinch
        lda             #15                             ; master volume to max
3053 34 robfinch
        sta             PSG+64
3054 28 robfinch
        lda             #13422                  ; 800Hz
3055
        sta             PSGFREQ0
3056
        ; decay  (16.384 ms)2
3057
        ; attack (8.192 ms)1
3058
        ; release (1.024 s)A
3059
        ; sustain level C
3060
        lda             #0xCA12
3061
        sta             PSGADSR0
3062
        lda             #0x1104                 ; gate, output enable, triangle waveform
3063
        sta             PSGCTRL0
3064 39 robfinch
;       lda             #1000                   ; delay about 1s
3065
        mSleep  #1000
3066 28 robfinch
        lda             #0x0104                 ; gate off, output enable, triangle waveform
3067
        sta             PSGCTRL0
3068 39 robfinch
;       lda             #1000                   ; delay about 1s
3069
        mSleep  #1000
3070 34 robfinch
        lda             #83
3071
        sta             LEDS
3072 28 robfinch
        lda             #0x0000                 ; gate off, output enable off, no waveform
3073
        sta             PSGCTRL0
3074 39 robfinch
.ret
3075 28 robfinch
        rts
3076
 
3077 39 robfinch
include "Piano.asm"
3078
include "SDCard.asm"
3079 28 robfinch
 
3080 15 robfinch
; Load the root directory from disk
3081
; r2 = where to place root directory in memory
3082
;
3083
loadBootFile:
3084 31 robfinch
        lb              r1,BYTE_SECTOR_BUF+BSI_SecPerFAT+1                      ; sectors per FAT
3085 18 robfinch
        asl             r1,r1,#8
3086 31 robfinch
        orb             r1,r1,BYTE_SECTOR_BUF+BSI_SecPerFAT
3087 15 robfinch
        bne             loadBootFile7
3088
        lb              r1,BYTE_SECTOR_BUF+$27                  ; sectors per FAT, FAT32
3089 18 robfinch
        asl             r1,r1,#8
3090 15 robfinch
        orb             r1,r1,BYTE_SECTOR_BUF+$26
3091 18 robfinch
        asl             r1,r1,#8
3092 15 robfinch
        orb             r1,r1,BYTE_SECTOR_BUF+$25
3093 18 robfinch
        asl             r1,r1,#8
3094 15 robfinch
        orb             r1,r1,BYTE_SECTOR_BUF+$24
3095
loadBootFile7:
3096
        lb              r4,BYTE_SECTOR_BUF+$10                  ; number of FATs
3097
        mul             r3,r1,r4                                                ; offset
3098
        lb              r1,BYTE_SECTOR_BUF+$F                   ; r1 = # reserved sectors before FAT
3099 18 robfinch
        asl             r1,r1,#8
3100 15 robfinch
        orb             r1,r1,BYTE_SECTOR_BUF+$E
3101
        add             r3,r3,r1                                                ; r3 = root directory sector number
3102
        ld              r6,startSector
3103
        add             r5,r3,r6                                                ; r5 = root directory sector number
3104
        lb              r1,BYTE_SECTOR_BUF+$D                   ; sectors per cluster
3105
        add             r3,r1,r5                                                ; r3 = first cluster after first cluster of directory
3106
        bra             loadBootFile6
3107
 
3108
loadBootFile6:
3109
        ; For now we cheat and just go directly to sector 512.
3110
        bra             loadBootFileTmp
3111
 
3112
loadBootFileTmp:
3113
        ; We load the number of sectors per cluster, then load a single cluster of the file.
3114
        ; This is 16kib
3115
        ld              r5,r3                                                   ; r5 = start sector of data area
3116
        ld              r2,#PROG_LOAD_AREA                              ; where to place file in memory
3117
        lb              r3,BYTE_SECTOR_BUF+$D                   ; sectors per cluster
3118
loadBootFile1:
3119
        ld              r1,r5                                                   ; r1=sector to read
3120 39 robfinch
        jsr             SDReadSector
3121 15 robfinch
        inc             r5                                              ; r5 = next sector
3122
        add             r2,r2,#512
3123
        dec             r3
3124
        bne             loadBootFile1
3125 26 robfinch
        lda             PROG_LOAD_AREA>>2               ; make sure it's bootable
3126 15 robfinch
        cmp             #$544F4F42
3127
        bne             loadBootFile2
3128
        lda             #msgJumpingToBoot
3129
        jsr             DisplayStringB
3130 26 robfinch
        lda             (PROG_LOAD_AREA>>2)+$1
3131 15 robfinch
        jsr             (r1)
3132
        jmp             Monitor
3133
loadBootFile2:
3134
        lda             #msgNotBootable
3135
        jsr             DisplayStringB
3136
        ldx             #PROG_LOAD_AREA>>2
3137
        jsr             DisplayMemW
3138
        jsr             DisplayMemW
3139
        jsr             DisplayMemW
3140
        jsr             DisplayMemW
3141
        jmp             Monitor
3142
 
3143 11 robfinch
msgJumpingToBoot:
3144
        db      "Jumping to boot",0
3145
msgNotBootable:
3146
        db      "SD card not bootable.",0
3147
spi_init_ok_msg:
3148
        db "SD card initialized okay.",0
3149
spi_init_error_msg:
3150
        db      ": error occurred initializing the SD card.",0
3151
spi_boot_error_msg:
3152 26 robfinch
        db      "SD card boot error",CR,LF,0
3153 11 robfinch
spi_read_error_msg:
3154 26 robfinch
        db      "SD card read error",CR,LF,0
3155 11 robfinch
spi_write_error_msg:
3156
        db      "SD card write error",0
3157
 
3158 31 robfinch
do_fmt:
3159 39 robfinch
        jsr             SDInit
3160 31 robfinch
        cmp             #0
3161
        bne             fmt_abrt
3162
        ; clear out the directory buffer
3163 39 robfinch
        lda             #65535
3164
        ldx             #0
3165
        ldy             #DIRBUF
3166
        stos
3167 31 robfinch
        jsr             store_dir
3168
fmt_abrt:
3169
        rts
3170
 
3171
do_dir:
3172
        jsr             CRLF
3173 39 robfinch
        jsr             SDInit
3174 31 robfinch
        cmp             #0
3175
        bne             dirabrt
3176
        jsr             load_dir
3177
        ld              r4,#0                   ; r4 = entry counter
3178
ddir3:
3179
        asl             r3,r4,#6                ; y = start of entry, 64 bytes per entry
3180
        ldx             #32                             ; 32 chars in filename
3181
ddir4:
3182
        lb              r1,DIRBUF<<2,y
3183
        beq             ddir2                   ; move to next dir entry if null is found
3184
        cmp             #$20                    ; don't display control chars
3185
        bmi             ddir1
3186
        jsr             DisplayChar
3187
        bra             ddir5
3188
ddir1:
3189
        lda             #' '
3190
        jsr             DisplayChar
3191
ddir5:
3192
        iny
3193
        dex
3194
        bne             ddir4
3195
        lda             #' '
3196
        jsr             DisplayChar
3197
        asl             r3,r4,#4                ; y = start of entry, 16 words per entry
3198
        lda             DIRBUF+$D,y
3199
        ldx             #5
3200
        jsr             PRTNUM
3201
        jsr             CRLF
3202
ddir2:
3203
        jsr             KeybdGetChar
3204
        cmp             #CTRLC
3205
        beq             ddir6
3206
        inc             r4
3207
        cmp             r4,#512         ; max 512 dir entries
3208
        bne             ddir3
3209
ddir6:
3210
 
3211
dirabrt:
3212
        rts
3213
 
3214
load_dir:
3215
        pha
3216
        phx
3217
        phy
3218
        lda             #4000
3219
        ldx             #DIRBUF<<2
3220
        ldy             #64
3221 39 robfinch
        jsr             SDReadMultiple
3222 31 robfinch
        ply
3223
        plx
3224
        pla
3225
        rts
3226
store_dir:
3227
        pha
3228
        phx
3229
        phy
3230
        lda             #4000
3231
        ldx             #DIRBUF<<2
3232
        ldy             #64
3233 39 robfinch
        jsr             SDWriteMultiple
3234 31 robfinch
        ply
3235
        plx
3236
        pla
3237
        rts
3238
 
3239
; r1 = pointer to file name
3240
; r2 = pointer to buffer to save
3241
; r3 = length of buffer
3242
;
3243
do_save:
3244
        pha
3245 39 robfinch
        jsr             SDInit
3246 31 robfinch
        cmp             #0
3247
        bne             dsavErr
3248
        pla
3249
        jsr             load_dir
3250
        ld              r4,#0
3251
dsav4:
3252
        asl             r5,r4,#6
3253
        ld              r7,#0
3254
        ld              r10,r1
3255
dsav2:
3256
        lb              r6,DIRBUF<<2,r5
3257
        lb              r8,0,r10
3258
        cmp             r6,r8
3259
        bne             dsav1
3260
        inc             r5
3261
        inc             r7
3262
        inc             r10
3263
        cmp             r7,#32
3264
        bne             dsav2
3265
        ; here the filename matched
3266
dsav8:
3267
        asl             r7,r4,#7        ; compute file address  64k * entry #
3268
        add             r7,r7,#5000     ; start at sector 5,000
3269
        ld              r1,r7           ; r1 = sector number
3270
        lsr             r3,r3,#9        ; r3/512
3271
        iny                                     ; +1
3272 39 robfinch
        jsr             SDWriteMultiple
3273 31 robfinch
dsav3:
3274
        rts
3275
        ; Here the filename didn't match
3276
dsav1:
3277
        inc             r4
3278
        cmp             r4,#512
3279
        bne             dsav4
3280
        ; Here none of the filenames in the directory matched
3281
        ; Find an empty entry.
3282
        ld              r4,#0
3283
dsav6:
3284
        asl             r5,r4,#6
3285
        lb              r6,DIRBUF<<2,r5
3286
        beq             dsav5
3287
        inc             r4
3288
        cmp             r4,#512
3289
        bne             dsav6
3290
        ; Here there were no empty entries
3291
        lda             #msgDiskFull
3292
        jsr             DisplayStringB
3293
        rts
3294
dsav5:
3295
        ld              r7,#32
3296
        ld              r10,r1
3297
dsav7:
3298
        lb              r6,0,r10        ; copy the filename into the directory entry
3299
        sb              r6,DIRBUF<<2,r5
3300
        inc             r5
3301
        inc             r10
3302
        dec             r7
3303
        bne             dsav7
3304
                                                ; copy the file size into the directory entry
3305
        asl             r5,r4,#4        ; 16 words per dir entry
3306
        sty             DIRBUF+$D,r5
3307
        jsr             store_dir
3308
        bra             dsav8
3309
dsavErr:
3310
        pla
3311
        rts
3312
 
3313
msgDiskFull
3314
        db      CR,LF,"The disk is full, unable to save file.",CR,LF,0
3315
 
3316
do_load:
3317
        pha
3318 39 robfinch
        jsr             SDInit
3319 31 robfinch
        cmp             #0
3320
        bne             dsavErr
3321
        pla
3322
        jsr             load_dir
3323
        ld              r4,#0
3324
dlod4:
3325
        asl             r5,r4,#6
3326
        ld              r7,#0
3327
        ld              r10,r1
3328
dlod2:
3329
        lb              r6,DIRBUF<<2,r5
3330
        lb              r8,0,r10
3331
        cmp             r6,r8
3332
        bne             dlod1
3333
        inc             r5
3334
        inc             r7
3335
        inc             r10
3336
        cmp             r7,#32
3337
        bne             dlod2
3338
        ; here the filename matched
3339
dlod8:
3340
        asl             r5,r4,#4                                ; 16 words
3341
        ld              r3,DIRBUF+$d,r5                 ; get file size into y register
3342
        asl             r7,r4,#7        ; compute file address  64k * entry #
3343
        add             r7,r7,#5000     ; start at sector 5,000
3344
        ld              r1,r7           ; r1 = sector number
3345
        lsr             r3,r3,#9        ; r3/512
3346
        iny                                     ; +1
3347 39 robfinch
        jsr             SDReadMultiple
3348 31 robfinch
dlod3:
3349
        rts
3350
        ; Here the filename didn't match
3351
dlod1:
3352
        inc             r4
3353
        cmp             r4,#512
3354
        bne             dlod4
3355
        ; Here none of the filenames in the directory matched
3356
        ;
3357
        lda             #msgFileNotFound
3358
        jsr             DisplayStringB
3359
        rts
3360
 
3361
msgFileNotFound:
3362
        db      CR,LF,"File not found.",CR,LF
3363 26 robfinch
 
3364 39 robfinch
;include "ethernet.asm"
3365 34 robfinch
 
3366 26 robfinch
;--------------------------------------------------------------------------
3367
; Initialize sprite image caches with random data.
3368
;--------------------------------------------------------------------------
3369 34 robfinch
message "RandomizeSprram"
3370 26 robfinch
RandomizeSprram:
3371
        ldx             #SPRRAM
3372
        ld              r4,#14336               ; number of chars to initialize
3373
rsr1:
3374
        tsr             LFSR,r1
3375
        sta             (x)
3376
        inx
3377
        dec             r4
3378
        bne             rsr1
3379
        rts
3380
 
3381
;include "float.asm"
3382 39 robfinch
include "RandomLines.asm"
3383 26 robfinch
 
3384 34 robfinch
;--------------------------------------------------------------------------
3385
; RTF65002 code to display the date and time from the date/time device.
3386
;--------------------------------------------------------------------------
3387
DisplayDatetime
3388
        pha
3389
        phx
3390
        lda             #' '
3391
        jsr             DisplayChar
3392
        stz             DATETIME_SNAPSHOT       ; take a snapshot of the running date/time
3393
        lda             DATETIME_DATE
3394
        tax
3395
        lsr             r1,r1,#16
3396
        jsr             DisplayHalf             ; display the year
3397
        lda             #'/'
3398
        jsr             DisplayChar
3399
        txa
3400
        lsr             r1,r1,#8
3401
        and             #$FF
3402
        jsr             DisplayByte             ; display the month
3403
        lda             #'/'
3404
        jsr             DisplayChar
3405
        txa
3406
        and             #$FF
3407
        jsr             DisplayByte             ; display the day
3408
        lda             #' '
3409
        jsr             DisplayChar
3410
        lda             #' '
3411
        jsr             DisplayChar
3412
        lda             DATETIME_TIME
3413
        tax
3414
        lsr             r1,r1,#24
3415
        jsr             DisplayByte             ; display hours
3416
        lda             #':'
3417
        jsr             DisplayChar
3418
        txa
3419
        lsr             r1,r1,#16
3420
        jsr             DisplayByte             ; display minutes
3421
        lda             #':'
3422
        jsr             DisplayChar
3423
        txa
3424
        lsr             r1,r1,#8
3425
        jsr             DisplayByte             ; display seconds
3426
        lda             #'.'
3427
        jsr             DisplayChar
3428
        txa
3429
        jsr             DisplayByte             ; display 100ths seconds
3430
        jsr             CRLF
3431
        plx
3432
        pla
3433
        rts
3434 31 robfinch
 
3435 39 robfinch
include "ReadTemp.asm"
3436 34 robfinch
 
3437 39 robfinch
include "memory.asm"
3438 34 robfinch
 
3439 15 robfinch
;------------------------------------------------------------------------------
3440 26 robfinch
; Bus Error Routine
3441
; This routine display a message then restarts the BIOS.
3442
;------------------------------------------------------------------------------
3443
;
3444
message "bus_err_rout"
3445
bus_err_rout:
3446
        cld
3447 34 robfinch
        ldx             #87
3448
        stx             LEDS
3449 26 robfinch
        pla                                                     ; get rid of the stacked flags
3450
        ply                                                     ; get the error PC
3451
        ldx             #$05FFFFF8                      ; setup stack pointer top of memory
3452
        txs
3453 34 robfinch
        ldx             #88
3454
        stx             LEDS
3455 26 robfinch
        jsr             CRLF
3456 34 robfinch
        stz             RunningTCB
3457 39 robfinch
        lda             #JCBs
3458
        sta             IOFocusNdx
3459 26 robfinch
        lda             #msgBusErr
3460
        jsr             DisplayStringB
3461
        tya
3462
        jsr             DisplayWord                     ; display the originating PC address
3463
        lda             #msgDataAddr
3464
        jsr             DisplayStringB
3465
        tsr             #9,r1
3466
        jsr             DisplayWord
3467 34 robfinch
        ldx             #89
3468
        stx             LEDS
3469
        ldx             #128
3470
ber2:
3471
        lda             #' '
3472
        jsr             DisplayChar
3473
        tsr             hist,r1
3474
        jsr             DisplayWord
3475
        dex
3476
        bne             ber2
3477
        jsr             CRLF
3478
ber3:
3479
        nop
3480
        jmp             ber3
3481
        ;cli                                                    ; enable interrupts so we can get a char
3482 28 robfinch
ber1:
3483 34 robfinch
        jsr             KeybdGetCharDirect      ; Don't use the keyboard buffer
3484 28 robfinch
        cmp             #-1
3485
        beq             ber1
3486 34 robfinch
        lda             RunningTCB
3487
        jsr             KillTask
3488
        jmp             SelectTaskToRun
3489 26 robfinch
 
3490
msgBusErr:
3491
        db              "Bus error at: ",0
3492
msgDataAddr:
3493
        db              " data address: ",0
3494
 
3495 34 robfinch
 
3496
;------------------------------------------------------------------------------
3497 15 robfinch
; 1000 Hz interrupt
3498
; This IRQ must be fast.
3499 26 robfinch
; Increments the millisecond counter
3500 15 robfinch
;------------------------------------------------------------------------------
3501 39 robfinch
message "p1000Hz"
3502 15 robfinch
p1000Hz:
3503 31 robfinch
        pha
3504
        lda             #2                                              ; reset edge sense circuit
3505
        sta             PIC_RSTE
3506 15 robfinch
        inc             Milliseconds                    ; increment milliseconds count
3507 31 robfinch
        pla
3508 15 robfinch
        rti
3509
 
3510 31 robfinch
;------------------------------------------------------------------------------
3511
; Sleep interrupt
3512
; This interrupt just selects another task to run. The current task is
3513
; stuck in an infinite loop.
3514
;------------------------------------------------------------------------------
3515 39 robfinch
message "slp_rout"
3516 15 robfinch
slp_rout:
3517 31 robfinch
        cld             ; clear extended precision mode
3518 34 robfinch
        pusha
3519
        lda             RunningTCB
3520
        cmp             #MAX_TASKNO
3521
        bhi             slp1
3522
        jsr             RemoveTaskFromReadyList
3523
        tax
3524 31 robfinch
        tsa                                             ; save off the stack pointer
3525
        sta             TCB_SPSave,x
3526
        tsr             sp8,r1                  ; and the eight bit mode stack pointer
3527
        sta             TCB_SP8Save,x
3528 34 robfinch
        tsr             abs8,r1
3529
        sta             TCB_ABS8Save,x
3530
        lda             #TS_SLEEP               ; set the task status to SLEEP
3531 31 robfinch
        sta             TCB_Status,x
3532
slp1:
3533
        jmp             SelectTaskToRun
3534
 
3535
;------------------------------------------------------------------------------
3536
; Check for and emulate unsupoorted instructions.
3537
;------------------------------------------------------------------------------
3538
InvalidOpIRQ:
3539
        pha
3540
        phx
3541
        phy
3542
        tsx
3543
        lda             4,x             ; get the address of the invalid op off the stack
3544
        lb              r3,0,r1 ; get the opcode byte
3545
        cpy             #$44    ; is it MVP ?
3546
        beq             EmuMVP
3547
        cpy             #$54    ; is it MVN ?
3548
        beq             EmuMVN
3549
        ; We don't know what the op is. Treat it like a NOP
3550
        ; Increment the address and return.
3551
        pha
3552
        lda             #msgUnimp
3553
        jsr             DisplayStringB
3554
        pla
3555
        jsr             DisplayWord
3556
        jsr             CRLF
3557
        ina
3558
        sta             4,x             ; save incremented return address back to stack
3559 39 robfinch
        jsr             DumpHistoryTable
3560
        ply
3561
        plx
3562
        pla
3563
        rti
3564
 
3565
DumpHistoryTable:
3566
        pha
3567
        phx
3568 31 robfinch
        ldx             #64
3569
ioi1:
3570 34 robfinch
        tsr             hist,r1
3571 31 robfinch
        jsr             DisplayWord
3572
        lda             #' '
3573
        jsr             DisplayChar
3574
        dex
3575
        bne             ioi1
3576
        plx
3577
        pla
3578 39 robfinch
        rts
3579 31 robfinch
 
3580
EmuMVP:
3581
        push    r4
3582
        push    r5
3583
        tsr             sp,r4
3584
        lda             4,r4
3585
        ldx             3,r4
3586
        ldy             2,r4
3587
EmuMVP1:
3588
        ld              r5,(x)
3589
        st              r5,(y)
3590
        dex
3591
        dey
3592
        dea
3593
        cmp             #$FFFFFFFF
3594
        bne             EmuMVP1
3595
        sta             4,r4
3596
        stx             3,r4
3597
        sty             2,r4
3598
        inc             6,r4            ; increment the return address by one.
3599
        pop             r5
3600
        pop             r4
3601
        ply
3602
        plx
3603
        pla
3604
        rti
3605
 
3606
EmuMVN:
3607
        push    r4
3608
        push    r5
3609
        tsr             sp,r4
3610
        lda             4,r4
3611
        ldx             3,r4
3612
        ldy             2,r4
3613
EmuMVN1:
3614
        ld              r5,(x)
3615
        st              r5,(y)
3616
        inx
3617
        iny
3618
        dea
3619
        cmp             #$FFFFFFFF
3620
        bne             EmuMVN1
3621
        sta             4,r4
3622
        stx             3,r4
3623
        sty             2,r4
3624
        inc             6,r4            ; increment the return address by one.
3625
        pop             r5
3626
        pop             r4
3627
        ply
3628
        plx
3629
        pla
3630
        rti
3631
 
3632
msgUnimp:
3633
        db      "Unimplemented at: ",0
3634
 
3635 15 robfinch
brk_rout:
3636 39 robfinch
        lda             #16
3637
        sta             LEDS
3638
        jsr             kernel_panic
3639
        db              "Break routine",0
3640
        jsr             DumpHistoryTable
3641
        stp
3642 15 robfinch
        rti
3643 39 robfinch
 
3644 31 robfinch
nmirout:
3645
        pha
3646
        lda             #msgPerr
3647
        jsr             DisplayStringB
3648 39 robfinch
        lda             3,sp
3649 31 robfinch
        jsr             DisplayWord
3650
        jsr             CRLF
3651
        pla
3652 11 robfinch
        rti
3653 31 robfinch
 
3654
msgPerr:
3655
        db      "Parity error at: ",0
3656
 
3657 39 robfinch
;==============================================================================
3658
; Finitron Multi-Tasking Kernel (FMTK)
3659
;        __
3660
;   \\__/ o\    (C) 2013, 2014  Robert Finch, Stratford
3661
;    \  __ /    All rights reserved.
3662
;     \/_//     robfinch@opencores.org
3663
;       ||
3664
;==============================================================================
3665
message "FMTK"
3666
        org             $FFFFC000
3667
syscall_vectors:
3668
        dw              MTKInitialize
3669
        dw              StartTask
3670
        dw              ExitTask
3671
        dw              KillTask
3672
        dw              SetTaskPriority
3673
        dw              Sleep
3674
        dw              AllocMbx
3675
        dw              FreeMbx
3676
        dw              PostMsg
3677
        dw              SendMsg
3678
        dw              WaitMsg
3679
        dw              CheckMsg
3680
 
3681
        org             $FFFFC200
3682
message "MTKInitialize"
3683
MTKInitialize:
3684
        ; Initialize semaphores
3685
        lda             #1
3686
        sta             freetcb_sema
3687
        sta             freembx_sema
3688
        sta             freemsg_sema
3689
        sta             tcb_sema
3690
        sta             readylist_sema
3691
        sta             tolist_sema
3692
        sta             mbx_sema
3693
        sta             msg_sema
3694
        sta             jcb_sema
3695
 
3696
        tsr             vbr,r2
3697
        and             r2,#-2
3698
        lda             #reschedule
3699
        sta             2,x
3700
        lda             #syscall_int
3701
        sta             4,x
3702
        lda             #MTKTick
3703
        sta             448+3,x
3704
        stz             UserTick
3705
 
3706
        lda             #-1
3707
        sta             TimeoutList             ; no entries in timeout list
3708
        sta             QNdx0
3709
        sta             QNdx1
3710
        sta             QNdx2
3711
        sta             QNdx3
3712
        sta             QNdx4
3713
 
3714
        stz             missed_ticks
3715
 
3716
        ; Initialize IO Focus List
3717
        ;
3718
        lda             #7
3719
        ldx             #0
3720
        ldy             #IOFocusTbl
3721
        stos
3722
 
3723
        ; Set owning job to zero (the monitor)
3724
        lda             #255
3725
        ldx             #0
3726
        ldy             #TCB_hJCB
3727
        stos
3728
 
3729
        ; zero out JCB's
3730
        ; This will NULL out the I/O focus list pointers
3731
        lda             #NR_JCB * JCB_Size
3732
        ldx             #0
3733
        lea             r3,JCBs
3734
        stos
3735
 
3736
        ; Setup default values in the JCB's
3737
        ldy             #0
3738
        ldx             #JCBs
3739
ijcb1:
3740
        sty             JCB_Number,x
3741
        sty             JCB_Map,x
3742
        stz             JCB_esc,x
3743
        lda             #31
3744
        sta             JCB_VideoRows,x
3745
        lda             #56
3746
        sta             JCB_VideoCols,x
3747
        lda             #1                                      ; turn on keyboard echo
3748
        sta             JCB_KeybdEcho,x
3749
        sta             JCB_CursorOn,x
3750
        sta             JCB_CursorFlash,x
3751
        stz             JCB_CursorRow,x
3752
        stz             JCB_CursorCol,x
3753
        stz             JCB_CursorType,x
3754
        lda             #%1011_01111            ; grey on grey
3755
        sta             JCB_NormAttr,x
3756
        sta             JCB_CurrAttr,x
3757
        ld              r4,r3
3758
        mul             r4,r4,#8192                     ; 8192 words per screen
3759
        add             r4,r4,#BIOS_SCREENS
3760
        st              r4,JCB_pVirtVid,x
3761
        st              r4,JCB_pVidMem,x
3762
        add             r4,r4,#$1000
3763
        st              r4,JCB_pVirtVidAttr,x
3764
        st              r4,JCB_pVidMemAttr,x
3765
        cpy             #0
3766
        bne             ijcb2
3767
        lda             #%0110_01110            ; CE =blue on blue FB = grey on grey
3768
        sta             JCB_NormAttr,x
3769
        sta             JCB_CurrAttr,x
3770
        ld              r4,#TEXTSCR
3771
        st              r4,JCB_pVidMem,x
3772
        add             r4,r4,#$10000
3773
        st              r4,JCB_pVidMemAttr,x
3774
ijcb2:
3775
        lda             #8
3776
        sta             JCB_LogSize,x
3777
        iny
3778
        add             r2,r2,#JCB_Size
3779
        cpy             #32
3780
        blo             ijcb1
3781
 
3782
 
3783
        ; Initialize free message list
3784
        lda             #NR_MSG
3785
        sta             nMsgBlk
3786
        stz             FreeMsg
3787
        ldx             #0
3788
        lda             #1
3789
st4:
3790
        sta             MSG_LINK,x
3791
        ina
3792
        inx
3793
        cpx             #NR_MSG
3794
        bne             st4
3795
        lda             #-1
3796
        sta             MBX_LINK+NR_MSG-1
3797
 
3798
        ; Initialize free mailbox list
3799
        ; Note the first NR_TCB mailboxes are statically allocated to the tasks.
3800
        ; They are effectively pre-allocated.
3801
        lda             #NR_MBX-NR_TCB
3802
        sta             nMailbox
3803
 
3804
        ldx             #NR_TCB
3805
        stx             FreeMbxHandle
3806
        lda             #NR_TCB+1
3807
st3:
3808
        sta             MBX_LINK,x
3809
        ina
3810
        inx
3811
        cpx             #NR_MBX
3812
        bne             st3
3813
        lda             #-1
3814
        sta             MBX_LINK+NR_MBX-1
3815
 
3816
        ; Initialize the FreeJCB list
3817
        lda             #JCBs+JCB_Size          ; the next available JCB
3818
        sta             FreeJCB
3819
        tax
3820
        add             r1,r1,#JCB_Size
3821
        ldy             #NR_JCB-1
3822
st5:
3823
        sta             JCB_Next,x
3824
        add             r1,r1,#JCB_Size
3825
        add             r2,r2,#JCB_Size
3826
        dey
3827
        bne             st5
3828
        stz             JCB_Next,x
3829
 
3830
        ; Initialize the FreeTCB list
3831
        lda             #1                              ; the next available TCB
3832
        sta             FreeTCB
3833
        ldx             #1
3834
        lda             #2
3835
st2:
3836
        sta             TCB_NxtTCB,x
3837
        ina
3838
        inx
3839
        cpx             #256
3840
        bne             st2
3841
        lda             #-1
3842
        sta             TCB_NxtTCB+255
3843
        lda             #4
3844
        sta             LEDS
3845
 
3846
        ; Manually setup the BIOS task
3847
        stz             RunningTCB              ; BIOS is task #0
3848
        stz             TCB_NxtRdy              ; manually build the ready list
3849
        stz             TCB_PrvRdy
3850
        lda             #-1
3851
        sta             TCB_NxtTo
3852
        sta             TCB_PrvTo
3853
        stz             QNdx2                   ; insert at priority 2
3854
        ; manually build the IO focus list
3855
        lda             #JCBs
3856
        sta             IOFocusNdx              ; Job #0 (Monitor) has the focus
3857
        stz             JCB_iof_next,r1
3858
        stz             JCB_iof_prev,r1
3859
        lda             #1
3860
        sta             IOFocusTbl              ; set the job #0 request bit
3861
 
3862
        lda             #PRI_NORMAL
3863
        sta             TCB_Priority
3864
        stz             TCB_Timeout
3865
        lda             #TS_RUNNING|TS_READY
3866
        sta             TCB_Status
3867
        stz             TCB_CursorRow
3868
        stz             TCB_CursorCol
3869
        stz             TCB_ABS8Save
3870
        ldx             #BIOS_STACKS+0x03FF     ; setup stack pointer top of memory
3871
        stx             TCB_SPSave
3872
        ldx             #$1FF
3873
        stx             TCB_SP8Save
3874
        rts
3875
 
3876
;------------------------------------------------------------------------------
3877
;------------------------------------------------------------------------------
3878
message "startIdleTask"
3879
StartIdleTask:
3880
        lda             #4
3881
        ldx             #0
3882
        ldy             #IdleTask
3883
        jsr             StartTask
3884
        rts
3885
 
3886
;------------------------------------------------------------------------------
3887
; IdleTask
3888
;
3889
; IdleTask is a low priority task that is always running. It runs when there
3890
; is nothing else to run.
3891
; This task check for tasks that are stuck in infinite loops and kills them.
3892
;------------------------------------------------------------------------------
3893
IdleTask:
3894
        stz             TestTask
3895
it2:
3896
        inc             TEXTSCR+111             ; increment IDLE active flag
3897
        ldx             TestTask
3898
        and             r2,r2,#$FF
3899
        beq             it1
3900
        lda             TCB_Status,x
3901
        cmp             #TS_SLEEP
3902
        bne             it1
3903
        txa
3904
        int             #4                              ; KillTask function
3905
        db              3
3906
;       jsr             KillTask
3907
it1:
3908
        inc             TestTask
3909
        cli                                             ; enable interrupts
3910
        wai                                             ; wait for one to happen
3911
        bra             it2
3912
 
3913
;------------------------------------------------------------------------------
3914
; Parameters:
3915
;       r1 = job name
3916
;       r2 = start address
3917
;------------------------------------------------------------------------------
3918
;
3919
StartJob:
3920
        pha
3921
 
3922
        ; Get a free JCB
3923
        spl             freejcb_sema + 1
3924
        ld              r6,FreeJCB
3925
        beq             sjob1
3926
        ld              r7,JCB_Next,r6
3927
        st              r7,FreeJCB
3928
        stz             freejcb_sema + 1
3929
 
3930
        lea             r7,JCB_Name,r6          ; r7 = address of name field
3931
        asl             r7,r7,#2                        ; convert word to byte address
3932
        ld              r9,r7                           ; save off buffer address
3933
        ld              r8,#0                           ; r8 = count of characters (0 to 31)
3934
sjob3:
3935
        lb              r5,0,r1                         ; get a character
3936
        beq             sjob2                           ; end of string ?
3937
        sb              r5,1,r7
3938
        ina
3939
        inc             r7
3940
        inc             r8
3941
        cmp             r8,#31                          ; max number of chars ?
3942
        blo             sjob3
3943
sjob2:
3944
        sb              r8,0,r9                         ; save name length
3945
 
3946
sjob1:
3947
        stz             freejcb_sema + 1
3948
        pla
3949
        rts
3950
 
3951
;------------------------------------------------------------------------------
3952
; StartTask
3953
;
3954
; Startup a task. The task is automatically allocated a 1kW stack from the BIOS
3955
; stacks area. The scheduler is invoked after the task is added to the ready
3956
; list.
3957
;
3958
; Parameters:
3959
;       r1 = task priority
3960
;       r2 = start flags
3961
;       r3 = start address
3962
;       r4 = start parameter
3963
;       r5 = job handle
3964
;------------------------------------------------------------------------------
3965
message "StartTask"
3966
StartTask:
3967
        pusha
3968
        ld              r6,r1                           ; r6 = task priority
3969
        ld              r8,r2                           ; r8 = flag register value on startup
3970
 
3971
        ; get a free TCB
3972
        ;
3973
        spl             freetcb_sema+1
3974
        lda             FreeTCB                         ; get free tcb list pointer
3975
        bmi             stask1
3976
        tax
3977
        lda             TCB_NxtTCB,x
3978
        sta             FreeTCB                         ; update the FreeTCB list pointer
3979
        stz             freetcb_sema+1
3980
        lda             #81
3981
        sta             LEDS
3982
        txa                                                     ; acc = TCB index (task number)
3983
        sta             TCB_mbx,x
3984
 
3985
        ; setup the stack for the task
3986
        ; Zap the stack memory.
3987
        ld              r7,r2
3988
        asl             r2,r2,#10                       ; 1kW stack per task
3989
        add             r2,r2,#BIOS_STACKS      ;+0x3ff ; add in stack base
3990
        pha
3991
        phx
3992
        phy
3993
        txy                                                     ; y = target address
3994
        ldx             #ExitTask                       ; x = fill value
3995
        lda             #$3FF                           ; acc = # words to fill -1
3996
        stos
3997
        ply
3998
        plx
3999
        pla
4000
 
4001
        add             r2,r2,#$3FF                     ; Move pointer to top of stack
4002
        stx             TCB_StackTop,r7
4003
        sub             r2,r2,#128
4004
        tsr             sp,r9                           ; save off current stack pointer
4005
        spl             tcb_sema + 1
4006
        txs
4007
        st              r6,TCB_Priority,r7
4008
        stz             TCB_Status,r7
4009
        stz             TCB_Timeout,r7
4010
        st              r5,TCB_hJCB,r7          ; save job handle
4011
        ; setup virtual video for the task
4012
;       stz             TCB_CursorRow,r7
4013
;       stz             TCB_CursorCol,r7
4014
        stz             TCB_mmu_map,r7          ; use mmu map
4015
;       jsr             AllocateMemPage
4016
        pha
4017
        lda             #82
4018
        sta             LEDS
4019
        lda             #-1
4020
        sta             TCB_MbxList,r7
4021
        lda             BASIC_SESSION
4022
        cmp             #1
4023
        bls             stask3
4024
        asl             r1,r1,#14
4025
        add             r1,r1,#$430_0000
4026
        sta             TCB_ABS8Save,r7
4027
        add             r1,r1,#$1FF
4028
        sta             TCB_SP8Save,r7
4029
        bra             stask4
4030
stask3:
4031
        lda             #$1FF
4032
        sta             TCB_SP8Save,r7
4033
        stz             TCB_ABS8Save,r7
4034
stask4:
4035
        lda             #83
4036
        sta             LEDS
4037
        pla
4038
;       tay
4039
 
4040
        ; setup the initial stack image for the task
4041
        ; Cause a return to the ExitTask routine when the task does a
4042
        ; final rts.
4043
        ; fake an IRQ call by stacking the return address and processor
4044
        ; flags on the stack
4045
        ldx             #ExitTask                       ; save the address of the task exit routine
4046
        phx
4047
        phy                                                     ; save start address on stack
4048
        push    r8                                      ; save processor status reg on stack
4049
 
4050
        ; now fake pushing the register set onto the stack. Registers start up
4051
        ; in an undefined state.
4052
;       sub             sp,#15                          ; 15 registers
4053
        push    r4
4054
        push    r4
4055
        push    r4
4056
        push    r4
4057
        push    r4
4058
        push    r4
4059
        push    r4
4060
        push    r4
4061
        push    r4
4062
        push    r4
4063
        push    r4
4064
        push    r4
4065
        push    r4
4066
        push    r4
4067
        push    r4
4068
        tsx
4069
        stx             TCB_SPSave,r7
4070
        ; now restore the current stack pointer
4071
        trs             r9,sp
4072
 
4073
        ; Insert the task into the ready list
4074
        ld              r4,#84
4075
        st              r4,LEDS
4076
        jsr             AddTaskToReadyList
4077
        lda             #1
4078
        sta             tcb_sema
4079
        int             #2                      ; invoke the scheduler
4080
;       GoReschedule            ; invoke the scheduler
4081
stask2:
4082
        popa
4083
        rts
4084
stask1:
4085
        stz             freetcb_sema+1
4086
        jsr             kernel_panic
4087
        db              "No more task control blocks available.",0
4088
        bra             stask2
4089
 
4090
;------------------------------------------------------------------------------
4091
; ExitTask
4092
;
4093
; This routine is called when the task exits with an rts instruction. OR
4094
; it may be invoked with a JMP ExitTask. In either case the task must be
4095
; running so it can't be on the timeout list. The scheduler is invoked
4096
; after the task is removed from the ready list.
4097
;------------------------------------------------------------------------------
4098
message "ExitTask"
4099
ExitTask:
4100
        ; release any aquired resources
4101
        ; - mailboxes
4102
        ; - messages
4103
        hoff
4104
        spl             tcb_sema + 1
4105
        lda             RunningTCB
4106
        cmp             #MAX_TASKNO
4107
        bhi             xtsk1
4108
        jsr             RemoveTaskFromReadyList
4109
        jsr             RemoveFromTimeoutList
4110
        stz             TCB_Status,r1                           ; set task status to TS_NONE
4111
        jsr             ReleaseIOFocus
4112
;       lda             TCB_ABS8Save,x
4113
;       jsr             FreeMemPage
4114
        ; Free up all the mailboxes associated with the task.
4115
xtsk7:
4116
        pha
4117
        lda             TCB_MbxList,r1
4118
        bmi             xtsk6
4119
        jsr             FreeMbx
4120
        pla
4121
        bra             xtsk7
4122
xtsk6:
4123
        pla
4124
        ldx             #86
4125
        stx             LEDS
4126
        spl             freetcb_sema+1
4127
        ldx             FreeTCB                                         ; add the task control block to the free list
4128
        stx             TCB_NxtTCB,r1
4129
        sta             FreeTCB
4130
        stz             freetcb_sema+1
4131
xtsk1:
4132
        jmp             SelectTaskToRun
4133
 
4134
;------------------------------------------------------------------------------
4135
; r1 = task number
4136
; r2 = new priority
4137
;------------------------------------------------------------------------------
4138
;
4139
SetTaskPriority:
4140
        cmp             #MAX_TASKNO                                     ; make sure task number is reasonable
4141
        bhi             stp1
4142
        phy
4143
        spl             tcb_sema + 1
4144
        ldy             TCB_Status,r1                           ; if the task is on the ready list
4145
        bit             r3,#TS_READY|TS_RUNNING         ; then remove it and re-add it.
4146
        beq             stp2                                            ; Otherwise just go set the priority field
4147
        jsr             RemoveTaskFromReadyList
4148
        stx             TCB_Priority,r1
4149
        jsr             AddTaskToReadyList
4150
        bra             stp3
4151
stp2:
4152
        stx             TCB_Priority,r1
4153
stp3:
4154
        ldy             #1
4155
        sty             tcb_sema
4156
        int             #2
4157
        ply
4158
stp1:
4159
        rts
4160
 
4161
;------------------------------------------------------------------------------
4162
; AddTaskToReadyList
4163
;
4164
; The ready list is a group of five ready lists, one for each priority
4165
; level. Each ready list is organized as a doubly linked list to allow fast
4166
; insertions and removals. The list is organized as a ring (or bubble) with
4167
; the last entry pointing back to the first. This allows a fast task switch
4168
; to the next task. Which task is at the head of the list is maintained
4169
; in the variable QNdx for the priority level.
4170
;
4171
; Registers Affected: none
4172
; Parameters:
4173
;       r1 = task number
4174
; Returns:
4175
;       none
4176
;------------------------------------------------------------------------------
4177
;
4178
message "AddTaskToReadyList"
4179
AddTaskToReadyList:
4180
        phx
4181
        phy
4182
        ldx             #TS_READY
4183
        stx             TCB_Status,r1
4184
        ldx             #-1
4185
        stx             TCB_NxtRdy,r1
4186
        stx             TCB_PrvRdy,r1
4187
        ldy             TCB_Priority,r1
4188
        cpy             #5
4189
        blo             arl1
4190
        ldy             #PRI_LOWEST
4191
arl1:
4192
        ldx             QNdx0,y
4193
        bmi             arl5
4194
        ldy             TCB_PrvRdy,x
4195
        sta             TCB_NxtRdy,y
4196
        sty             TCB_PrvRdy,r1
4197
        sta             TCB_PrvRdy,x
4198
        stx             TCB_NxtRdy,r1
4199
        ply
4200
        plx
4201
        rts
4202
 
4203
        ; Here the ready list was empty, so add at head
4204
arl5:
4205
        sta             QNdx0,y
4206
        sta             TCB_NxtRdy,r1
4207
        sta             TCB_PrvRdy,r1
4208
        ply
4209
        plx
4210
        rts
4211
 
4212
;------------------------------------------------------------------------------
4213
; RemoveTaskFromReadyList
4214
;
4215
; This subroutine removes a task from the ready list.
4216
;
4217
; Registers Affected: none
4218
; Parameters:
4219
;       r1 = task number
4220
; Returns:
4221
;   r1 = task number
4222
;------------------------------------------------------------------------------
4223
 
4224
message "RemoveTaskFromReadyList"
4225
RemoveTaskFromReadyList:
4226
        phx
4227
        phy
4228
        push    r4
4229
        push    r5
4230
 
4231
        ldy             TCB_Status,r1   ; is the task on the ready list ?
4232
        bit             r3,#TS_READY|TS_RUNNING
4233
        beq             rfr2
4234
        and             r3,r3,#~(TS_READY|TS_RUNNING)
4235
        sty             TCB_Status,r1           ; task status no longer running or ready
4236
        ld              r4,TCB_NxtRdy,r1        ; Get previous and next fields.
4237
        ld              r5,TCB_PrvRdy,r1
4238
        st              r4,TCB_NxtRdy,r5
4239
        st              r5,TCB_PrvRdy,r4
4240
        ldy             TCB_Priority,r1
4241
        cmp             r1,QNdx0,y                      ; Are we removing the QNdx task ?
4242
        bne             rfr2
4243
        st              r4,QNdx0,y
4244
        ; Now we test for the case where the task being removed was the only one
4245
        ; on the ready list of that priority level. We can tell because the
4246
        ; NxtRdy would point to the task itself.
4247
        cmp             r4,r1
4248
        bne             rfr2
4249
        ldx             #-1                                     ; Make QNdx negative
4250
        stx             QNdx0,y
4251
        stx             TCB_NxtRdy,r1
4252
        stx             TCB_PrvRdy,r1
4253
rfr2:
4254
        pop             r5
4255
        pop             r4
4256
        ply
4257
        plx
4258
        rts
4259
 
4260
;------------------------------------------------------------------------------
4261
; AddToTimeoutList
4262
; AddToTimeoutList adds a task to the timeout list. The task is placed in the
4263
; list depending on it's timeout value.
4264
;
4265
; Registers Affected: none
4266
; Parameters:
4267
;       r1 = task
4268
;       r2 = timeout value
4269
;------------------------------------------------------------------------------
4270
message "AddToTimeoutList"
4271
AddToTimeoutList:
4272
        phx
4273
        push    r4
4274
        push    r5
4275
 
4276
        ld              r5,#-1
4277
        st              r5,TCB_NxtTo,r1         ; these fields should already be -1
4278
        st              r5,TCB_PrvTo,r1
4279
        ld              r4,TimeoutList          ; are there any tasks on the timeout list ?
4280
        bmi             attl_add_at_head        ; If not, update head of list
4281
attl_check_next:
4282
        sub             r2,r2,TCB_Timeout,r4    ; is this timeout > next
4283
        bmi             attl_insert_before
4284
        ld              r5,r4
4285
        ld              r4,TCB_NxtTo,r4
4286
        bpl             attl_check_next
4287
 
4288
        ; Here we scanned until the end of the timeout list and didn't find a
4289
        ; timeout of a greater value. So we add the task to the end of the list.
4290
attl_add_at_end:
4291
        st              r4,TCB_NxtTo,r1         ; r4 is = -1
4292
        st              r1,TCB_NxtTo,r5
4293
        st              r5,TCB_PrvTo,r1
4294
        stx             TCB_Timeout,r1
4295
        bra             attl_exit
4296
 
4297
attl_insert_before:
4298
        cmp             r5,#0
4299
        bmi             attl_insert_before_head
4300
        st              r4,TCB_NxtTo,r1         ; next on list goes after this task
4301
        st              r5,TCB_PrvTo,r1         ; set previous link
4302
        st              r1,TCB_NxtTo,r5
4303
        st              r1,TCB_PrvTo,r4
4304
        bra             attl_adjust_timeout
4305
 
4306
        ; Here there is no previous entry in the timeout list
4307
        ; Add at start
4308
attl_insert_before_head:
4309
        sta             TCB_PrvTo,r4
4310
        st              r5,TCB_PrvTo,r1         ; r5 is = -1
4311
        st              r4,TCB_NxtTo,r1
4312
        sta             TimeoutList                     ; update the head pointer
4313
attl_adjust_timeout:
4314
        add             r2,r2,TCB_Timeout,r4    ; get back timeout
4315
        stx             TCB_Timeout,r1
4316
        ld              r5,TCB_Timeout,r4       ; adjust the timeout of the next task
4317
        sub             r5,r5,r2
4318
        st              r5,TCB_Timeout,r4
4319
        bra             attl_exit
4320
 
4321
        ; Here there were no tasks on the timeout list, so we add at the
4322
        ; head of the list.
4323
attl_add_at_head:
4324
        sta             TimeoutList                     ; set the head of the timeout list
4325
        stx             TCB_Timeout,r1
4326
        ldx             #-1                                     ; flag no more entries in timeout list
4327
        stx             TCB_NxtTo,r1            ; no next entries
4328
        stx             TCB_PrvTo,r1            ; and no prev entries
4329
attl_exit:
4330
        ldx             TCB_Status,r1           ; set the task's status as timing out
4331
        or              r2,r2,#TS_TIMEOUT
4332
        stx             TCB_Status,r1
4333
        pop             r5
4334
        pop             r4
4335
        plx
4336
        rts
4337
 
4338
;------------------------------------------------------------------------------
4339
; RemoveFromTimeoutList
4340
;
4341
; This routine is called when a task is killed. The task may need to be
4342
; removed from the middle of the timeout list.
4343
;
4344
; On entry: the timeout list semaphore must be already set.
4345
; Registers Affected: none
4346
; Parameters:
4347
;        r1 = task number
4348
;------------------------------------------------------------------------------
4349
message "RemoveFromTimeoutList"
4350
RemoveFromTimeoutList:
4351
        cmp             #MAX_TASKNO
4352
        bhi             rftl_not_on_list2
4353
        phx
4354
        push    r4
4355
        push    r5
4356
 
4357
        ld              r4,TCB_Status,r1                ; Is the task even on the timeout list ?
4358
        bit             r4,#TS_TIMEOUT
4359
        beq             rftl_not_on_list
4360
        cmp             TimeoutList                             ; Are we removing the head of the list ?
4361
        beq             rftl_remove_from_head
4362
        ld              r4,TCB_PrvTo,r1                 ; adjust the links of the next and previous
4363
        bmi             rftl_empty_list                 ; no previous link - list corrupt?
4364
        ld              r5,TCB_NxtTo,r1                 ; tasks on the list to point around the task
4365
        st              r5,TCB_NxtTo,r4
4366
        bmi             rftl_empty_list
4367
        st              r4,TCB_PrvTo,r5
4368
        ldx             TCB_Timeout,r1                  ; update the timeout of the next on list
4369
        add             r2,r2,TCB_Timeout,r5    ; with any remaining timeout in the task
4370
        stx             TCB_Timeout,r5                  ; removed from the list
4371
        bra             rftl_empty_list
4372
 
4373
        ; Update the head of the list.
4374
rftl_remove_from_head:
4375
        ld              r5,TCB_NxtTo,r1
4376
        st              r5,TimeoutList                  ; store next field into list head
4377
        bmi             rftl_empty_list
4378
        ld              r4,TCB_Timeout,r1               ; add any remaining timeout to the timeout
4379
        add             r4,r4,TCB_Timeout,r5    ; of the next task on the list.
4380
        st              r4,TCB_Timeout,r5
4381
        ld              r4,#-1                                  ; there is no previous item to the head
4382
        sta             TCB_PrvTo,r5
4383
 
4384
        ; Here there is no previous or next items in the list, so the list
4385
        ; will be empty once this task is removed from it.
4386
rftl_empty_list:
4387
        tax
4388
        lda             #0                                      ; clear timeout status (bit #0)
4389
        bmc             TCB_Status,x
4390
        dea                                                     ; acc=-1; make sure the next and prev fields indicate
4391
        sta             TCB_NxtTo,x                     ; the task is not on a list.
4392
        sta             TCB_PrvTo,x
4393
        txa
4394
rftl_not_on_list:
4395
        pop             r5
4396
        pop             r4
4397
        plx
4398
rftl_not_on_list2:
4399
        rts
4400
 
4401
;------------------------------------------------------------------------------
4402
; PopTimeoutList
4403
;
4404
; This subroutine is called from within the timer ISR when the task's
4405
; timeout expires. It's always the head of the list that's being removed in
4406
; the timer ISR so the removal from the timeout list is optimized. We know
4407
; the timeout expired, so the amount of time to add to the next task is zero.
4408
;       This routine is written as a macro since it's only called from one place.
4409
; This routine is inlined. Implementing it as a macro increases performance.
4410
;
4411
; Registers Affected: acc, x, y, flags
4412
; Parameters:
4413
;       x: head of timeout list
4414
; Returns:
4415
;       r1 = task id of task popped from timeout list
4416
;------------------------------------------------------------------------------
4417
;
4418
message "PopTimeoutList"
4419
macro PopTimeoutList
4420
        ldy             #-1
4421
        lda             TCB_NxtTo,x
4422
        sta             TimeoutList             ; store next field into list head
4423
        bmi             ptl1
4424
        sty             TCB_PrvTo,r1    ; previous link = -1
4425
ptl1:
4426
        lda             #0                              ; clear timeout status
4427
        bmc             TCB_Status,x
4428
        sty             TCB_NxtTo,x             ; make sure the next and prev fields indicate
4429
        sty             TCB_PrvTo,x             ; the task is not on a list.
4430
        txa
4431
endm
4432
 
4433
;------------------------------------------------------------------------------
4434
; Sleep
4435
;
4436
; Put the currently running task to sleep for a specified time.
4437
;
4438
; Registers Affected: none
4439
; Parameters:
4440
;       r1 = time duration in centi-seconds (1/100 second).
4441
; Returns: none
4442
;------------------------------------------------------------------------------
4443
;
4444
Sleep:
4445
        pha
4446
        phx
4447
        tax
4448
        spl             tcb_sema + 1
4449
        lda             RunningTCB
4450
        jsr             RemoveTaskFromReadyList
4451
        jsr             AddToTimeoutList        ; The scheduler will be returning to this
4452
        lda             #1
4453
        sta             tcb_sema
4454
        int             #2                              ; task eventually, once the timeout expires,
4455
        plx
4456
        pla
4457
        rts
4458
 
4459
;------------------------------------------------------------------------------
4460
; Short delay routine.
4461
;       This routine works by reading the tick register. When a subsequent read
4462
; of the tick register exceeds the value of the original read by at least
4463
; the value passed as a parameter, then this routine returns.
4464
;       The tick register increments at the clock rate (eg 25 MHz).
4465
;------------------------------------------------------------------------------
4466
;
4467
short_delay:
4468
        phx
4469
        phy
4470
        tsr             tick,r2
4471
usec1:
4472
        tsr             tick,r3
4473
        sub             r3,r3,r2
4474
        cmp             r1,r3
4475
        blo             usec1
4476
        ply
4477
        plx
4478
        rts
4479
 
4480
;------------------------------------------------------------------------------
4481
; KillTask
4482
;
4483
; "Kills" a task, removing it from all system lists. If the task has the
4484
; IO focus, the IO focus is switched. Task #0 is immortal and cannot be
4485
; killed.
4486
;
4487
; Registers Affected: none
4488
; Parameters:
4489
;       r1 = task number
4490
;------------------------------------------------------------------------------
4491
;
4492
KillTask:
4493
        phx
4494
        cmp             #1                                                      ; BIOS task and IDLE task are immortal
4495
        bls             kt1
4496
        cmp             #MAX_TASKNO
4497
        bhi             kt1
4498
        tax
4499
        lda             TCB_hJCB,r1
4500
        jsr             ForceReleaseIOFocus
4501
        txa
4502
        spl             tcb_sema + 1
4503
        jsr             RemoveTaskFromReadyList
4504
        jsr             RemoveFromTimeoutList
4505
        stz             TCB_Status,r1                           ; set task status to TS_NONE
4506
 
4507
        ; Free up all the mailboxes associated with the task.
4508
kt7:
4509
        pha
4510
        tax
4511
        lda             TCB_MbxList,r1
4512
        bmi             kt6
4513
        jsr             FreeMbx2
4514
        pla
4515
        bra             kt7
4516
kt6:
4517
        lda             #1
4518
        sta             tcb_sema
4519
        pla
4520
 
4521
        spl             freetcb_sema + 1
4522
        ldx             FreeTCB                                         ; add the task control block to the free list
4523
        stx             TCB_NxtTCB,r1
4524
        sta             FreeTCB
4525
        stz             freetcb_sema + 1
4526
        cmp             RunningTCB                                      ; keep running the current task as long as
4527
        bne             kt1                                                     ; the task didn't kill itself.
4528
        int             #2                                                      ; invoke scheduler to reschedule tasks
4529
kt1:
4530
        plx
4531
        rts
4532
 
4533
;------------------------------------------------------------------------------
4534
; Allocate a mailbox
4535
; Parameters:
4536
;       r1 = pointer to place to store handle
4537
; Returns:
4538
;       r1 = E_Ok       means mailbox allocated properly
4539
;       r1 = E_Arg      means a NULL pointer was passed in r1
4540
;       r1 = E_NoMoreMbx        means no more mailboxes were available
4541
;       zf is set if everything is ok, otherwise zf is clear
4542
;------------------------------------------------------------------------------
4543
;
4544
message "AllocMbx"
4545
AllocMbx:
4546
        cmp             #0
4547
        beq             ambx_bad_ptr
4548
        phx
4549
        phy
4550
        push    r4
4551
        ld              r4,r1                   ; r4 = pointer to returned handle
4552
        spl             freembx_sema + 1
4553
        lda             FreeMbxHandle                   ; Get mailbox off of free mailbox list
4554
        sta             (r4)                    ; store off the mailbox number
4555
        bmi             ambx_no_mbxs
4556
        ldx             MBX_LINK,r1             ; and update the head of the list
4557
        stx             FreeMbxHandle
4558
        dec             nMailbox                ; decrement number of available mailboxes
4559
        stz             freembx_sema + 1
4560
        spl             tcb_sema + 1
4561
        ldy             RunningTCB              ; Add the mailbox to the list of mailboxes
4562
        ldx             TCB_MbxList,y   ; managed by the task.
4563
        stx             MBX_LINK,r1
4564
        sta             TCB_MbxList,y
4565
        tax
4566
        ldy             RunningTCB                      ; set the mailbox owner
4567
;       bmi             RunningTCBErr
4568
        lda             TCB_hJCB,y
4569
        stz             tcb_sema + 1
4570
 
4571
        spl             mbx_sema + 1
4572
        sta             MBX_OWNER,x
4573
        lda             #-1                             ; initialize the head and tail of the queues
4574
        sta             MBX_TQ_HEAD,x
4575
        sta             MBX_TQ_TAIL,x
4576
        sta             MBX_MQ_HEAD,x
4577
        sta             MBX_MQ_TAIL,x
4578
        stz             MBX_TQ_COUNT,x  ; initialize counts to zero
4579
        stz             MBX_MQ_COUNT,x
4580
        stz             MBX_MQ_MISSED,x
4581
        lda             #8                              ; set the max queue size
4582
        sta             MBX_MQ_SIZE,x   ; and
4583
        lda             #MQS_NEWEST             ; queueing strategy
4584
        sta             MBX_MQ_STRATEGY,x
4585
        stz             mbx_sema + 1
4586
        pop             r4
4587
        ply
4588
        plx
4589
        lda             #E_Ok
4590
        rts
4591
ambx_bad_ptr:
4592
        lda             #E_Arg
4593
        rts
4594
ambx_no_mbxs:
4595
        stz             freembx_sema + 1
4596
        pop             r4
4597
        ply
4598
        plx
4599
        lda             #E_NoMoreMbx
4600
        rts
4601
 
4602
;------------------------------------------------------------------------------
4603
; Free up a mailbox.
4604
;       This function frees a mailbox from the currently running task. It may be
4605
; called by ExitTask().
4606
;
4607
; Parameters:
4608
;       r1 = mailbox handle
4609
;------------------------------------------------------------------------------
4610
;
4611
FreeMbx:
4612
        phx
4613
        ldx             RunningTCB
4614
        jsr             FreeMbx2
4615
        plx
4616
        rts
4617
 
4618
;------------------------------------------------------------------------------
4619
; Free up a mailbox.
4620
;       This function dequeues any messages from the mailbox and adds the messages
4621
; back to the free message pool. The function also dequeues any threads from
4622
; the mailbox.
4623
;       Called from KillTask() and FreeMbx().
4624
;
4625
; Parameters:
4626
;       r1 = mailbox handle
4627
;       r2 = task handle
4628
; Returns:
4629
;       r1 = E_Ok       if everything ok
4630
;       r1 = E_Arg      if a bad handle is passed
4631
;------------------------------------------------------------------------------
4632
;
4633
FreeMbx2:
4634
        cmp             #NR_MBX                         ; check mailbox handle parameter
4635
        bhs             fmbx1
4636
        cpx             #MAX_TASKNO
4637
        bhi             fmbx1
4638
        phx
4639
        phy
4640
        spl             mbx_sema + 1
4641
 
4642
        ; Dequeue messages from mailbox and add them back to the free message list.
4643
fmbx5:
4644
        pha
4645
        jsr             DequeueMsgFromMbx
4646
        bmi             fmbx3
4647
        spl             freemsg_sema + 1
4648
        phx
4649
        ldx             FreeMsg
4650
        stx             MSG_LINK,r1
4651
        sta             FreeMsg
4652
        stz             freemsg_sema + 1
4653
        plx
4654
        pla
4655
        bra             fmbx5
4656
fmbx3:
4657
        pla
4658
 
4659
        ; Dequeue threads from mailbox.
4660
fmbx6:
4661
        pha
4662
        jsr             DequeueThreadFromMbx2
4663
        bmi             fmbx7
4664
        pla
4665
        bra             fmbx6
4666
fmbx7:
4667
        pla
4668
 
4669
        ; Remove mailbox from TCB list
4670
        ldy             TCB_MbxList,x
4671
        phx
4672
        ldx             #-1
4673
fmbx10:
4674
        cmp             r1,r3
4675
        beq             fmbx9
4676
        tyx
4677
        ldy             MBX_LINK,y
4678
        bpl             fmbx10
4679
        ; ?The mailbox was not in the list managed by the task.
4680
        plx
4681
        bra             fmbx2
4682
fmbx9:
4683
        cmp             r2,r0
4684
        bmi             fmbx11
4685
        ldy             MBX_LINK,y
4686
        sty             MBX_LINK,x
4687
        plx
4688
        bra             fmbx12
4689
fmbx11:
4690
        ; No prior mailbox in list, update head
4691
        ldy             MBX_LINK,r1
4692
        plx
4693
        sty             TCB_MbxList,x
4694
 
4695
fmbx12:
4696
        ; Add mailbox back to mailbox pool
4697
        spl             freembx_sema + 1
4698
        ldx             FreeMbxHandle
4699
        stx             MBX_LINK,r1
4700
        sta             FreeMbxHandle
4701
        stz             freembx_sema + 1
4702
fmbx2:
4703
        stz             mbx_sema + 1
4704
        ply
4705
        plx
4706
        lda             #E_Ok
4707
        rts
4708
fmbx1:
4709
        lda             #E_Arg
4710
        rts
4711
 
4712
;------------------------------------------------------------------------------
4713
; Queue a message at a mailbox.
4714
; On entry the mailbox semaphore is already activated.
4715
;
4716
; Parameters:
4717
;       r1 = message
4718
;       r2 = mailbox
4719
;------------------------------------------------------------------------------
4720
message "QueueMsgAtMbx"
4721
QueueMsgAtMbx:
4722
        cmp             #0
4723
        beq             qmam_bad_msg
4724
        pha
4725
        phx
4726
        phy
4727
        push    r4
4728
        ld              r4,MBX_MQ_STRATEGY,x
4729
        cmp             r4,#MQS_UNLIMITED
4730
        beq             qmam_unlimited
4731
        cmp             r4,#MQS_NEWEST
4732
        beq             qmam_newest
4733
        cmp             r4,#MQS_OLDEST
4734
        beq             qmam_oldest
4735
        jsr             kernel_panic
4736
        db              "Illegal message queue strategy",0
4737
        bra             qmam8
4738
        ; Here we assumed "unlimited" message storage. Just add the new message at
4739
        ; the tail of the queue.
4740
qmam_unlimited:
4741
        ldy             MBX_MQ_TAIL,x
4742
        bmi             qmam_add_at_head
4743
        sta             MSG_LINK,y
4744
        bra             qmam2
4745
qmam_add_at_head:
4746
        sta             MBX_MQ_HEAD,x
4747
qmam2:
4748
        sta             MBX_MQ_TAIL,x
4749
qmam6:
4750
        inc             MBX_MQ_COUNT,x          ; increase the queued message count
4751
        ldx             #-1
4752
        stx             MSG_LINK,r1
4753
        pop             r4
4754
        ply
4755
        plx
4756
        pla
4757
qmam_bad_msg:
4758
        rts
4759
        ; Here we are queueing a limited number of messages. As new messages are
4760
        ; added at the tail of the queue, messages drop off the head of the queue.
4761
qmam_newest:
4762
        ldy             MBX_MQ_TAIL,x
4763
        bmi             qmam3
4764
        sta             MSG_LINK,y
4765
        bra             qmam4
4766
qmam3:
4767
        sta             MBX_MQ_HEAD,x
4768
qmam4:
4769
        sta             MBX_MQ_TAIL,x
4770
        ldy             MBX_MQ_COUNT,x
4771
        iny
4772
        cmp             r3,MBX_MQ_SIZE,x
4773
        bls             qmam6
4774
        ldy             #-1
4775
        sty             MSG_LINK,r1
4776
        ; Remove the oldest message which is the one at the head of the mailbox queue.
4777
        ; Add the message back to the pool of free messages.
4778
        lda             MBX_MQ_HEAD,x
4779
        ldy             MSG_LINK,r1                     ; move next in queue
4780
        sty             MBX_MQ_HEAD,x           ; to head of list
4781
qmam8:
4782
        inc             MBX_MQ_MISSED,x
4783
qmam1:
4784
        spl             freemsg_sema + 1
4785
        ldy             FreeMsg                         ; put old message back into free message list
4786
        sty             MSG_LINK,r1
4787
        sta             FreeMsg
4788
        inc             nMsgBlk
4789
        stz             freemsg_sema + 1
4790
        ;GoReschedule
4791
        pop             r4
4792
        ply
4793
        plx
4794
        pla
4795
        rts
4796
        ; Here we are buffering the oldest messages. So if there are too many messages
4797
        ; in the queue already, then the queue doesn't change and the new message is
4798
        ; lost.
4799
qmam_oldest:
4800
        ldy             MBX_MQ_COUNT,x          ; Check if the queue is full
4801
        cmp             r3,MBX_MQ_SIZE,x
4802
        bhs             qmam8                           ; If the queue is full, then lose the current message
4803
        bra             qmam_unlimited          ; Otherwise add message to queue
4804
 
4805
;------------------------------------------------------------------------------
4806
; Dequeue a message from a mailbox.
4807
;
4808
; Returns
4809
;       r1 = message number
4810
;       nf set if there is no message, otherwise clear
4811
;------------------------------------------------------------------------------
4812
message "DequeueMsgFromMbx"
4813
DequeueMsgFromMbx:
4814
        phx
4815
        phy
4816
        tax                                             ; x = mailbox index
4817
        lda             MBX_MQ_COUNT,x          ; are there any messages available ?
4818
        beq             dmfm3
4819
        dea
4820
        sta             MBX_MQ_COUNT,x          ; update the message count
4821
        lda             MBX_MQ_HEAD,x           ; Get the head of the list, this should not be -1
4822
        bmi             dmfm3                   ; since the message count > 0
4823
        ldy             MSG_LINK,r1             ; get the link to the next message
4824
        sty             MBX_MQ_HEAD,x           ; update the head of the list
4825
        bpl             dmfm2                   ; if there was no more messages then update the
4826
        sty             MBX_MQ_TAIL,x           ; tail of the list as well.
4827
dmfm2:
4828
        sta             MSG_LINK,r1             ; point the link to the messahe itself to indicate it's dequeued
4829
dmfm1:
4830
        ply
4831
        plx
4832
        cmp             #0
4833
        rts
4834
dmfm3:
4835
        ply
4836
        plx
4837
        lda             #-1
4838
        rts
4839
 
4840
;------------------------------------------------------------------------------
4841
; Parameters:
4842
;       r1 = mailbox handle
4843
; Returns:
4844
;       r1 = E_arg              means pointer is invalid
4845
;       r1 = E_NoThread means no thread was queued at the mailbox
4846
;       r2 = thead handle
4847
;------------------------------------------------------------------------------
4848
message "DequeueThreadFromNbx"
4849
DequeueThreadFromMbx:
4850
        push    r4
4851
        ld              r4,MBX_TQ_HEAD,r1
4852
        bpl             dtfm2
4853
        pop             r4
4854
        ldx             #-1
4855
        lda             #E_NoThread
4856
        rts
4857
dtfm2:
4858
        push    r5
4859
        dec             MBX_TQ_COUNT,r1
4860
        ld              r2,r4
4861
        ld              r4,TCB_mbq_next,r4
4862
        st              r4,MBX_TQ_HEAD,r1
4863
        bmi             dtfm3
4864
                ld              r5,#-1
4865
                st              r5,TCB_mbq_prev,r4
4866
                bra             dtfm4
4867
dtfm3:
4868
                ld              r5,#-1
4869
                st              r5,MBX_TQ_TAIL,r1
4870
dtfm4:
4871
;       stz             MBX_SEMA+1
4872
        ld              r5,r2
4873
        lda             TCB_Status,r5
4874
        bit             #TS_TIMEOUT
4875
        beq             dtfm5
4876
        ld              r1,r5
4877
        jsr             RemoveFromTimeoutList
4878
dtfm5:
4879
        ld              r4,#-1
4880
        st              r4,TCB_mbq_next,r5
4881
        st              r4,TCB_mbq_prev,r5
4882
        stz             TCB_hWaitMbx,r5
4883
        stz             TCB_Status,r5           ; set task status = TS_NONE
4884
        pop             r5
4885
        pop             r4
4886
        lda             #E_Ok
4887
        rts
4888
 
4889
;------------------------------------------------------------------------------
4890
;       This function is called from FreeMbx(). It dequeues threads from the
4891
; mailbox without removing the thread from the timeout list. The thread will
4892
; then timeout waiting for a message that can never be delivered.
4893
;
4894
; Parameters:
4895
;       r1 = mailbox handle
4896
; Returns:
4897
;       r1 = E_arg              means pointer is invalid
4898
;       r1 = E_NoThread means no thread was queued at the mailbox
4899
;       r2 = thead handle
4900
;------------------------------------------------------------------------------
4901
message "DequeueThreadFromNbx2"
4902
DequeueThreadFromMbx2:
4903
        push    r4
4904
        ld              r4,MBX_TQ_HEAD,r1
4905
        bpl             dtfm2a
4906
        pop             r4
4907
        ldx             #-1
4908
        lda             #E_NoThread
4909
        rts
4910
dtfm2a:
4911
        push    r5
4912
        dec             MBX_TQ_COUNT,r1
4913
        ld              r2,r4
4914
        ld              r4,TCB_mbq_next,r4
4915
        st              r4,MBX_TQ_HEAD,r1
4916
        bmi             dtfm3a
4917
                ld              r5,#-1
4918
                st              r5,TCB_mbq_prev,r4
4919
                bra             dtfm4a
4920
dtfm3a:
4921
                ld              r5,#-1
4922
                st              r5,MBX_TQ_TAIL,r1
4923
dtfm4a:
4924
        ld              r4,#-1
4925
        st              r4,TCB_mbq_next,x
4926
        st              r4,TCB_mbq_prev,x
4927
        stz             TCB_hWaitMbx,x
4928
        sei
4929
        lda             #TS_WAITMSG_BIT
4930
        bmc             TCB_Status,x
4931
        cli
4932
        pop             r5
4933
        pop             r4
4934
        lda             #E_Ok
4935
        rts
4936
 
4937
;------------------------------------------------------------------------------
4938
; PostMsg and SendMsg are the same operation except that PostMsg doesn't
4939
; invoke rescheduling while SendMsg does. So they both call the same
4940
; SendMsgPrim primitive routine. This two wrapper functions for convenience.
4941
;------------------------------------------------------------------------------
4942
;
4943
PostMsg:
4944
        push    r4
4945
        ld              r4,#0                   ; Don't invoke scheduler
4946
        jsr             SendMsgPrim
4947
        pop             r4
4948
        rts
4949
 
4950
SendMsg:
4951
        push    r4
4952
        ld              r4,#1                   ; Do invoke scheduler
4953
        jsr             SendMsgPrim
4954
        pop             r4
4955
        rts
4956
 
4957
;------------------------------------------------------------------------------
4958
; SendMsgPrim
4959
; Send a message to a mailbox
4960
;
4961
; Parameters
4962
;       r1 = handle to mailbox
4963
;       r2 = message D1
4964
;       r3 = message D2
4965
;       r4 = scheduler flag             1=invoke,0=don't invoke
4966
;
4967
; Returns
4968
;       r1=E_Ok                 everything is ok
4969
;       r1=E_BadMbx             for a bad mailbox number
4970
;       r1=E_NotAlloc   for a mailbox that isn't allocated
4971
;       r1=E_NoMsg              if there are no more message blocks available
4972
;       zf is set if everything is okay, otherwise zf is clear
4973
;------------------------------------------------------------------------------
4974
message "SendMsgPrim"
4975
SendMsgPrim:
4976
        cmp             #NR_MBX                                 ; check the mailbox number to make sure
4977
        bhs             smsg1                                   ; that it's sensible
4978
        push    r5
4979
        push    r6
4980
        push    r7
4981
 
4982
        spl             mbx_sema + 1
4983
        ld              r7,MBX_OWNER,r1
4984
        bmi             smsg2                                   ; error: no owner
4985
        pha
4986
        phx
4987
        jsr             DequeueThreadFromMbx    ; r1=mbx
4988
        ld              r6,r2                                   ; r6 = thread
4989
        plx
4990
        pla
4991
        cmp             r6,#0
4992
        bpl             smsg3
4993
                ; Here there was no thread waiting at the mailbox, so a message needs to
4994
                ; be allocated
4995
smp2:
4996
                spl             freemsg_sema + 1
4997
                ld              r7,FreeMsg
4998
                bmi             smsg4           ; no more messages available
4999
                ld              r5,MSG_LINK,r7
5000
                st              r5,FreeMsg
5001
                dec             nMsgBlk         ; decrement the number of available messages
5002
                stz             freemsg_sema + 1
5003
                stx             MSG_D1,r7
5004
                sty             MSG_D2,r7
5005
                pha
5006
                phx
5007
                tax                                             ; x = mailbox
5008
                ld              r1,r7                   ; acc = message
5009
                jsr             QueueMsgAtMbx
5010
                plx
5011
                pla
5012
                cmp             r6,#0                   ; check if there is a thread waiting for a message
5013
                bmi             smsg5
5014
smsg3:
5015
        stx             TCB_MSG_D1,r6
5016
        sty             TCB_MSG_D2,r6
5017
smsg7:
5018
        spl             tcb_sema + 1
5019
        ld              r5,TCB_Status,r6
5020
        bit             r5,#TS_TIMEOUT
5021
        beq             smsg8
5022
        ld              r1,r6
5023
        jsr             RemoveFromTimeoutList
5024
smsg8:
5025
        lda             #TS_WAITMSG_BIT
5026
        bmc             TCB_Status,r6
5027
        lda             #1
5028
        sta             tcb_sema
5029
        ld              r1,r6
5030
        spl             tcb_sema + 1
5031
        jsr             AddTaskToReadyList
5032
        stz             tcb_sema + 1
5033
        cmp             r4,#0
5034
        beq             smsg5
5035
        stz             mbx_sema + 1
5036
        int             #2
5037
        ;GoReschedule
5038
        bra             smsg9
5039
smsg5:
5040
        stz             mbx_sema + 1
5041
smsg9:
5042
        pop             r7
5043
        pop             r6
5044
        pop             r5
5045
        lda             #E_Ok
5046
        rts
5047
smsg1:
5048
        lda             #E_BadMbx
5049
        rts
5050
smsg2:
5051
        stz             mbx_sema + 1
5052
        pop             r7
5053
        pop             r6
5054
        pop             r5
5055
        lda             #E_NotAlloc
5056
        rts
5057
smsg4:
5058
        stz             freemsg_sema + 1
5059
        stz             mbx_sema + 1
5060
        pop             r7
5061
        pop             r6
5062
        pop             r5
5063
        lda             #E_NoMsg
5064
        rts
5065
 
5066
;------------------------------------------------------------------------------
5067
; WaitMsg
5068
; Wait at a mailbox for a message to arrive. This subroutine will block the
5069
; task until a message is available or the task times out on the timeout
5070
; list.
5071
;
5072
; Parameters
5073
;       r1=mailbox
5074
;       r2=timeout
5075
; Returns:
5076
;       r1=E_Ok                 if everything is ok
5077
;       r1=E_BadMbx             for a bad mailbox number
5078
;       r1=E_NotAlloc   for a mailbox that isn't allocated
5079
;       r2=message D1
5080
;       r3=message D2
5081
;------------------------------------------------------------------------------
5082
message "WaitMsg"
5083
WaitMsg:
5084
        cmp             #NR_MBX                         ; check the mailbox number to make sure
5085
        bhs             wmsg1                           ; that it's sensible
5086
        push    r4
5087
        push    r5
5088
        push    r6
5089
        push    r7
5090
        ld              r6,r1
5091
wmsg11:
5092
        spl             mbx_sema + 1
5093
        ld              r5,MBX_OWNER,r1
5094
        cmp             r5,#MAX_TASKNO
5095
        bhi             wmsg2                                   ; error: no owner
5096
        jsr             DequeueMsgFromMbx
5097
;       cmp             #0
5098
        bpl             wmsg3
5099
 
5100
        ; Here there was no message available, remove the task from
5101
        ; the ready list, and optionally add it to the timeout list.
5102
        ; Queue the task at the mailbox.
5103
wmsg12:
5104
        spl             tcb_sema + 1
5105
        lda             RunningTCB                              ; remove the task from the ready list
5106
        jsr             RemoveTaskFromReadyList
5107
        stz             tcb_sema + 1
5108
wmsg13:
5109
        spl             tcb_sema + 1
5110
        ld              r7,TCB_Status,r1
5111
        or              r7,r7,#TS_WAITMSG                       ; set task status to waiting
5112
        st              r7,TCB_Status,r1
5113
        st              r6,TCB_hWaitMbx,r1                      ; set which mailbox is waited for
5114
        ld              r7,#-1
5115
        st              r7,TCB_mbq_next,r1                      ; adding at tail, so there is no next
5116
        ld              r7,MBX_TQ_HEAD,r6                       ; is there a task que setup at the mailbox ?
5117
        bmi             wmsg6
5118
        ld              r7,MBX_TQ_TAIL,r6
5119
        st              r7,TCB_mbq_prev,r1
5120
        sta             TCB_mbq_next,r7
5121
        sta             MBX_TQ_TAIL,r6
5122
        inc             MBX_TQ_COUNT,r6                         ; increment number of tasks queued
5123
wmsg7:
5124
        stz             tcb_sema + 1
5125
        stz             mbx_sema + 1
5126
        cmp             r2,#0                                           ; check for a timeout
5127
        beq             wmsg10
5128
wmsg14:
5129
        spl             tcb_sema + 1
5130
        jsr             AddToTimeoutList
5131
        stz             tcb_sema + 1
5132
        int             #2      ;       GoReschedule                    ; invoke the scheduler
5133
wmsg10:
5134
        ; At this point either a message was sent to the task, or the task
5135
        ; timed out. If a message is still not available then the task must
5136
        ; have timed out. Return a timeout error.
5137
        ; Note that SendMsg will directly set the message D1, D2 data
5138
        ; without queing a message at the mailbox (if there is a task
5139
        ; waiting already). So we cannot just try dequeing a message again.
5140
        ldx             TCB_MSG_D1,r1
5141
        ldy             TCB_MSG_D2,r1
5142
        ld              r4,TCB_Status,r1
5143
        bit             r4,#TS_WAITMSG  ; Is the task still waiting for a message ?
5144
        beq             wmsg8                   ; If not, go return OK status
5145
        pop             r7                              ; Otherwise return timeout error
5146
        pop             r6
5147
        pop             r5
5148
        pop             r4
5149
        lda             #E_Timeout
5150
        rts
5151
 
5152
        ; Here there were no prior tasks queued at the mailbox
5153
wmsg6:
5154
        ld              r7,#-1
5155
        st              r7,TCB_mbq_prev,r1              ; no previous tasks
5156
        st              r7,TCB_mbq_next,r1
5157
        sta             MBX_TQ_HEAD,r6                  ; set both head and tail indexes
5158
        sta             MBX_TQ_TAIL,r6
5159
        ld              r7,#1
5160
        st              r7,MBX_TQ_COUNT,r6              ; one task queued
5161
        bra             wmsg7                                   ; check for a timeout value
5162
 
5163
wmsg3:
5164
        stz             mbx_sema + 1
5165
        ldx             MSG_D1,r1
5166
        ldy             MSG_D2,r1
5167
        ; Add the newly dequeued message to the free messsage list
5168
wmsg5:
5169
        spl             freemsg_sema + 1
5170
        ld              r7,FreeMsg
5171
        st              r7,MSG_LINK,r1
5172
        sta             FreeMsg
5173
        inc             nMsgBlk
5174
        stz             freemsg_sema + 1
5175
wmsg8:
5176
        pop             r7
5177
        pop             r6
5178
        pop             r5
5179
        pop             r4
5180
        lda             #E_Ok
5181
        rts
5182
wmsg1:
5183
        lda             #E_BadMbx
5184
        rts
5185
wmsg2:
5186
        stz             mbx_sema + 1
5187
        pop             r7
5188
        pop             r6
5189
        pop             r5
5190
        pop             r4
5191
        lda             #E_NotAlloc
5192
        rts
5193
 
5194
;------------------------------------------------------------------------------
5195
; Check for a message at a mailbox. Does not block. This function is a
5196
; convenience wrapper for CheckMsg().
5197
;
5198
; Parameters
5199
;       r1=mailbox handle
5200
; Returns:
5201
;       r1=E_Ok                 if everything is ok
5202
;       r1=E_NoMsg              if no message is available
5203
;       r1=E_BadMbx             for a bad mailbox number
5204
;       r1=E_NotAlloc   for a mailbox that isn't allocated
5205
;       r2=message D1
5206
;       r3=message D2
5207
;------------------------------------------------------------------------------
5208
;
5209
PeekMsg:
5210
        ld              r2,#0           ; don't remove from queue
5211
        jsr             CheckMsg
5212
        rts
5213
 
5214
;------------------------------------------------------------------------------
5215
; CheckMsg
5216
; Check for a message at a mailbox. Does not block.
5217
;
5218
; Parameters
5219
;       r1=mailbox handle
5220
;       r2=remove from queue if present
5221
; Returns:
5222
;       r1=E_Ok                 if everything is ok
5223
;       r1=E_NoMsg              if no message is available
5224
;       r1=E_BadMbx             for a bad mailbox number
5225
;       r1=E_NotAlloc   for a mailbox that isn't allocated
5226
;       r2=message D1
5227
;       r3=message D2
5228
;------------------------------------------------------------------------------
5229
CheckMsg:
5230
        cmp             #NR_MBX                                 ; check the mailbox number to make sure
5231
        bhs             cmsg1                                   ; that it's sensible
5232
        push    r4
5233
        push    r5
5234
 
5235
        spl             mbx_sema + 1
5236
        ld              r5,MBX_OWNER,r1
5237
        bmi             cmsg2                                   ; error: no owner
5238
        cpx             #0                                              ; are we to dequeue the message ?
5239
        php
5240
        beq             cmsg3
5241
        jsr             DequeueMsgFromMbx
5242
        bra             cmsg4
5243
cmsg3:
5244
        lda             MBX_MQ_HEAD,r1                  ; peek the message at the head of the messages queue
5245
cmsg4:
5246
        cmp             #0
5247
        bmi             cmsg5
5248
        ldx             MSG_D1,r1
5249
        ldy             MSG_D2,r1
5250
        plp                                                             ; get back dequeue flag
5251
        beq             cmsg8
5252
cmsg10:
5253
        spl             freemsg_sema + 1
5254
        ld              r5,FreeMsg
5255
        st              r5,MSG_LINK,r1
5256
        sta             FreeMsg
5257
        inc             nMsgBlk
5258
        stz             freemsg_sema + 1
5259
cmsg8:
5260
        stz             mbx_sema + 1
5261
        pop             r5
5262
        pop             r4
5263
        lda             #E_Ok
5264
        rts
5265
cmsg1:
5266
        lda             #E_BadMbx
5267
        rts
5268
cmsg2:
5269
        stz             mbx_sema + 1
5270
        pop             r5
5271
        pop             r4
5272
        lda             #E_NotAlloc
5273
        rts
5274
cmsg5:
5275
        stz             mbx_sema + 1
5276
        pop             r5
5277
        pop             r4
5278
        lda             #E_NoMsg
5279
        rts
5280
 
5281
;------------------------------------------------------------------------------
5282
; Spinlock interrupt
5283
;       Go reschedule tasks if a spinlock is taking too long.
5284
;------------------------------------------------------------------------------
5285
;
5286
spinlock_irq:
5287
        cli
5288
        ld              r0,tcb_sema + 1
5289
        beq             spi1
5290
        cld
5291
        pusha
5292
        bra             resched1
5293
spi1:
5294
        rti
5295
 
5296
;------------------------------------------------------------------------------
5297
; System Call Interrupt
5298
;
5299
; The system call is executed using the caller's system stack.
5300
;
5301
; Stack Frame
5302
; 4,sp:  return address
5303
; 3,sp:  status register
5304
; 2,sp:  r6 save
5305
; 1,sp:  r7 save
5306
; 0,sp:  r8 save
5307
;------------------------------------------------------------------------------
5308
;
5309
syscall_int:
5310
        cli
5311
        cld
5312
        push    r6                                      ; save off some working registers
5313
        push    r7
5314
        push    r8
5315
        ld              r6,4,sp                         ; get return address into r6
5316
        lb              r7,0,r6                         ; get static call number parameter into r7
5317
        inc             r6                                      ; update return address
5318
        st              r6,4,sp
5319
;       tsr             sp,r8                           ; save off stack pointer
5320
;       ld              r6,RunningTCB           ; load the stack pointer with the system call
5321
;       ld              r6,TCB_StackTop,r6      ; stack area
5322
;       trs             r6,sp
5323
        ld              r6,(syscall_vectors>>2),r7      ; load the vector into r6
5324
        jsr             (r6)                            ; do the system function
5325
;       trs             r8,sp                           ; restore the stack pointer
5326
        pop             r8
5327
        pop             r7
5328
        pop             r6
5329
        rti
5330
 
5331
;------------------------------------------------------------------------------
5332
; Reschedule tasks to run without affecting the timeout list timing.
5333
;------------------------------------------------------------------------------
5334
;
5335
reschedule:
5336
        cli             ; enable interrupts
5337
        cld             ; clear extended precision mode
5338
 
5339
        pusha   ; save off regs on the stack
5340
        spl             tcb_sema + 1
5341
resched1:
5342
        ldx             RunningTCB
5343
        tsa
5344
        sta             TCB_SPSave,x    ; save stack pointer in TCB
5345
        tsr             sp8,r1                  ; and the eight bit mode stack pointer
5346
        sta             TCB_SP8Save,x
5347
        tsr             abs8,r1
5348
        sta             TCB_ABS8Save,x  ; 8 bit emulation base register
5349
        lda             #TS_RUNNING_BIT ; clear RUNNING status (bit #3)
5350
        bmc             TCB_Status,x
5351
;       lda             TCB_StackTop,x  ; switch to the system call stack
5352
;       tas
5353
        jmp             SelectTaskToRun
5354
 
5355
 
5356
strStartQue:
5357
        db              0,0,0,1,0,0,0,2,0,1,0,3,0,0,0,4
5358
;       db              0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
5359
 
5360
;------------------------------------------------------------------------------
5361
; 100 Hz interrupt
5362
; - takes care of "flashing" the cursor
5363
; - decrements timeouts for tasks on timeout list
5364
; - switching tasks
5365
;------------------------------------------------------------------------------
5366
;
5367
MTKTick:
5368
        pha
5369
        lda             #3                              ; reset the edge sense circuit
5370
        sta             PIC_RSTE
5371
        pla
5372
        inc             IRQFlag
5373
        ; Try and aquire the ready list and tcb. If unsuccessful it means there is
5374
        ; a system function in the process of updating the list. All we can do is
5375
        ; return to the system function and let it complete whatever it was doing.
5376
        ; As if we don't return to the system function we will be deadlocked.
5377
        ; The tick will be deferred; however if the system function was busy updating
5378
        ; the ready list, in all likelyhood it's about to call the reschedule
5379
        ; interrupt.
5380
        ld              r0,tcb_sema+1
5381
        bne             p100Hz11
5382
        inc             missed_ticks
5383
        rti
5384
p100Hz11:
5385
        cli
5386
        cld             ; clear extended precision mode
5387
 
5388
        pusha   ; save off regs on the stack
5389
        lda             #96
5390
        sta             LEDS
5391
        lda             UserTick
5392
        beq             p100Hz4
5393
        jsr             (r1)
5394
        cli
5395
p100Hz4:
5396
 
5397
        ldx             RunningTCB
5398
        tsa                                             ; save off the stack pointer
5399
        sta             TCB_SPSave,x
5400
        tsr             sp8,r1                  ; and the eight bit mode stack pointer
5401
        sta             TCB_SP8Save,x
5402
        tsr             abs8,r1
5403
        sta             TCB_ABS8Save,x  ; 8 bit emulation base register
5404
        lda             #TS_RUNNING_BIT
5405
        bmc             TCB_Status,x
5406
        lda             #97
5407
        sta             LEDS
5408
 
5409
        ; Check the timeout list to see if there are items ready to be removed from
5410
        ; the list. Also decrement the timeout of the item at the head of the list.
5411
p100Hz15:
5412
        ldx             TimeoutList
5413
        bmi             p100Hz12                                ; are there any entries in the timeout list ?
5414
        lda             TCB_Timeout,x
5415
        bgt             p100Hz14                                ; has this entry timed out ?
5416
        PopTimeoutList
5417
        jsr             AddTaskToReadyList
5418
        bra             p100Hz15                                ; go back and see if there's another task to be removed
5419
                                                                        ; there could be a string of tasks to make ready.
5420
p100Hz14:
5421
        dea                                                             ; decrement the entry's timeout
5422
        sub             r1,r1,missed_ticks              ; account for any missed ticks
5423
        stz             missed_ticks
5424
        sta             TCB_Timeout,x
5425
 
5426
p100Hz12:
5427
        ; Falls through into selecting a task to run
5428
tck3:
5429
        lda             #98
5430
        sta             LEDS
5431
;------------------------------------------------------------------------------
5432
; Search the ready queues for a ready task.
5433
; The search is occasionally started at a lower priority queue in order
5434
; to prevent starvation of lower priority tasks. This is managed by
5435
; using a tick count as an index to a string containing the start que.
5436
;------------------------------------------------------------------------------
5437
;
5438
SelectTaskToRun:
5439
        ld              r6,#5                   ; number of queues to search
5440
        ldy             IRQFlag                 ; use the IRQFlag as a buffer index
5441
;       lsr             r3,r3,#1                ; the LSB is always the same
5442
        and             r3,r3,#$0F              ; counts from 0 to 15
5443
        lb              r3,strStartQue,y        ; get the queue to start search at
5444
sttr2:
5445
        lda             QNdx0,y
5446
        bmi             sttr1
5447
        lda             TCB_NxtRdy,r1           ; Advance the queue index
5448
        sta             QNdx0,y
5449
        ; This is the only place the RunningTCB is set (except for initialization).
5450
        sta             RunningTCB
5451
        tax
5452
        lda             #TS_RUNNING_BIT
5453
        bms             TCB_Status,x            ; flag the task as the running task
5454
        lda             #99
5455
        sta             LEDS
5456
        lda             TCB_ABS8Save,x          ; 8 bit emulation base register
5457
        trs             r1,abs8
5458
        lda             TCB_SP8Save,x           ; get back eight bit stack pointer
5459
        trs             r1,sp8
5460
        ldx             TCB_SPSave,x            ; get back stack pointer
5461
        txs
5462
        lda             #1
5463
        sta             tcb_sema
5464
        ld              r0,iof_switch
5465
        beq             sttr6
5466
        ld              r0,iof_sema + 1         ; just ignore the request to switch
5467
        beq             sttr6                           ; I/O focus if the semaphore can't be aquired
5468
        stz             iof_switch
5469
        jsr             SwitchIOFocus
5470
        stz             iof_sema + 1
5471
sttr6:
5472
        popa                                            ; restore registers
5473
        rti
5474
 
5475
        ; Set index to check the next ready list for a task to run
5476
sttr1:
5477
        iny
5478
        cpy             #5
5479
        bne             sttr5
5480
        ldy             #0
5481
sttr5:
5482
        dec             r6
5483
        bne             sttr2
5484
 
5485
        ; Here there were no tasks ready
5486
        ; This should not be able to happen, so hang the machine (in a lower
5487
        ; power mode).
5488
sttr3:
5489
        ldx             #94
5490
        stx             LEDS
5491
        jsr             kernel_panic
5492
        db              "No tasks in ready queue.",0
5493
        ; Might as well power down the clock and wait for a reset or
5494
        ; NMI. In the case of an NMI the kernel is reinitialized without
5495
        ; doing the boot reset.
5496
        stp
5497
        jmp             MTKInitialize
5498
 
5499
;------------------------------------------------------------------------------
5500
; kernal_panic:
5501
;       All this does right now is display the panic message on the screen.
5502
; Parameters:
5503
;       inline: string
5504
;------------------------------------------------------------------------------
5505
;
5506
kernel_panic:
5507
        pla                                     ; pop the return address off the stack
5508
        push    r4                      ; save off r4
5509
        ld              r4,r1
5510
kpan2:
5511
        lb              r1,0,r4         ; get a byte from the code space
5512
        add             r4,#1           ; increment pointer
5513
        and             #$FF            ; we want only eight bits
5514
        beq             kpan1                   ; is it end of string ?
5515
        jsr             DisplayChar
5516
        bra             kpan2
5517
kpan1:                                          ; must update the return address !
5518
        jsr             CRLF
5519
        ld              r1,r4           ; get return address into acc
5520
        pop             r4                      ; restore r4
5521
        jmp             (r1)
5522
 
5523
include "DeviceDriver.asm"
5524
 
5525
;------------------------------------------------------------------
5526
;------------------------------------------------------------------
5527
include "Test816.asm"
5528
include "pi_calc816.asm"
5529
 
5530
;------------------------------------------------------------------
5531
; Kind of a chicken and egg problem here. If there is something
5532
; wrong with the processor, then this code likely won't execute.
5533
;
5534
 
5535
; put message to screen
5536
; tests pla,sta,ldy,inc,bne,ora,jmp,jmp(abs)
5537
 
5538
putmsg
5539
        pla                                     ; pop the return address off the stack
5540
        wdm                                     ; switch to 32 bits
5541
        xce
5542
        cpu             RTF65002
5543
        push    r4                      ; save off r4
5544
        or              r4,r1,#$FFFF0000        ; set program bank bits; code is at $FFFFxxxx
5545
pm2
5546
        add             r4,#1           ; increment pointer
5547
        lb              r1,0,r4         ; get a byte from the code space
5548
        and             #$FF            ; we want only eight bits
5549
        beq             pm1                     ; is it end of string ?
5550
        jsr             DisplayChar
5551
        jmp             pm2
5552
pm1                                             ; must update the return address !
5553
        ld              r1,r4           ; get return address into acc
5554
        pop             r4                      ; restore r4
5555
        clc                                     ; switch back to '816 mode
5556
        xce
5557
        cpu             W65C816S
5558
        rep             #$30            ; mem,ndx = 16 bits
5559
        pha
5560
        rts
5561
 
5562
        cpu             RTF65002
5563
;------------------------------------------------------------------
5564
; This test program just loop around waiting to recieve a message.
5565
; The message is a pointer to a string to display.
5566
;------------------------------------------------------------------
5567
;
5568
test_mbx_prg:
5569
        jsr             RequestIOFocus
5570
        lda             #test_mbx       ; where to put mailbox handle
5571
        int             #4
5572
        db              6                       ; AllocMbx
5573
        ldx             #5
5574
        jsr             PRTNUM
5575
;       mStartTask      #PRI_LOWEST,#0,#test_mbx_prg2,#0,#0
5576
        lda             #PRI_LOWEST
5577
        ldx             #0
5578
        ldy             #test_mbx_prg2
5579
        ld              r4,#0
5580
        ld              r5,#1
5581
        int             #4
5582
        db              1                       ; StartTask
5583
tmp2:
5584
        lda             test_mbx
5585
        ldx             #100
5586
        int             #4
5587
        db              10                      ; WaitMsg
5588
        cmp             #E_Ok
5589
        bne             tmp1
5590
        txa
5591
        jsr             DisplayStringB
5592
        bra             tmp2
5593
tmp1:
5594
        ldx             #4
5595
        jsr             PRTNUM
5596
        bra             tmp2
5597
 
5598
test_mbx_prg2:
5599
tmp2a:
5600
        lda             test_mbx
5601
        ldx             #msg_hello
5602
        ldy             #0
5603
        int             #4
5604
        db              8                       ; PostMsg
5605
        bra             tmp2a
5606
msg_hello:
5607
        db              "Hello from RTF",13,10,0
5608
 
5609
message "DOS.asm"
5610
include "DOS.asm"
5611
 
5612
        cpu             RTF65002
5613
 
5614 15 robfinch
message "1298"
5615
include "TinyBasic65002.asm"
5616 18 robfinch
message "1640"
5617 11 robfinch
        org $0FFFFFFF4          ; NMI vector
5618
        dw      nmirout
5619
 
5620
        org     $0FFFFFFF8              ; reset vector, native mode
5621
        dw      start
5622
 
5623
        end
5624
 

powered by: WebSVN 2.1.0

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