Changeset 4f508e6 in buchla-68k
- Timestamp:
- 07/01/2017 02:34:46 PM (7 years ago)
- Branches:
- master
- Children:
- 08e1da1
- Parents:
- f40a309
- Files:
-
- 2 added
- 50 edited
Legend:
- Unmodified
- Added
- Removed
-
iolib/hwdefs.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *hwdefs.s -- External definitions of Buchla 700 I/O addresses3 *Version 14 -- 1988-08-15 -- D.N. Lynx Crowe4 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | hwdefs.s -- External definitions of Buchla 700 I/O addresses 3 | Version 14 -- 1988-08-15 -- D.N. Lynx Crowe 4 | ------------------------------------------------------------------------------ 5 5 .text 6 * 6 7 7 .xdef _io_time,_io_lcd,_io_ser,_io_midi 8 8 .xdef _io_disk,_io_tone,_io_leds,_io_kbrd 9 9 .xdef _io_vreg,_io_vraw,_io_vram,_io_fpu 10 10 .xdef _lcd_a0,_lcd_a1 11 * 11 12 12 .xdef _v_regs,_v_odtab,_v_actab 13 13 .xdef _v_ct0 14 14 .xdef _v_gt1 15 15 .xdef _v_score,_v_cgtab 16 * 16 17 17 .xdef _v_curs0,_v_curs1,_v_curs2,_v_curs3 18 18 .xdef _v_curs4,_v_curs5,_v_curs6,_v_curs7 … … 20 20 .xdef _v_win0 21 21 .xdef _v_cur 22 * 22 23 23 .xdef _fc_sw,_fc_val 24 * 25 *------------------------------------------------------------------------------26 * 27 *Hardware base addresses28 *-----------------------29 _io_fpu .equ $180000 *FPU base address30 * 31 VB .equ $200000 *VSDD base address32 * 33 _io_time .equ $3A0001 *Timer chip34 _io_lcd .equ $3A4001 *LCD controller35 _io_ser .equ $3A8001 *Serial ports (RS232)36 _io_midi .equ $3AC001 *MIDI ports37 _io_disk .equ $3B0001 *Disk controller38 _io_tone .equ $3B4001 *Sound generator chip39 _io_leds .equ $3B8001 *LED driver40 _io_kbrd .equ $3BC001 *Keyboard / panel processor41 * 42 _lcd_a0 .equ _io_lcd *LCD port a043 _lcd_a1 .equ _io_lcd+2 *LCD port a144 * 24 25 | ------------------------------------------------------------------------------ 26 27 | Hardware base addresses 28 | ----------------------- 29 _io_fpu = 0x180000 | FPU base address 30 31 VB = 0x200000 | VSDD base address 32 33 _io_time = 0x3A0001 | Timer chip 34 _io_lcd = 0x3A4001 | LCD controller 35 _io_ser = 0x3A8001 | Serial ports (RS232) 36 _io_midi = 0x3AC001 | MIDI ports 37 _io_disk = 0x3B0001 | Disk controller 38 _io_tone = 0x3B4001 | Sound generator chip 39 _io_leds = 0x3B8001 | LED driver 40 _io_kbrd = 0x3BC001 | Keyboard / panel processor 41 42 _lcd_a0 = _io_lcd | LCD port a0 43 _lcd_a1 = _io_lcd+2 | LCD port a1 44 45 45 .page 46 * 47 *Video definitions48 *-----------------49 _io_vreg .equ VB *Relocated video registers after setup50 _io_vraw .equ VB+$400 *Raw video registers at RESET51 _io_vram .equ VB *Video RAM base address52 * 53 *Name Offset Usage Bank54 *------- --------- ------------------------- ----55 _v_regs .equ VB *Video registers 0,156 * 57 _v_odtab .equ VB+128 *Object Descriptor Table 058 _v_actab .equ VB+256 *Access Table 059 _v_ct0 .equ VB+1024 *Character Text-0 060 _v_gt1 .equ VB+1304 *Graphics Text-1 061 _v_score .equ VB+8192 *Score object 062 _v_cgtab .equ VB+122880 *Character Generator Table 063 * 64 _v_curs0 .equ VB+1024 *Cursor object 0 (arrow ULE) 165 _v_curs1 .equ VB+1152 *Cursor object 1 (arrow ULO) 166 _v_curs2 .equ VB+1280 *Cursor object 2 (arrow URE) 167 _v_curs3 .equ VB+1408 *Cursor object 3 (arrow URO) 168 _v_curs4 .equ VB+1536 *Cursor object 4 (arrow LLE) 169 _v_curs5 .equ VB+1664 *Cursor object 5 (arrow LLO) 170 _v_curs6 .equ VB+1792 *Cursor object 6 (arrow LRE) 171 _v_curs7 .equ VB+1920 *Cursor object 7 (arrow LRO) 172 _v_tcur .equ VB+2048 *Typewriter cursor 173 _v_kbobj .equ VB+2880 *Keyboard object 174 _v_lnobj .equ VB+4672 *Line object 175 _v_cur .equ VB+6464 *Underline cursor 176 _v_win0 .equ VB+16384 *Window-0 object 177 * 78 *BIOS RAM definitions79 *--------------------80 *WARNING: the following addresses must match those of the corresponding81 *variables defined in bios.s or chaos is guaranteed.82 * 83 _fc_sw .equ $420 *word - Frame counter switch84 _fc_val .equ $422 *long - Frame counter value85 * 46 47 | Video definitions 48 | ----------------- 49 _io_vreg = VB | Relocated video registers after setup 50 _io_vraw = VB+0x400 | Raw video registers at RESET 51 _io_vram = VB | Video RAM base address 52 53 | Name Offset Usage Bank 54 | ------- --------- ------------------------- ---- 55 _v_regs = VB | Video registers 0,1 56 57 _v_odtab = VB+128 | Object Descriptor Table 0 58 _v_actab = VB+256 | Access Table 0 59 _v_ct0 = VB+1024 | Character Text-0 0 60 _v_gt1 = VB+1304 | Graphics Text-1 0 61 _v_score = VB+8192 | Score object 0 62 _v_cgtab = VB+122880 | Character Generator Table 0 63 64 _v_curs0 = VB+1024 | Cursor object 0 (arrow ULE) 1 65 _v_curs1 = VB+1152 | Cursor object 1 (arrow ULO) 1 66 _v_curs2 = VB+1280 | Cursor object 2 (arrow URE) 1 67 _v_curs3 = VB+1408 | Cursor object 3 (arrow URO) 1 68 _v_curs4 = VB+1536 | Cursor object 4 (arrow LLE) 1 69 _v_curs5 = VB+1664 | Cursor object 5 (arrow LLO) 1 70 _v_curs6 = VB+1792 | Cursor object 6 (arrow LRE) 1 71 _v_curs7 = VB+1920 | Cursor object 7 (arrow LRO) 1 72 _v_tcur = VB+2048 | Typewriter cursor 1 73 _v_kbobj = VB+2880 | Keyboard object 1 74 _v_lnobj = VB+4672 | Line object 1 75 _v_cur = VB+6464 | Underline cursor 1 76 _v_win0 = VB+16384 | Window-0 object 1 77 78 | BIOS RAM definitions 79 | -------------------- 80 | WARNING: the following addresses must match those of the corresponding 81 | variables defined in bios.s or chaos is guaranteed. 82 83 _fc_sw = 0x420 | word - Frame counter switch 84 _fc_val = 0x422 | long - Frame counter value 85 86 86 .end -
iolib/rtraps.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *rtraps.s -- define ROMP debug trap3 *Version 7 -- 1988-01-12 -- Copyright 1987, 1988 by D.N. Lynx Crowe4 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | rtraps.s -- define ROMP debug trap 3 | Version 7 -- 1988-01-12 -- Copyright 1987, 1988 by D.N. Lynx Crowe 4 | ------------------------------------------------------------------------------ 5 5 .text 6 * 6 7 7 .xdef _trap15 8 * 8 9 9 .xref _rompbp 10 * 10 11 11 .xref tr1sav,tr13sav,tr14sav 12 12 .xref tr1rmp,tr13rmp,tr14rmp 13 * 14 BUCHLA .equ 1 *IPL value: 0 = NASA , 1 = Buchla15 * 13 14 BUCHLA = 1 | IPL value: 0 = NASA , 1 = Buchla 15 16 16 .ifeq BUCHLA 17 IPLEVEL .equ $0400 *NASA IPL = 4 (enable 5 and above)17 IPLEVEL = 0x0400 | NASA IPL = 4 (enable 5 and above) 18 18 .endc 19 * 19 20 20 .ifne BUCHLA 21 IPLEVEL .equ $0200 *Buchla IPL = 2 (enable 3 and above)21 IPLEVEL = 0x0200 | Buchla IPL = 2 (enable 3 and above) 22 22 .endc 23 * 24 IPL7 .equ $0700 *IPL 725 * 26 *_trap15 -- ROMP debug trap (used to implement breakpoints)27 *------- ------------------------------------------------28 _trap15: ori.w #IPL7,sr *Disable interrupts29 move.w #0,-(a7) *Keep stack long aligned30 movem.l d0-d7/a0-a7,-(a7) *Save regs on stack31 move.l tr1sav,tr1rmp *Save trap save areas32 move.l tr13sav,tr13rmp *...33 move.l tr14sav,tr14rmp *...34 move.w sr,d0 *Get status register35 andi.w # $F8FF,d0 *Enable serial I/O interrupts36 ori.w #IPLEVEL,d0 *...37 move.w d0,sr *...38 jsr _rompbp *Pass control to ROMP39 * 40 ori.w #IPL7,sr *Disable interrupts41 move.l tr14rmp,tr14sav *Restore trap save areas42 move.l tr13rmp,tr13sav *...43 move.l tr1rmp,tr1sav *...44 movem.l (a7)+,d0-d7/a0-a7 *Restore regs45 addq.l #2,a7 *Discard alignment filler word46 rte *Back to what we interrupted47 * 23 24 IPL7 = 0x0700 | IPL 7 25 26 | _trap15 -- ROMP debug trap (used to implement breakpoints) 27 | ------- ------------------------------------------------ 28 _trap15: ori.w #IPL7,sr | Disable interrupts 29 move.w #0,-(a7) | Keep stack long aligned 30 movem.l d0-d7/a0-a7,-(a7) | Save regs on stack 31 move.l tr1sav,tr1rmp | Save trap save areas 32 move.l tr13sav,tr13rmp | ... 33 move.l tr14sav,tr14rmp | ... 34 move.w sr,d0 | Get status register 35 andi.w #0xF8FF,d0 | Enable serial I/O interrupts 36 ori.w #IPLEVEL,d0 | ... 37 move.w d0,sr | ... 38 jsr _rompbp | Pass control to ROMP 39 40 ori.w #IPL7,sr | Disable interrupts 41 move.l tr14rmp,tr14sav | Restore trap save areas 42 move.l tr13rmp,tr13sav | ... 43 move.l tr1rmp,tr1sav | ... 44 movem.l (a7)+,d0-d7/a0-a7 | Restore regs 45 addq.l #2,a7 | Discard alignment filler word 46 rte | Back to what we interrupted 47 48 48 .end -
iolib/setipl.s
rf40a309 r4f508e6 1 * 2 *setipl.s -- Set internal processor interrupt level3 *-------- --------------------------------------4 *Version 2 -- 1988-06-29 -- D.N. Lynx Crowe5 * 6 *short7 *setipl(arg);8 *short arg;9 * 10 *Sets processor interrupt level to arg.11 *Returns old interrupt level, or -1 if arg < 0 or > 712 * 13 *Assumes you are in supervisor mode.14 *You get a Privelege Violation TRAP if you aren't.15 * 1 2 | setipl.s -- Set internal processor interrupt level 3 | -------- -------------------------------------- 4 | Version 2 -- 1988-06-29 -- D.N. Lynx Crowe 5 6 | short 7 | setipl(arg); 8 | short arg; 9 10 | Sets processor interrupt level to arg. 11 | Returns old interrupt level, or -1 if arg < 0 or > 7 12 13 | Assumes you are in supervisor mode. 14 | You get a Privelege Violation TRAP if you aren't. 15 16 16 .text 17 * 17 18 18 .xdef _setipl 19 * 20 _setipl: link a6,#0 *Link up stack frames21 move.w 8(a6),d0 *Get argument22 tst.w d0 *Check lower limit23 bmi setipler *Jump if < 0 (error)24 * 25 cmpi.w #7,d0 *Check upper limit26 bgt setipler *Jump if > 7 (error)27 * 28 move.w sr,d1 *Get current level29 move.w d1,d2 *... save for later30 lsl.w #8,d0 *Shift argument into position31 andi.w # $F8FF,d1 *Mask out old level32 or.w d0,d1 *OR in new level33 move.w d2,d0 *Setup return of old level34 lsr.w #8,d0 *...35 andi.l # $7,d0 *...36 move.w d1,sr *Set the new interrupt level37 unlk a6 *Unlink stack frames38 rts *Return to caller39 * 40 setipler: moveq.l #-1,d0 *Setup to return error code41 unlk a6 *Unlink stack frames42 rts *Return to caller43 * 19 20 _setipl: link a6,#0 | Link up stack frames 21 move.w 8(a6),d0 | Get argument 22 tst.w d0 | Check lower limit 23 bmi setipler | Jump if < 0 (error) 24 25 cmpi.w #7,d0 | Check upper limit 26 bgt setipler | Jump if > 7 (error) 27 28 move.w sr,d1 | Get current level 29 move.w d1,d2 | ... save for later 30 lsl.w #8,d0 | Shift argument into position 31 andi.w #0xF8FF,d1 | Mask out old level 32 or.w d0,d1 | OR in new level 33 move.w d2,d0 | Setup return of old level 34 lsr.w #8,d0 | ... 35 andi.l #0x7,d0 | ... 36 move.w d1,sr | Set the new interrupt level 37 unlk a6 | Unlink stack frames 38 rts | Return to caller 39 40 setipler: moveq.l #-1,d0 | Setup to return error code 41 unlk a6 | Unlink stack frames 42 rts | Return to caller 43 44 44 .end -
iolib/setsr.s
rf40a309 r4f508e6 1 * 2 *setsr.s -- Set processor status register3 *------- -----------------------------4 *Version 1 -- 1988-06-29 -- D.N. Lynx Crowe5 * 6 *short7 *setsr(arg);8 *short arg;9 * 10 *Sets processor status register to 'arg'.11 *Returns old status register value.12 * 13 *Assumes you are in supervisor mode.14 *You get a Privelege Violation TRAP if you aren't.15 * 16 *Coded for speed -- this is as fast as you can get.17 *No error checking is done -- assumes you know what you're doing.18 * 1 2 | setsr.s -- Set processor status register 3 | ------- ----------------------------- 4 | Version 1 -- 1988-06-29 -- D.N. Lynx Crowe 5 6 | short 7 | setsr(arg); 8 | short arg; 9 10 | Sets processor status register to 'arg'. 11 | Returns old status register value. 12 13 | Assumes you are in supervisor mode. 14 | You get a Privelege Violation TRAP if you aren't. 15 16 | Coded for speed -- this is as fast as you can get. 17 | No error checking is done -- assumes you know what you're doing. 18 19 19 .text 20 * 20 21 21 .xdef _setsr 22 * 23 _setsr: move.w sr,d0 *Get current sr24 move.w 4(sp),sr *Set new sr25 rts *Return to caller26 * 22 23 _setsr: move.w sr,d0 | Get current sr 24 move.w 4(sp),sr | Set new sr 25 rts | Return to caller 26 27 27 .end -
iolib/traps.s
rf40a309 r4f508e6 1 * 2 *traps.s -- define trap linkages for C routines3 *------- -----------------------------------4 *Version 8 -- 1987-06-08 -- D.N. Lynx Crowe5 * 6 *Caution: these are serially re-useable, but NOT reentrant, so7 *don't use them in interrupt processing code.8 * 9 *An exception is made for ROMP in _trap15 for breakpoints so that the10 *debug code can be debugged.11 * 1 2 | traps.s -- define trap linkages for C routines 3 | ------- ----------------------------------- 4 | Version 8 -- 1987-06-08 -- D.N. Lynx Crowe 5 6 | Caution: these are serially re-useable, but NOT reentrant, so 7 | don't use them in interrupt processing code. 8 9 | An exception is made for ROMP in _trap15 for breakpoints so that the 10 | debug code can be debugged. 11 12 12 .text 13 * 13 14 14 .xdef _trap1 15 15 .xdef _trap13,_trap14 16 16 .xdef _xtrap15 17 * 17 18 18 .xdef tr1sav,tr13sav,tr14sav 19 19 .xdef tr1rmp,tr13rmp,tr14rmp 20 * 21 *_trap1 -- provide access to BDOS functions22 *------ --------------------------------23 _trap1: move.l (a7)+,tr1sav *Save return address24 trap #1 *Do the trap25 move.l tr1sav,-(a7) *Restore return address26 rts *Return to caller27 * 28 *_trap13 -- provide access to BIOS functions29 *------- --------------------------------30 _trap13: move.l (a7)+,tr13sav *Save return address31 trap #13 *Do the trap32 move.l tr13sav,-(a7) *Restore return address33 rts *Return to caller34 * 35 *_trap14 -- provide access to extended BIOS functions36 *------- -----------------------------------------37 _trap14: move.l (a7)+,tr14sav *Save return address38 trap #14 *Do the trap39 move.l tr14sav,-(a7) *Restore return address40 rts *Return to caller41 * 42 *_xtrap15 -- Setup initial register trap for ROMP43 *-------- ------------------------------------44 _xtrap15: trap #15 *TRAP into ROMP45 rts *Return (usually won't happen)46 * 20 21 | _trap1 -- provide access to BDOS functions 22 | ------ -------------------------------- 23 _trap1: move.l (a7)+,tr1sav | Save return address 24 trap #1 | Do the trap 25 move.l tr1sav,-(a7) | Restore return address 26 rts | Return to caller 27 28 | _trap13 -- provide access to BIOS functions 29 | ------- -------------------------------- 30 _trap13: move.l (a7)+,tr13sav | Save return address 31 trap #13 | Do the trap 32 move.l tr13sav,-(a7) | Restore return address 33 rts | Return to caller 34 35 | _trap14 -- provide access to extended BIOS functions 36 | ------- ----------------------------------------- 37 _trap14: move.l (a7)+,tr14sav | Save return address 38 trap #14 | Do the trap 39 move.l tr14sav,-(a7) | Restore return address 40 rts | Return to caller 41 42 | _xtrap15 -- Setup initial register trap for ROMP 43 | -------- ------------------------------------ 44 _xtrap15: trap #15 | TRAP into ROMP 45 rts | Return (usually won't happen) 46 47 47 .page 48 * 49 *RAM storage areas50 *-----------------48 49 | RAM storage areas 50 | ----------------- 51 51 .bss 52 52 .even 53 * 54 tr1sav: ds.l 1 *Return address for trap155 tr13sav: ds.l 1 *Return address for trap1356 tr14sav: ds.l 1 *Return address for trap1457 * 58 tr1rmp: ds.l 1 *Save area for tr1sav for ROMP59 tr13rmp: ds.l 1 *Save area for tr13sav for ROMP60 tr14rmp: ds.l 1 *Save area for tr14sav for ROMP61 * 53 54 tr1sav: ds.l 1 | Return address for trap1 55 tr13sav: ds.l 1 | Return address for trap13 56 tr14sav: ds.l 1 | Return address for trap14 57 58 tr1rmp: ds.l 1 | Save area for tr1sav for ROMP 59 tr13rmp: ds.l 1 | Save area for tr13sav for ROMP 60 tr14rmp: ds.l 1 | Save area for tr14sav for ROMP 61 62 62 .end -
lib700/aldiv.s
rf40a309 r4f508e6 1 * 2 *aldiv.s -- indirect long divide3 *Version 1 -- 1989-01-24 -- D.N. Lynx Crowe4 * 1 2 | aldiv.s -- indirect long divide 3 | Version 1 -- 1989-01-24 -- D.N. Lynx Crowe 4 5 5 .text 6 * 6 7 7 .xdef aldiv 8 8 .xdef _aldiv 9 * 9 10 10 .xref _ldiv 11 * 11 12 12 aldiv: 13 13 _aldiv: 14 * 14 15 15 link a6,#-2 16 16 move.l 12(a6),-(a7) … … 23 23 unlk a6 24 24 rts 25 * 25 26 26 .end -
lib700/almul.s
rf40a309 r4f508e6 1 * 2 *almul.s -- indirect long multiply3 *Version 1 -- 1989-01-24 -- D.N. Lynx Crowe4 * 1 2 | almul.s -- indirect long multiply 3 | Version 1 -- 1989-01-24 -- D.N. Lynx Crowe 4 5 5 .text 6 * 6 7 7 .xdef almul 8 * 8 9 9 .xref lmul 10 * 10 11 11 almul: move.l a5,-(a7) 12 12 movea.l 8(a7),a5 … … 18 18 movea.l (a7)+,a5 19 19 rts 20 * 20 21 21 .end -
lib700/alrem.s
rf40a309 r4f508e6 1 * 2 *alrem.s -- indirect long modulus3 *Version 1 -- 1989-01-24 -- D.N. Lynx Crowe4 * 1 2 | alrem.s -- indirect long modulus 3 | Version 1 -- 1989-01-24 -- D.N. Lynx Crowe 4 5 5 .text 6 * 6 7 7 .xdef alrem 8 8 .xdef _alrem 9 * 9 10 10 .xref _ldiv 11 11 .xref _ldivr 12 * 12 13 13 alrem: 14 14 _alrem: 15 * 15 16 16 link a6,#-2 17 17 move.l 12(a6),-(a7) … … 25 25 unlk a6 26 26 rts 27 * 27 28 28 .end -
lib700/blkfill.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *blkfill.s -- block fill function3 *Version 1 -- 1987-08-28 -- D.N. Lynx Crowe4 * 5 *void6 *blkfill(where, what, count)7 * char *where;8 *char what;9 *short count;10 * 11 *Fills 'count' bytes at 'where' with 'what'.12 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | blkfill.s -- block fill function 3 | Version 1 -- 1987-08-28 -- D.N. Lynx Crowe 4 5 | void 6 | blkfill(where, what, count) 7 | char |where; 8 | char what; 9 | short count; 10 11 | Fills 'count' bytes at 'where' with 'what'. 12 | ------------------------------------------------------------------------------ 13 13 .text 14 * 14 15 15 .xdef _blkfill 16 * 16 17 17 _blkfill: link a6,#0 18 18 movem.l d5-d7/a5-a5,-(a7) … … 21 21 move.w 14(a6),d6 22 22 bra blkf2 23 * 23 24 24 blkf1: move.b d7,(a5)+ 25 * 25 26 26 blkf2: move.w d6,d0 27 27 subq.w #1,d6 28 28 tst.w d0 29 29 bgt blkf1 30 * 30 31 31 tst (a7)+ 32 32 movem.l (a7)+,d6-d7/a5-a5 33 33 unlk a6 34 34 rts 35 * 35 36 36 .end -
lib700/blkmove.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *blkmove.s -- block move function3 *Version 1 -- 1987-08-28 -- D.N. Lynx Crowe4 * 5 *void6 *blkmove(to, from, n)7 * char *to, *from;8 *short n;9 * 10 *Copies 'n' bytes from address 'from' to address 'to'.11 *Treats overlaps of from and to areas intelligently.12 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | blkmove.s -- block move function 3 | Version 1 -- 1987-08-28 -- D.N. Lynx Crowe 4 5 | void 6 | blkmove(to, from, n) 7 | char |to, |from; 8 | short n; 9 10 | Copies 'n' bytes from address 'from' to address 'to'. 11 | Treats overlaps of from and to areas intelligently. 12 | ------------------------------------------------------------------------------ 13 13 .text 14 * 14 15 15 .xdef _blkmove 16 * 17 _blkmove: link a6,# $FFFC16 17 _blkmove: link a6,#-4 18 18 move.l 8(a6),d0 19 19 cmp.l 12(a6),d0 20 20 bcc blkm3 21 * 21 22 22 bra blkm2 23 * 23 24 24 blkm1: movea.l 8(a6),a0 25 25 movea.l 12(a6),a1 … … 27 27 addq.l #1,8(a6) 28 28 addq.l #1,12(a6) 29 * 29 30 30 blkm2: move.w 16(a6),d0 31 31 subq.w #1,16(a6) 32 32 tst.w d0 33 33 bne blkm1 34 * 34 35 35 bra blkm6 36 * 36 37 37 blkm3: move.w 16(a6),d0 38 38 ext.l d0 … … 40 40 add.l d0,12(a6) 41 41 bra blkm5 42 * 42 43 43 blkm4: subq.l #1,8(a6) 44 44 subq.l #1,12(a6) … … 46 46 movea.l 12(a6),a1 47 47 move.b (a1),(a0) 48 * 48 49 49 blkm5: move.w 16(a6),d0 50 50 subq.w #1,16(a6) 51 51 tst.w d0 52 52 bne blkm4 53 * 53 54 54 blkm6: unlk a6 55 55 rts 56 * 56 57 57 .end -
lib700/finalone.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *finalone.s -- the last stuff to get loaded3 *Version 4 -- 1987-06-30 -- D.N. Lynx Crowe4 * 5 *This is so we can figure out where things got loaded.6 *------------------------------------------------------------------------------7 * 1 | ------------------------------------------------------------------------------ 2 | finalone.s -- the last stuff to get loaded 3 | Version 4 -- 1987-06-30 -- D.N. Lynx Crowe 4 5 | This is so we can figure out where things got loaded. 6 | ------------------------------------------------------------------------------ 7 8 8 .text 9 * 9 10 10 .xdef FinalOne 11 11 .xdef The_Fini 12 12 .xdef Text_End 13 * 14 * 15 *This is the last piece of code in the 'text' segment.16 * 17 FinalOne: rts *we just need the address here18 * 19 Text_End: rts *we just need the address here20 * 21 *------------------------------------------------------------------------------22 * 13 14 15 | This is the last piece of code in the 'text' segment. 16 17 FinalOne: rts | we just need the address here 18 19 Text_End: rts | we just need the address here 20 21 | ------------------------------------------------------------------------------ 22 23 23 .data 24 24 .even 25 * 26 The_Fini: dc.w $FFFF *last thing in the 'data' segment27 * 28 *------------------------------------------------------------------------------29 * 25 26 The_Fini: dc.w 0xFFFF | last thing in the 'data' segment 27 28 | ------------------------------------------------------------------------------ 29 30 30 .end -
lib700/jumpto.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *jumpto.s -- miscellaneous ROMP support functions3 *Version 4 -- 1987-10-14 -- D.N. Lynx Crowe4 * 5 *WARNING:6 *--------7 *These functions, in general, assume supervisor mode and8 *'sane' arguments, so no error checking is done.9 * 10 *halt()11 * 12 *Brings the processor to a grinding halt. Requires external13 *reset to restart things. Use only for catastrophic hard halts.14 * 15 *jumpto(addr)16 *long addr;17 * 18 *Jumps to 'addr'. No error check is done on 'addr'.19 * 20 *rjumpto(addr)21 *long addr;22 * 23 *Performs the 68000 'RESET' command, then jumps to 'addr'.24 *No error check is made on 'addr'.25 * 26 *sjumpto(addr, stack)27 *long addr, stack;28 * 29 *Sets a7 to 'stack', then jumps to 'addr'.30 *No error check is done on 'addr'.31 * 32 *xreset()33 * 34 *Performs the 68000 'RESET' command. This is very dangerous,35 *and should be used with extreme care regarding such36 *things as interrupts, device initialization, vectors,37 *and sundry other reset-related things.38 * 39 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | jumpto.s -- miscellaneous ROMP support functions 3 | Version 4 -- 1987-10-14 -- D.N. Lynx Crowe 4 5 | WARNING: 6 | -------- 7 | These functions, in general, assume supervisor mode and 8 | 'sane' arguments, so no error checking is done. 9 10 | halt() 11 12 | Brings the processor to a grinding halt. Requires external 13 | reset to restart things. Use only for catastrophic hard halts. 14 15 | jumpto(addr) 16 | long addr; 17 18 | Jumps to 'addr'. No error check is done on 'addr'. 19 20 | rjumpto(addr) 21 | long addr; 22 23 | Performs the 68000 'RESET' command, then jumps to 'addr'. 24 | No error check is made on 'addr'. 25 26 | sjumpto(addr, stack) 27 | long addr, stack; 28 29 | Sets a7 to 'stack', then jumps to 'addr'. 30 | No error check is done on 'addr'. 31 32 | xreset() 33 34 | Performs the 68000 'RESET' command. This is very dangerous, 35 | and should be used with extreme care regarding such 36 | things as interrupts, device initialization, vectors, 37 | and sundry other reset-related things. 38 39 | ------------------------------------------------------------------------------ 40 40 .text 41 * 41 42 42 .xdef _halt,_jumpto,_rjumpto,_sjumpto,_xreset 43 * 43 44 44 .page 45 * 46 _halt: stop # $2700 *stop dead, interrupts disabled47 jmp _halt *stay stopped if stepped thru48 * 49 _jumpto: movea.l 4(a7),a0 *get jump address50 jmp (a0) *go to the jump address51 * 52 _rjumpto: reset *reset external devices53 movea.l 4(a7),a0 *get jump address54 jmp (a0) *go to the jump address55 * 56 _sjumpto: movea.l 4(a7),a0 *get jump address57 movea.l 8(a7),a7 *set stack pointer58 jmp (a0) *go to the jump address59 * 60 _xreset: reset *reset external devices61 rts *return to caller62 * 45 46 _halt: stop #0x2700 | stop dead, interrupts disabled 47 jmp _halt | stay stopped if stepped thru 48 49 _jumpto: movea.l 4(a7),a0 | get jump address 50 jmp (a0) | go to the jump address 51 52 _rjumpto: reset | reset external devices 53 movea.l 4(a7),a0 | get jump address 54 jmp (a0) | go to the jump address 55 56 _sjumpto: movea.l 4(a7),a0 | get jump address 57 movea.l 8(a7),a7 | set stack pointer 58 jmp (a0) | go to the jump address 59 60 _xreset: reset | reset external devices 61 rts | return to caller 62 63 63 .end -
lib700/ldiv.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *ldiv.s -- long division3 *Version 1 -- 1988-01-224 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | ldiv.s -- long division 3 | Version 1 -- 1988-01-22 4 | ------------------------------------------------------------------------------ 5 5 .text 6 * 6 7 7 .xdef _ldiv 8 8 .xdef ldiv 9 * 9 10 10 .xdef _ldivr 11 * 12 ARG1 .equ813 ARG2 .equ1214 * 11 12 ARG1 = 8 13 ARG2 = 12 14 15 15 _ldiv: 16 16 ldiv: link a6,#-2 … … 21 21 move.l ARG2(a6),d6 22 22 bne ldiv1 23 * 24 move.l # $80000000,_ldivr25 move.l # $80000000,d023 24 move.l #0x80000000,_ldivr 25 move.l #0x80000000,d0 26 26 divs #0,d0 27 27 bra ldiv11 28 * 28 29 29 ldiv1: bge ldiv2 30 * 30 31 31 neg.l d6 32 32 addq.w #1,d3 33 * 33 34 34 ldiv2: tst.l d7 35 35 bge ldiv3 36 * 36 37 37 neg.l d7 38 38 addq.w #1,d3 39 * 39 40 40 ldiv3: cmp.l d7,d6 41 41 bgt ldiv9 42 * 42 43 43 bne ldiv4 44 * 44 45 45 moveq.l #1,d5 46 46 clr.l d7 47 47 bra ldiv9 48 * 49 ldiv4: cmp.l # $10000,d748 49 ldiv4: cmp.l #0x10000,d7 50 50 bge ldiv5 51 * 51 52 52 divu d6,d7 53 53 move.w d7,d5 … … 55 55 ext.l d7 56 56 bra ldiv9 57 * 57 58 58 ldiv5: moveq.l #1,d4 59 * 59 60 60 ldiv6: cmp.l d6,d7 61 61 bcs ldiv7 62 * 62 63 63 asl.l #1,d6 64 64 asl.l #1,d7 65 65 bra ldiv6 66 * 66 67 67 ldiv7: tst.l d4 68 68 beq ldiv9 69 * 69 70 70 cmp.l d6,d7 71 71 bcs ldiv8 72 * 72 73 73 or.l d4,d5 74 74 sub.l d6,d7 75 * 75 76 76 ldiv8: lsr.l #1,d4 77 77 lsr.l #1,d6 78 78 bra ldiv7 79 * 79 80 80 ldiv9: cmp.w #1,d3 81 81 bne ldiv10 82 * 82 83 83 neg.l d7 84 84 move.l d7,_ldivr … … 86 86 neg.l d0 87 87 bra ldiv11 88 * 88 89 89 ldiv10: move.l d7,_ldivr 90 90 move.l d5,d0 91 * 91 92 92 ldiv11: tst.l (a7)+ 93 93 movem.l (a7)+,d3-d7 94 94 unlk a6 95 95 rts 96 * 96 97 97 .bss 98 * 98 99 99 _ldivr: .ds.l 1 100 * 100 101 101 .end -
lib700/lmul.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *lmul.s -- long multiply3 *Version 2 -- 1989-07-184 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | lmul.s -- long multiply 3 | Version 2 -- 1989-07-18 4 | ------------------------------------------------------------------------------ 5 5 .text 6 * 6 7 7 .xdef lmul 8 * 9 ARG1 .equ810 ARG2 .equ1211 * 12 TEMP .equ-413 * 8 9 ARG1 = 8 10 ARG2 = 12 11 12 TEMP = -4 13 14 14 lmul: link a6,#-4 15 15 clr.w d2 16 16 tst.l ARG1(a6) 17 17 bge lmul1 18 * 18 19 19 neg.l ARG1(a6) 20 20 addq.w #1,d2 21 * 21 22 22 lmul1: tst.l ARG2(a6) 23 23 bge lmul2 24 * 24 25 25 neg.l ARG2(a6) 26 26 addq.w #1,d2 27 * 27 28 28 lmul2: move.w ARG1+2(a6),d0 29 29 mulu ARG2+2(a6),d0 … … 39 39 btst #0,d2 40 40 beq lmul3 41 * 41 42 42 neg.l d0 43 * 43 44 44 lmul3: unlk a6 45 45 rts 46 * 46 47 47 .end -
lib700/lrem.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *lrem.s -- long modulo3 *Version 1 -- 1988-01-224 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | lrem.s -- long modulo 3 | Version 1 -- 1988-01-22 4 | ------------------------------------------------------------------------------ 5 5 .text 6 * 6 7 7 .xdef _lrem 8 8 .xdef lrem 9 * 9 10 10 .xref ldiv 11 11 .xref _ldivr 12 * 13 ARG1 .equ814 ARG2 .equ1215 * 12 13 ARG1 = 8 14 ARG2 = 12 15 16 16 _lrem: 17 17 lrem: link a6,#-2 … … 23 23 unlk a6 24 24 rts 25 * 25 26 26 .end -
lib700/rand24.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *rand24.s -- generate a 24 bit random number3 *Version 3 -- 1988-04-29 -- D.N. Lynx Crowe4 *------------------------------------------------------------------------------5 *Synopsis:6 *long7 *rand24()8 * 9 *Based on:10 *Knuth, Donald E.11 *The Art of Computer Programming,12 *Volume 2: Semi-Numerical Algorithms13 * 14 *Computes:15 * S = [S *C] + K16 * 17 *Where:18 *K = 119 *C = 314159262120 *S = the seed (if zero, it gets set from the 200 Hz clock)21 * 22 *Returns:23 *S >> 8 (a 24 bit pseudo-random number)24 * 25 *Note: this function has an LSB with an exactly 50% distribution, so using26 *individual bits is probably not a good idea. Using more bits makes things27 *appear more random.28 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | rand24.s -- generate a 24 bit random number 3 | Version 3 -- 1988-04-29 -- D.N. Lynx Crowe 4 | ------------------------------------------------------------------------------ 5 | Synopsis: 6 | long 7 | rand24() 8 9 | Based on: 10 | Knuth, Donald E. 11 | The Art of Computer Programming, 12 | Volume 2: Semi-Numerical Algorithms 13 14 | Computes: 15 | S = [S | C] + K 16 17 | Where: 18 | K = 1 19 | C = 3141592621 20 | S = the seed (if zero, it gets set from the 200 Hz clock) 21 22 | Returns: 23 | S >> 8 (a 24 bit pseudo-random number) 24 25 | Note: this function has an LSB with an exactly 50% distribution, so using 26 | individual bits is probably not a good idea. Using more bits makes things 27 | appear more random. 28 | ------------------------------------------------------------------------------ 29 29 .text 30 * 30 31 31 .xdef _rand24 32 * 32 33 33 .xdef _rseed 34 * 35 *equates for things in the BIOS36 * 37 RCLOCK .equ $49E *LONG - 200 Hz clock38 * 39 *equates for stack offsets40 * 41 ARG1 .equ 8 *LONG / WORD - arg1 / MS bits42 ARG1L .equ 10 *WORD - arg1 LS bits43 ARG2 .equ 12 *LONG / WORD - arg2 / MS bits44 ARG2L .equ 14 *WORD - arg2 LS bits45 * 46 PART .equ -4 *LONG - partial product47 * 48 PI .equ $BB40E62D *LONG - PI as a hex value49 * 34 35 | equates for things in the BIOS 36 37 RCLOCK = 0x49E | LONG - 200 Hz clock 38 39 | equates for stack offsets 40 41 ARG1 = 8 | LONG / WORD - arg1 / MS bits 42 ARG1L = 10 | WORD - arg1 LS bits 43 ARG2 = 12 | LONG / WORD - arg2 / MS bits 44 ARG2L = 14 | WORD - arg2 LS bits 45 46 PART = -4 | LONG - partial product 47 48 PI = 0xBB40E62D | LONG - PI as a hex value 49 50 50 .page 51 * 52 *mult32 -- 32 bit signed multiply53 *------ ----------------------54 mult32: link a6,#-4 *link stack frames55 clr.w d2 *clear sign flags56 tst.l ARG1(a6) *check sign of 1st argument57 bge mult32a *...58 * 59 neg.l ARG1(a6) *make 1st argument positive60 addq.w #1,d2 *log its sign as negative61 * 62 mult32a: tst.l ARG2(a6) *check sign of 2nd argument63 bge mult32b *...64 * 65 neg.l ARG2(a6) *make 2nd argument positive66 addq.w #1,d2 *log its sign as negative67 * 68 mult32b: move.w ARG1L(a6),d0 *generate 1st partial product69 mulu ARG2L(a6),d0 *...70 move.l d0,PART(a6) *...71 move.w ARG1(a6),d0 *generate 2nd partial product72 mulu ARG2L(a6),d0 *...73 move.w ARG2(a6),d1 *generate 3rd partial product74 mulu ARG1L(a6),d1 *...75 add.w d1,d0 *add partial products76 add.w PART(a6),d0 *...77 move.w d0,PART(a6) *...78 move.l PART(a6),d0 *...79 btst #0,d2 *adjust sign of result80 beq mult32c *...81 * 82 neg.l d0 *...83 * 84 mult32c: unlk a6 *unlink stack frames85 rts *return86 * 51 52 | mult32 -- 32 bit signed multiply 53 | ------ ---------------------- 54 mult32: link a6,#-4 | link stack frames 55 clr.w d2 | clear sign flags 56 tst.l ARG1(a6) | check sign of 1st argument 57 bge mult32a | ... 58 59 neg.l ARG1(a6) | make 1st argument positive 60 addq.w #1,d2 | log its sign as negative 61 62 mult32a: tst.l ARG2(a6) | check sign of 2nd argument 63 bge mult32b | ... 64 65 neg.l ARG2(a6) | make 2nd argument positive 66 addq.w #1,d2 | log its sign as negative 67 68 mult32b: move.w ARG1L(a6),d0 | generate 1st partial product 69 mulu ARG2L(a6),d0 | ... 70 move.l d0,PART(a6) | ... 71 move.w ARG1(a6),d0 | generate 2nd partial product 72 mulu ARG2L(a6),d0 | ... 73 move.w ARG2(a6),d1 | generate 3rd partial product 74 mulu ARG1L(a6),d1 | ... 75 add.w d1,d0 | add partial products 76 add.w PART(a6),d0 | ... 77 move.w d0,PART(a6) | ... 78 move.l PART(a6),d0 | ... 79 btst #0,d2 | adjust sign of result 80 beq mult32c | ... 81 82 neg.l d0 | ... 83 84 mult32c: unlk a6 | unlink stack frames 85 rts | return 86 87 87 .page 88 * 89 *_rand24 -- Generate a random number90 *------- ------------------------91 _rand24: link a6,#0 *Link stack frames92 tst.l _rseed *See if the seed is zero93 bne rand01 *Jump if not94 * 95 move.l RCLOCK,d0 *Pick up the 200 Hz clock96 moveq.l #16,d1 *Shift it left97 asl.l d1,d0 *...98 or.l RCLOCK,d0 *OR in current 200 Hz clock99 move.l d0,_rseed *Use that as the seed100 * 101 rand01: move.l #PI,-(a7) *Put PI on the stack102 move.l _rseed,-(a7) *... and _rseed, too103 bsr mult32 *Multiply them104 addq.l #8,a7 *Cleanup stack105 addq.l #1,d0 *Add 1 to the result106 move.l d0,_rseed *Save as new seed107 asr.l #8,d0 *Make it a 24 bit number108 and.l # $00FFFFFF,d0 *...109 unlk a6 *Unlink stack frames110 rts *Return to caller111 * 112 *------------------------------------------------------------------------------88 89 | _rand24 -- Generate a random number 90 | ------- ------------------------ 91 _rand24: link a6,#0 | Link stack frames 92 tst.l _rseed | See if the seed is zero 93 bne rand01 | Jump if not 94 95 move.l RCLOCK,d0 | Pick up the 200 Hz clock 96 moveq.l #16,d1 | Shift it left 97 asl.l d1,d0 | ... 98 or.l RCLOCK,d0 | OR in current 200 Hz clock 99 move.l d0,_rseed | Use that as the seed 100 101 rand01: move.l #PI,-(a7) | Put PI on the stack 102 move.l _rseed,-(a7) | ... and _rseed, too 103 bsr mult32 | Multiply them 104 addq.l #8,a7 | Cleanup stack 105 addq.l #1,d0 | Add 1 to the result 106 move.l d0,_rseed | Save as new seed 107 asr.l #8,d0 | Make it a 24 bit number 108 and.l #0x00FFFFFF,d0 | ... 109 unlk a6 | Unlink stack frames 110 rts | Return to caller 111 112 | ------------------------------------------------------------------------------ 113 113 .bss 114 *------------------------------------------------------------------------------115 * 116 _rseed: .ds.l 1 *random number seed117 * 114 | ------------------------------------------------------------------------------ 115 116 _rseed: .ds.l 1 | random number seed 117 118 118 .end -
lib700/setjmp.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *setjmp.s -- Unix(tm) compatible setjmp(env) and longjmp(env,ret)3 *Version 3 -- 1987-06-16 -- D.N. Lynx Crowe4 *------------------------------------------------------------------------------5 * 1 | ------------------------------------------------------------------------------ 2 | setjmp.s -- Unix(tm) compatible setjmp(env) and longjmp(env,ret) 3 | Version 3 -- 1987-06-16 -- D.N. Lynx Crowe 4 | ------------------------------------------------------------------------------ 5 6 6 .text 7 * 7 8 8 .xdef _setjmp,_longjmp 9 * 10 _setjmp: movea.l 4(a7),a0 *Get env pointer11 move.l (a7),(a0) *Put return address in env12 movem.l d1-d7/a1-a7,4(a0) *Save registers in env13 moveq.l #0,d0 *Set return value to 014 rts *Return to caller15 * 16 _longjmp: move.w 8(a7),d0 *Get ret value17 bne lj1 *Jump if non-zero18 * 19 moveq.l #1,d0 *Force return value to 120 * 21 lj1: movea.l 4(a7),a0 *Get env pointer22 movem.l 4(a0),d1-d7/a1-a7 *Restore registers from env23 move.l (a0),(a7) *Get return address from env24 rts *Return to caller25 * 9 10 _setjmp: movea.l 4(a7),a0 | Get env pointer 11 move.l (a7),(a0) | Put return address in env 12 movem.l d1-d7/a1-a7,4(a0) | Save registers in env 13 moveq.l #0,d0 | Set return value to 0 14 rts | Return to caller 15 16 _longjmp: move.w 8(a7),d0 | Get ret value 17 bne lj1 | Jump if non-zero 18 19 moveq.l #1,d0 | Force return value to 1 20 21 lj1: movea.l 4(a7),a0 | Get env pointer 22 movem.l 4(a0),d1-d7/a1-a7 | Restore registers from env 23 move.l (a0),(a7) | Get return address from env 24 rts | Return to caller 25 26 26 .end -
lib700/uldiv.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *uldiv.s -- unsigned long division, with remainder3 *Version 2 -- 1987-06-08 -- D.N. Lynx Crowe4 *Lifted from the Alcyon C library by disassembly so I could fix a bug -5 *_uldivr must be in the bss segment so the code will work in PROM.6 * 7 *long8 *uldiv(dividnd, divisor)9 *long dividnd, divisor;10 * 11 *extern long uldivr;12 * 13 *Divides 'dividnd' by 'divisor', treating both as unsigned14 *long integers. Returns the quotient and leaves the15 *remainder in 'uldivr'. Produces a divide check on division16 * by zero, with $80000000 returned for both quotient and17 *remainder.18 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | uldiv.s -- unsigned long division, with remainder 3 | Version 2 -- 1987-06-08 -- D.N. Lynx Crowe 4 | Lifted from the Alcyon C library by disassembly so I could fix a bug - 5 | _uldivr must be in the bss segment so the code will work in PROM. 6 7 | long 8 | uldiv(dividnd, divisor) 9 | long dividnd, divisor; 10 11 | extern long uldivr; 12 13 | Divides 'dividnd' by 'divisor', treating both as unsigned 14 | long integers. Returns the quotient and leaves the 15 | remainder in 'uldivr'. Produces a divide check on division 16 | by zero, with 0x80000000 returned for both quotient and 17 | remainder. 18 | ------------------------------------------------------------------------------ 19 19 .text 20 * 20 21 21 .xdef _uldiv,_uldivr 22 * 23 DIVIDEND .equ824 DIVISOR .equ1225 * 26 _uldiv: link a6,#0 *Link stack frames27 movem.l d3-d7,-(a7) *Save registers28 move.l DIVIDEND(a6),d7 *d7 = DIVIDEND29 move.l DIVISOR(a6),d6 *d6 = DIVISOR30 tst.l d6 *Divide by zero ?31 bne notdzero *Jump if not32 * 33 move.l # $80000000,_uldivr *Force error result34 move.l # $80000000,d0 *... by dividing35 divu #0,d0 *... by zero36 bra ulexit *... then exit37 * 38 notdzero: cmp.l d7,d6 *Divide underflow ?39 bls notunflo *Jump if not40 * 41 move.l d7,_uldivr *Remainder = dividend42 clr.l d0 *Quotient = 043 bra ulexit *Exit44 * 45 notunflo: cmp.l d6,d7 *Is dividend = divisor ?46 bne startdiv *Go start dividing if not47 * 48 moveq.l #1,d5 *Quotient = 149 clr.l d7 *Remainder = 050 bra setreslt *Go set result51 * 22 23 DIVIDEND = 8 24 DIVISOR = 12 25 26 _uldiv: link a6,#0 | Link stack frames 27 movem.l d3-d7,-(a7) | Save registers 28 move.l DIVIDEND(a6),d7 | d7 = DIVIDEND 29 move.l DIVISOR(a6),d6 | d6 = DIVISOR 30 tst.l d6 | Divide by zero ? 31 bne notdzero | Jump if not 32 33 move.l #0x80000000,_uldivr | Force error result 34 move.l #0x80000000,d0 | ... by dividing 35 divu #0,d0 | ... by zero 36 bra ulexit | ... then exit 37 38 notdzero: cmp.l d7,d6 | Divide underflow ? 39 bls notunflo | Jump if not 40 41 move.l d7,_uldivr | Remainder = dividend 42 clr.l d0 | Quotient = 0 43 bra ulexit | Exit 44 45 notunflo: cmp.l d6,d7 | Is dividend = divisor ? 46 bne startdiv | Go start dividing if not 47 48 moveq.l #1,d5 | Quotient = 1 49 clr.l d7 | Remainder = 0 50 bra setreslt | Go set result 51 52 52 .page 53 * 54 startdiv: moveq.l #1,d4 *Set result bit in d455 * 56 divloop1: cmp.l d6,d7 *Divisor aligned OK ?57 bcs divloop2 *Jump if so58 * 59 move.l d6,d0 *Can we align things better ?60 asl.l #1,d0 *...61 cmp.l d0,d6 *...62 bhi divloop2 *Jump if not63 * 64 asl.l #1,d6 *Shift the divisor65 asl.l #1,d4 *Shift the result bit66 bra divloop1 *Loop for next bit67 * 68 divloop2: clr.l d5 *Clear quotient69 * 70 divloop3: tst.l d4 *More bits to do ?71 beq setreslt *Go set result if not72 * 73 cmp.l d6,d7 *Can we subtract ?74 bcs divloop4 *Jump if not75 * 76 or.l d4,d5 *Set a bit in the quotient77 sub.l d6,d7 *Subtract divisor from dividend78 * 79 divloop4: lsr.l #1,d4 *Shift the result bit80 lsr.l #1,d6 *Shift the divisor81 bra divloop3 *Loop for next bit82 * 83 setreslt: move.l d7,_uldivr *Store remainder84 move.l d5,d0 *Put quotient in d085 * 86 ulexit: tst.l (a7)+ *Discard top of stack87 movem.l (a7)+,d4-d7 *Restore registers88 unlk a6 *Unlink stack frames89 rts *Return to caller90 * 53 54 startdiv: moveq.l #1,d4 | Set result bit in d4 55 56 divloop1: cmp.l d6,d7 | Divisor aligned OK ? 57 bcs divloop2 | Jump if so 58 59 move.l d6,d0 | Can we align things better ? 60 asl.l #1,d0 | ... 61 cmp.l d0,d6 | ... 62 bhi divloop2 | Jump if not 63 64 asl.l #1,d6 | Shift the divisor 65 asl.l #1,d4 | Shift the result bit 66 bra divloop1 | Loop for next bit 67 68 divloop2: clr.l d5 | Clear quotient 69 70 divloop3: tst.l d4 | More bits to do ? 71 beq setreslt | Go set result if not 72 73 cmp.l d6,d7 | Can we subtract ? 74 bcs divloop4 | Jump if not 75 76 or.l d4,d5 | Set a bit in the quotient 77 sub.l d6,d7 | Subtract divisor from dividend 78 79 divloop4: lsr.l #1,d4 | Shift the result bit 80 lsr.l #1,d6 | Shift the divisor 81 bra divloop3 | Loop for next bit 82 83 setreslt: move.l d7,_uldivr | Store remainder 84 move.l d5,d0 | Put quotient in d0 85 86 ulexit: tst.l (a7)+ | Discard top of stack 87 movem.l (a7)+,d4-d7 | Restore registers 88 unlk a6 | Unlink stack frames 89 rts | Return to caller 90 91 91 .bss 92 92 .even 93 * 93 94 94 _uldivr: ds.l 1 95 * 95 96 96 .end -
libcio/ptcl12.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *ptcl12.s -- store a cluster entry into the FAT3 *Version 2 -- 1987-10-27 -- D.N. Lynx Crowe4 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | ptcl12.s -- store a cluster entry into the FAT 3 | Version 2 -- 1987-10-27 -- D.N. Lynx Crowe 4 | ------------------------------------------------------------------------------ 5 5 .text 6 6 .xdef __ptcl12 7 * 8 CL .equ129 VAL .equ1410 CLA .equd711 CLP .equd612 CLT .equd513 FAT .equa514 * 7 8 CL = 12 9 VAL = 14 10 CLA = d7 11 CLP = d6 12 CLT = d5 13 FAT = a5 14 15 15 __ptcl12: link A6,#0 16 16 movem.l CLT-CLA/FAT-FAT,-(sp) 17 17 move.l 8(A6),FAT 18 18 move.w CL(A6),CLA 19 lsr.w CLA19 lsr.w #1,CLA 20 20 add.w CL(A6),CLA 21 21 move.b 1(FAT,CLA.W),CLP … … 24 24 btst #0,CL+1(A6) 25 25 beq L2 26 * 26 27 27 move.w CLP,CLT 28 and.w # $000F,CLT28 and.w #0x000F,CLT 29 29 move.w VAL(A6),D0 30 30 lsl.w #4,D0 31 31 or.w D0,CLT 32 32 bra L3 33 * 33 34 34 L2: move.w CLP,CLT 35 and.w # $F000,CLT35 and.w #0xF000,CLT 36 36 move.w VAL(A6),D0 37 and.w # $0FFF,D037 and.w #0x0FFF,D0 38 38 or.w D0,CLT 39 * 39 40 40 L3: move.b CLT,0(FAT,CLA.W) 41 41 move.w CLT,D0 42 42 lsr.w #8,D0 43 43 move.b D0,1(FAT,CLA.W) 44 * 44 45 45 L1: movem.l (sp)+,CLT-CLA/FAT-FAT 46 46 unlk A6 47 47 rts 48 * 48 49 49 .end -
prolog/fsmain.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *fsmain.s -- startup code for the Buchla 700 standalone C runtime library3 *Version 3 -- 1987-06-29 -- D.N. Lynx Crowe4 * 5 *This code clears 'bss' space, sets up some global variables,6 *and calls Croot(), which sets up the file system and calls main().7 * 8 *This routine should be entered with the address of the basepage9 *as its parameter.10 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | fsmain.s -- startup code for the Buchla 700 standalone C runtime library 3 | Version 3 -- 1987-06-29 -- D.N. Lynx Crowe 4 5 | This code clears 'bss' space, sets up some global variables, 6 | and calls Croot(), which sets up the file system and calls main(). 7 8 | This routine should be entered with the address of the basepage 9 | as its parameter. 10 | ------------------------------------------------------------------------------ 11 11 .text 12 * 12 13 13 .xdef start_ 14 * 14 15 15 .xref _Croot 16 * 16 17 17 .xdef _panic 18 18 .xdef _brk 19 * 19 20 20 .xdef __heap 21 21 .xdef __break 22 22 .xdef __pmesg 23 * 23 24 24 .xdef _errno 25 * 26 p_bbase .equ $18 *bss base27 p_blen .equ $1C *bss length28 * 25 26 p_bbase = 0x18 | bss base 27 p_blen = 0x1C | bss length 28 29 29 .page 30 * 31 *start_ -- Initial entry point -- Must be first object file in link statement32 *------ ------------------------------------------------------------------33 * 34 *WARNING: Hazardous assumptions35 * 36 * We assume that: 37 * 38 *the system has set the stack pointer for us.39 *the system passed us a pointer to a valid basepage.40 *the stack is above the heap.41 *BSS is located in RAM.42 * 43 *If any of these assumptions is in error, we're in for serious trouble.44 * 45 start_: clr.l a6 *Clear frame pointer46 movea.l 4(a7),a1 *Set pointer to base page47 movea.l p_bbase(a1),a0 *Setup to clear bss space48 * 49 start1: clr.w (a0)+ *Clear a word50 cmpa.l a0,a7 *See if we're done51 bne start1 *Loop if not done yet52 * 53 move.l p_bbase(a1),d0 *Calculate break address54 add.l p_blen(a1),d0 *...55 move.l d0,__break *Set initial break56 move.l d0,__heap *Set heap start57 * 58 move.l #0,-(a7) *Pass NULL to Croot (no command line)59 jsr _Croot *call Croot() routine60 addq.l #4,a7 *...61 * 62 move.l #pmsg1,-(a7) *panic(pmsg1);63 jsr _panic *...64 addq.l #4,a7 *...65 * 66 hstop: stop # $2000 *"Die, sucker!"30 31 | start_ -- Initial entry point -- Must be first object file in link statement 32 | ------ ------------------------------------------------------------------ 33 34 | WARNING: Hazardous assumptions 35 36 | We assume that: 37 38 | the system has set the stack pointer for us. 39 | the system passed us a pointer to a valid basepage. 40 | the stack is above the heap. 41 | BSS is located in RAM. 42 43 | If any of these assumptions is in error, we're in for serious trouble. 44 45 start_: movea.l #0,a6 | Clear frame pointer 46 movea.l 4(a7),a1 | Set pointer to base page 47 movea.l p_bbase(a1),a0 | Setup to clear bss space 48 49 start1: clr.w (a0)+ | Clear a word 50 cmpa.l a0,a7 | See if we're done 51 bne start1 | Loop if not done yet 52 53 move.l p_bbase(a1),d0 | Calculate break address 54 add.l p_blen(a1),d0 | ... 55 move.l d0,__break | Set initial break 56 move.l d0,__heap | Set heap start 57 58 move.l #0,-(a7) | Pass NULL to Croot (no command line) 59 jsr _Croot | call Croot() routine 60 addq.l #4,a7 | ... 61 62 move.l #pmsg1,-(a7) | panic(pmsg1); 63 jsr _panic | ... 64 addq.l #4,a7 | ... 65 66 hstop: stop #0x2000 | "Die, sucker!" 67 67 bra hstop 68 * 68 69 69 .page 70 * 71 *_panic -- hard halt for fatal errors72 *------ --------------------------73 _panic: movea.l 4(a7),a0 *Save panic message address74 move.l a0,__pmesg *...75 * 76 trap #15 *Invoke ROMP (we hope ...)77 * 78 pstop: stop # $2700 *HARD HALT70 71 | _panic -- hard halt for fatal errors 72 | ------ -------------------------- 73 _panic: movea.l 4(a7),a0 | Save panic message address 74 move.l a0,__pmesg | ... 75 76 trap #15 | Invoke ROMP (we hope ...) 77 78 pstop: stop #0x2700 | HARD HALT 79 79 bra pstop 80 * 80 81 81 .page 82 * 83 *_brk -- set break value84 *---- ---------------85 *WARNING: This only works if the stack is above the heap.86 * 87 _brk: cmpa.l __break,a7 *compare current break with stack88 bcs pstop *actual stack overflow!89 * 90 movea.l 4(sp),a0 *get new break91 move.l a0,d0 *compare with current stack,92 adda.l # $100,a0 *... including 256-byte slop factor93 cmpa.l a0,a7 *if (sp < a0+256)94 bcs badbrk *bad break;95 * 96 move.l d0,__break *OK break: save the break97 clr.l d0 *Set OK return98 rts *return99 * 100 badbrk: moveq.l #-1,d0 *Load return reg101 rts *Return102 * 82 83 | _brk -- set break value 84 | ---- --------------- 85 | WARNING: This only works if the stack is above the heap. 86 87 _brk: cmpa.l __break,a7 | compare current break with stack 88 bcs pstop | actual stack overflow! 89 90 movea.l 4(sp),a0 | get new break 91 move.l a0,d0 | compare with current stack, 92 adda.l #0x100,a0 | ... including 256-byte slop factor 93 cmpa.l a0,a7 | if (sp < a0+256) 94 bcs badbrk | bad break; 95 96 move.l d0,__break | OK break: save the break 97 clr.l d0 | Set OK return 98 rts | return 99 100 badbrk: moveq.l #-1,d0 | Load return reg 101 rts | Return 102 103 103 .page 104 * 105 ************************************************************************* 106 * Data Area * 107 ************************************************************************* 108 * 104 105 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 106 | Data Area | 107 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 108 109 109 .data 110 * 111 pmsg1: dc.b ' returned from Croot() ',0112 * 113 ************************************************************************* 114 * BSS Area * 115 ************************************************************************* 116 * 110 111 pmsg1: dc.b " returned from Croot() ",0 112 113 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 114 | BSS Area | 115 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 116 117 117 .bss 118 118 .even 119 * 120 __pmesg: ds.l 1 *panic() message string address121 __heap: ds.l 1 *Heap start (initial break)122 __break: ds.l 1 *Current break location123 _errno: ds.w 1 *System error number124 * 119 120 __pmesg: ds.l 1 | panic() message string address 121 __heap: ds.l 1 | Heap start (initial break) 122 __break: ds.l 1 | Current break location 123 _errno: ds.w 1 | System error number 124 125 125 .end -
ram/execins.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *execins.s -- execute an instrument selection3 *Version 9 -- 1988-09-09 -- D.N. Lynx Crowe4 * 5 *Hand optimized C object code from: execins.c -- ver 2 -- 1988-06-296 *------------------------------------------------------------------------------7 * 1 | ------------------------------------------------------------------------------ 2 | execins.s -- execute an instrument selection 3 | Version 9 -- 1988-09-09 -- D.N. Lynx Crowe 4 5 | Hand optimized C object code from: execins.c -- ver 2 -- 1988-06-29 6 | ------------------------------------------------------------------------------ 7 8 8 .text 9 * 10 DOUBLED .equ 1 *double output to WS table11 * 9 10 DOUBLED = 1 | double output to WS table 11 12 12 .xdef _execins 13 * 13 14 14 .xref _clrvce 15 15 .xref _execkey 16 * 16 17 17 .xref _io_fpu 18 18 .xref _instmod … … 20 20 .xref _idefs 21 21 .xref _vbufs 22 * 23 *register equates24 *----------------25 SYNC .equD426 OLDSR .equD527 VCE .equD728 * 29 IP .equA530 P1 .equA431 P2 .equA332 * 33 P3 .equA234 P4 .equA135 * 36 *parameter offsets37 *-----------------38 VOICE .equ839 INS .equ1040 TAG .equ1241 * 42 .page 43 * 44 _execins: link A6,#0 *link stack frames45 movem.l D3-VCE/P2-IP,-(sp) *preserve registers46 move.w VOICE(A6),VCE *get voice number47 move.w VCE,D0 *calculate IP48 add.w D0,D0 *...49 add.w D0,D0 *...50 lea vibtabl,A0 *...51 movea.l 0(A0,D0.W),IP *...52 add.l #_vbufs,IP *...53 move.w VCE,(sp) *clrvce(vce)54 jsr _clrvce *...55 tst.w TAG(A6) *if (tag) {56 beq L2 *...57 * 58 move.l IP,P1 *p1 = ip;59 move.w INS(A6),D0 *p2 = &idefs[ins]60 add.w D0,D0 *...61 add.w D0,D0 *...62 lea vibtabl,A0 *...63 movea.l 0(A0,D0.W),P2 *...64 add.l #_idefs,P2 *...65 move.w #1968,D0 *set move count66 * 67 L6: move.w (P2)+,(P1)+ *load voice buffer68 dbra D0,L6 *...69 * 70 .page 71 * 72 move.w VCE,D0 *calculate FPU offset for voice73 move.w #9,D1 *...74 asl.w D1,D0 *...75 asl.w #1,D0 *...76 ext.l D0 *...77 move.l D0,P1 *...78 move.l D0,P3 *...79 add.l #_io_fpu,P1 *point P1 at FPU WS A80 add.l # $202,P1 *...81 lea 1778(IP),P2 *point P2 at instdef WS A82 add.l #_io_fpu,P3 *point P3 at FPU WS B83 add.l #2,P3 *...84 lea 2858(IP),P4 *point P4 at instdef WS B85 move.w #253,D0 *setup move count86 * 22 23 | register equates 24 | ---------------- 25 SYNC = D4 26 OLDSR = D5 27 VCE = D7 28 29 IP = A5 30 P1 = A4 31 P2 = A3 32 33 P3 = A2 34 P4 = A1 35 36 | parameter offsets 37 | ----------------- 38 VOICE = 8 39 INS = 10 40 TAG = 12 41 42 .page 43 44 _execins: link A6,#0 | link stack frames 45 movem.l D3-VCE/P2-IP,-(sp) | preserve registers 46 move.w VOICE(A6),VCE | get voice number 47 move.w VCE,D0 | calculate IP 48 add.w D0,D0 | ... 49 add.w D0,D0 | ... 50 lea vibtabl,A0 | ... 51 movea.l 0(A0,D0.W),IP | ... 52 add.l #_vbufs,IP | ... 53 move.w VCE,(sp) | clrvce(vce) 54 jsr _clrvce | ... 55 tst.w TAG(A6) | if (tag) { 56 beq L2 | ... 57 58 move.l IP,P1 | p1 = ip; 59 move.w INS(A6),D0 | p2 = &idefs[ins] 60 add.w D0,D0 | ... 61 add.w D0,D0 | ... 62 lea vibtabl,A0 | ... 63 movea.l 0(A0,D0.W),P2 | ... 64 add.l #_idefs,P2 | ... 65 move.w #1968,D0 | set move count 66 67 L6: move.w (P2)+,(P1)+ | load voice buffer 68 dbra D0,L6 | ... 69 70 .page 71 72 move.w VCE,D0 | calculate FPU offset for voice 73 move.w #9,D1 | ... 74 asl.w D1,D0 | ... 75 asl.w #1,D0 | ... 76 ext.l D0 | ... 77 move.l D0,P1 | ... 78 move.l D0,P3 | ... 79 add.l #_io_fpu,P1 | point P1 at FPU WS A 80 add.l #0x202,P1 | ... 81 lea 1778(IP),P2 | point P2 at instdef WS A 82 add.l #_io_fpu,P3 | point P3 at FPU WS B 83 add.l #2,P3 | ... 84 lea 2858(IP),P4 | point P4 at instdef WS B 85 move.w #253,D0 | setup move count 86 87 87 .ifne DOUBLED 88 move.l P1,-(a7) *save P1 on stack89 move.l P2,-(a7) *save P2 on stack90 move.l P3,-(a7) *save P3 on stack91 move.l P4,-(a7) *save P4 on stack92 move.w D0,-(a7) *save D0 on stack88 move.l P1,-(a7) | save P1 on stack 89 move.l P2,-(a7) | save P2 on stack 90 move.l P3,-(a7) | save P3 on stack 91 move.l P4,-(a7) | save P4 on stack 92 move.w D0,-(a7) | save D0 on stack 93 93 .endc 94 * 95 move.w SR,OLDSR *turn off FPU interrupts96 move.w # $2200,SR *...97 * 98 L10: move.w (P2)+,(P1)+ *set FPU WS A from instdef99 nop *delay for FPU timing100 nop *...101 nop *...102 move.w (P4)+,(P3)+ *set FPU WS B from instdef103 nop *delay for FPU timing104 nop *...105 dbra D0,L10 *loop until done106 * 94 95 move.w SR,OLDSR | turn off FPU interrupts 96 move.w #0x2200,SR | ... 97 98 L10: move.w (P2)+,(P1)+ | set FPU WS A from instdef 99 nop | delay for FPU timing 100 nop | ... 101 nop | ... 102 move.w (P4)+,(P3)+ | set FPU WS B from instdef 103 nop | delay for FPU timing 104 nop | ... 105 dbra D0,L10 | loop until done 106 107 107 .ifne DOUBLED 108 move.w (a7)+,D0 *restore D0 from stack109 movea.l (a7)+,P4 *restore P4 from stack110 movea.l (a7)+,P3 *restore P3 from stack111 movea.l (a7)+,P2 *restore P2 from stack112 movea.l (a7)+,P1 *restore P1 from stack113 * 114 L10A: move.w (P2)+,(P1)+ *set FPU WS A from instdef115 nop *delay for FPU timing116 nop *...117 nop *...118 move.w (P4)+,(P3)+ *set FPU WS B from instdef119 nop *delay for FPU timing120 nop *...121 dbra D0,L10A *loop until done122 * 108 move.w (a7)+,D0 | restore D0 from stack 109 movea.l (a7)+,P4 | restore P4 from stack 110 movea.l (a7)+,P3 | restore P3 from stack 111 movea.l (a7)+,P2 | restore P2 from stack 112 movea.l (a7)+,P1 | restore P1 from stack 113 114 L10A: move.w (P2)+,(P1)+ | set FPU WS A from instdef 115 nop | delay for FPU timing 116 nop | ... 117 nop | ... 118 move.w (P4)+,(P3)+ | set FPU WS B from instdef 119 nop | delay for FPU timing 120 nop | ... 121 dbra D0,L10A | loop until done 122 123 123 .endc 124 * 125 move.w OLDSR,SR *enable FPU interrupts126 * 127 .page 128 * 129 move.w VCE,A0 *instmod[vce] = FALSE130 add.l A0,A0 *...131 add.l #_instmod,A0 *...132 clr.w (A0) *...133 move.w VCE,A0 *s_inst[vce] = ins134 add.l A0,A0 *...135 add.l #_s_inst,A0 *...136 move.w INS(A6),(A0) *...137 move.b 70(IP),SYNC *get config bits138 ext.w SYNC *...139 asl.w #8,SYNC *...140 btst #2,74(IP) *sync 2nd osc141 beq L15 *...142 * 143 ori.w # $2000,SYNC *...144 * 145 L15: btst #2,75(IP) *sync 3rd osc146 beq L16 *...147 * 148 ori.w # $4000,SYNC *...149 * 150 L16: btst #2,76(IP) *sync 4th osc151 beq L17 *...152 * 153 ori.w # $8000,SYNC *...154 * 155 L17: move.w VCE,A0 *send sync to FPU156 add.l A0,A0 *...157 add.l #_io_fpu,A0 *...158 add.l # $5FE0,A0 *...159 move.w SYNC,(A0) *...160 * 161 L2: move.w #1,(sp) *execkey(-1, 0, vce, 1)162 move.w VCE,-(sp) *...163 clr.w -(sp) *...164 move.w #-1,-(sp) *...165 jsr _execkey *...166 addq.l #6,sp *...167 tst.l (sp)+ *clean up stack168 movem.l (sp)+,SYNC-VCE/P2-IP *restore registers169 unlk A6 *unlink stack frames170 rts *return171 * 172 .page 173 * 124 125 move.w OLDSR,SR | enable FPU interrupts 126 127 .page 128 129 move.w VCE,A0 | instmod[vce] = FALSE 130 add.l A0,A0 | ... 131 add.l #_instmod,A0 | ... 132 clr.w (A0) | ... 133 move.w VCE,A0 | s_inst[vce] = ins 134 add.l A0,A0 | ... 135 add.l #_s_inst,A0 | ... 136 move.w INS(A6),(A0) | ... 137 move.b 70(IP),SYNC | get config bits 138 ext.w SYNC | ... 139 asl.w #8,SYNC | ... 140 btst #2,74(IP) | sync 2nd osc 141 beq L15 | ... 142 143 ori.w #0x2000,SYNC | ... 144 145 L15: btst #2,75(IP) | sync 3rd osc 146 beq L16 | ... 147 148 ori.w #0x4000,SYNC | ... 149 150 L16: btst #2,76(IP) | sync 4th osc 151 beq L17 | ... 152 153 ori.w #0x8000,SYNC | ... 154 155 L17: move.w VCE,A0 | send sync to FPU 156 add.l A0,A0 | ... 157 add.l #_io_fpu,A0 | ... 158 add.l #0x5FE0,A0 | ... 159 move.w SYNC,(A0) | ... 160 161 L2: move.w #1,(sp) | execkey(-1, 0, vce, 1) 162 move.w VCE,-(sp) | ... 163 clr.w -(sp) | ... 164 move.w #-1,-(sp) | ... 165 jsr _execkey | ... 166 addq.l #6,sp | ... 167 tst.l (sp)+ | clean up stack 168 movem.l (sp)+,SYNC-VCE/P2-IP | restore registers 169 unlk A6 | unlink stack frames 170 rts | return 171 172 .page 173 174 174 .data 175 * 176 *vibtabl -- voice and instrument buffer offset table177 *------- ----------------------------------------178 vibtabl: .dc.l 0 *0179 .dc.l 3938 *1180 .dc.l 7876 *2181 .dc.l 11814 *3182 .dc.l 15752 *4183 .dc.l 19690 *5184 .dc.l 23628 *6185 .dc.l 27566 *7186 .dc.l 31504 *8187 .dc.l 35442 *9188 .dc.l 39380 *10189 .dc.l 43318 *11190 .dc.l 47256 *12191 .dc.l 51194 *13192 .dc.l 55132 *14193 .dc.l 59070 *15194 .dc.l 63008 *16195 .dc.l 66946 *17196 .dc.l 70884 *18197 .dc.l 74822 *19198 .dc.l 78760 *20199 .dc.l 82698 *21200 .dc.l 86636 *22201 .dc.l 90574 *23202 .dc.l 94512 *24203 .dc.l 98450 *25204 .dc.l 102388 *26205 .dc.l 106326 *27206 .dc.l 110264 *28207 .dc.l 114202 *29208 .dc.l 118140 *30209 .dc.l 122078 *31210 .dc.l 126016 *32211 .dc.l 129954 *33212 .dc.l 133892 *34213 .dc.l 137830 *35214 .dc.l 141768 *36215 .dc.l 145706 *37216 .dc.l 149644 *38217 .dc.l 153582 *39218 .dc.l 157520 *40219 * 175 176 | vibtabl -- voice and instrument buffer offset table 177 | ------- ---------------------------------------- 178 vibtabl: .dc.l 0 | 0 179 .dc.l 3938 | 1 180 .dc.l 7876 | 2 181 .dc.l 11814 | 3 182 .dc.l 15752 | 4 183 .dc.l 19690 | 5 184 .dc.l 23628 | 6 185 .dc.l 27566 | 7 186 .dc.l 31504 | 8 187 .dc.l 35442 | 9 188 .dc.l 39380 | 10 189 .dc.l 43318 | 11 190 .dc.l 47256 | 12 191 .dc.l 51194 | 13 192 .dc.l 55132 | 14 193 .dc.l 59070 | 15 194 .dc.l 63008 | 16 195 .dc.l 66946 | 17 196 .dc.l 70884 | 18 197 .dc.l 74822 | 19 198 .dc.l 78760 | 20 199 .dc.l 82698 | 21 200 .dc.l 86636 | 22 201 .dc.l 90574 | 23 202 .dc.l 94512 | 24 203 .dc.l 98450 | 25 204 .dc.l 102388 | 26 205 .dc.l 106326 | 27 206 .dc.l 110264 | 28 207 .dc.l 114202 | 29 208 .dc.l 118140 | 30 209 .dc.l 122078 | 31 210 .dc.l 126016 | 32 211 .dc.l 129954 | 33 212 .dc.l 133892 | 34 213 .dc.l 137830 | 35 214 .dc.l 141768 | 36 215 .dc.l 145706 | 37 216 .dc.l 149644 | 38 217 .dc.l 153582 | 39 218 .dc.l 157520 | 40 219 220 220 .end -
ram/execkey.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *execkey.s -- execute key -- FPU function start subroutine3 *Version 15 -- 1988-08-29 -- D.N. Lynx Crowe4 *Hand optimized version of execkey() and fnstart() from C compiler output5 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | execkey.s -- execute key -- FPU function start subroutine 3 | Version 15 -- 1988-08-29 -- D.N. Lynx Crowe 4 | Hand optimized version of execkey() and fnstart() from C compiler output 5 | ------------------------------------------------------------------------------ 6 6 .text 7 * 8 LOC_EOR .equ09 LOC_SUB .equ110 * 7 8 LOC_EOR = 0 9 LOC_SUB = 1 10 11 11 .xdef _execkey 12 * 12 13 13 .xref _xgetran 14 * 14 15 15 .xref _rsntab 16 16 .xref _expbit … … 26 26 .xref _veltab 27 27 .xref _vpsms 28 * 29 .page 30 * 31 *Offsets for execkey() parameters32 * -------------------------------- 33 TRG .equ 8 *WORD -- trigger34 PCH .equ 10 *WORD -- pitch35 VCE .equ 12 *WORD -- voice (0..11)36 TAG .equ 14 *WORD -- I_TM_... inversion tag37 * 38 *Register variables39 *------------------40 A_FP .equ A5 * LONG -- struct idfnhdr *41 A_FPU .equ A4 *LONG -- FPU base address42 A_SMP .equ A3 * LONG -- struct sment *43 * 44 R_FPMANT .equ D7 *WORD -- FPU time mantissa45 R_FPEXP .equ D6 *WORD -- FPU time exponent46 R_FPCTL .equ D5 *WORD -- FPU control word47 R_I .equ D4 *WORD -- loop index48 R_FPVAL .equ D3 *WORD -- FPU value49 * 50 *Local (stack) variables51 *-----------------------52 PT .equ -4 * LONG -- instpnt *53 VEP .equ -8 * LONG -- struct valent *54 OLDI .equ -10 *WORD -- old IPL (sr)55 OCTYPE .equ -12 *WORD -- oscillator 1 mode / scratch56 VP .equ -14 *WORD -- voice # + function # index57 SRCNUM .equ -16 *WORD -- general source #58 SRCVAL .equ -18 *WORD -- general source value59 TSRCVAL .equ -20 *WORD -- temporary general source value60 MLTVAL .equ -22 *WORD -- general source multiplier61 TFPVAL .equ -24 *WORD -- temporary FPU value62 LTMP .equ -28 *LONG -- long temporary63 IP .equ -32 * LONG -- struct instdef *64 GROUP .equ -34 *WORD -- group number << 465 * 66 *Symbolic constants67 *------------------68 LASTLOCL .equ GROUP *last local on the stack69 * 70 FPU_DI .equ $2200 *sr value for disabling FPU interrupts71 PITCHMAX .equ 21920 *maximum pitch value72 VALMAX .equ $00007D00 *maximum FPU value73 VALMIN .equ $FFFF8300 *minimum FPU value74 VBLEN .equ 3938 *length of a voice buffer75 LSPCH .equ 2 *left shift for pitch sources76 * 77 .page 78 * 79 *execkey(trg, pch, vce)80 *short trg, pch, vce;81 *{82 * 28 29 .page 30 31 | Offsets for execkey() parameters 32 | -------------------------------- 33 TRG = 8 | WORD -- trigger 34 PCH = 10 | WORD -- pitch 35 VCE = 12 | WORD -- voice (0..11) 36 TAG = 14 | WORD -- I_TM_... inversion tag 37 38 | Register variables 39 | ------------------ 40 A_FP = A5 | LONG -- struct idfnhdr | 41 A_FPU = A4 | LONG -- FPU base address 42 A_SMP = A3 | LONG -- struct sment | 43 44 R_FPMANT = D7 | WORD -- FPU time mantissa 45 R_FPEXP = D6 | WORD -- FPU time exponent 46 R_FPCTL = D5 | WORD -- FPU control word 47 R_I = D4 | WORD -- loop index 48 R_FPVAL = D3 | WORD -- FPU value 49 50 | Local (stack) variables 51 | ----------------------- 52 PT = -4 | LONG -- instpnt | 53 VEP = -8 | LONG -- struct valent | 54 OLDI = -10 | WORD -- old IPL (sr) 55 OCTYPE = -12 | WORD -- oscillator 1 mode / scratch 56 VP = -14 | WORD -- voice # + function # index 57 SRCNUM = -16 | WORD -- general source # 58 SRCVAL = -18 | WORD -- general source value 59 TSRCVAL = -20 | WORD -- temporary general source value 60 MLTVAL = -22 | WORD -- general source multiplier 61 TFPVAL = -24 | WORD -- temporary FPU value 62 LTMP = -28 | LONG -- long temporary 63 IP = -32 | LONG -- struct instdef | 64 GROUP = -34 | WORD -- group number << 4 65 66 | Symbolic constants 67 | ------------------ 68 LASTLOCL = GROUP | last local on the stack 69 70 FPU_DI = 0x2200 | sr value for disabling FPU interrupts 71 PITCHMAX = 21920 | maximum pitch value 72 VALMAX = 0x00007D00 | maximum FPU value 73 VALMIN = 0xFFFF8300 | minimum FPU value 74 VBLEN = 3938 | length of a voice buffer 75 LSPCH = 2 | left shift for pitch sources 76 77 .page 78 79 | execkey(trg, pch, vce) 80 | short trg, pch, vce; 81 | { 82 83 83 _execkey: link A6,#LASTLOCL 84 84 movem.l D2-R_FPMANT/A_SMP-A_FP,-(sp) 85 * 86 *ip = &vbufs[vce];87 * 85 86 | ip = &vbufs[vce]; 87 88 88 move.w VCE(A6),D0 89 89 asl.w #2,D0 90 90 lea vbtab,A0 91 91 move.l 0(A0,D0.W),IP(A6) 92 * 93 *vce2trg[vce] = trg;94 * 92 93 | vce2trg[vce] = trg; 94 95 95 lsr.w #1,D0 96 96 lea _vce2trg,A0 97 97 move.w TRG(A6),0(A0,D0.W) 98 * 99 *group = (vce2grp[vce] - 1) << 4;100 * 98 99 | group = (vce2grp[vce] - 1) << 4; 100 101 101 move.w VCE(A6),A0 102 102 add.l A0,A0 … … 107 107 asl.w #4,D0 108 108 move.w D0,GROUP(A6) 109 * 110 .page 111 *------------------------------------------------------------------------------112 *Start function 0 -- Frq 1113 *------------------------------------------------------------------------------114 * 115 *if (ip->idhfnc[0].idftmd & I_TM_KEY) {116 * 109 110 .page 111 | ------------------------------------------------------------------------------ 112 | Start function 0 -- Frq 1 113 | ------------------------------------------------------------------------------ 114 115 | if (ip->idhfnc[0].idftmd & I_TM_KEY) { 116 117 117 move.l IP(A6),A0 118 118 move.b 93(A0),D0 … … 121 121 btst #0,D0 122 122 bne FN00A 123 * 123 124 124 jmp FN01 125 * 126 *vp = (vce << 4) + 1;127 * 125 126 | vp = (vce << 4) + 1; 127 128 128 FN00A: move VCE(A6),D0 129 129 asl #4,D0 130 130 add.w #1,D0 131 131 move D0,VP(A6) 132 * 133 *fpu = io_fpu + FPU_OFNC + (vp << 4);134 * 132 133 | fpu = io_fpu + FPU_OFNC + (vp << 4); 134 135 135 asl #5,D0 136 136 ext.l D0 137 137 move.l D0,A_FPU 138 add.l #_io_fpu+ $4000,A_FPU139 * 140 *fp = &ip->idhfnc[0];141 * 138 add.l #_io_fpu+0x4000,A_FPU 139 140 | fp = &ip->idhfnc[0]; 141 142 142 move.l IP(A6),A_FP 143 143 add.l #86,A_FP 144 * 145 *pt = &ip->idhpnt[fp->idfpt1];146 * 144 145 | pt = &ip->idhpnt[fp->idfpt1]; 146 147 147 clr.l D0 148 148 move.b 6(A_FP),D0 … … 154 154 add.l #242,D0 155 155 move.l D0,PT(A6) 156 * 157 .page 158 * 159 *srcnum = group | fp->idfsrc;160 * 156 157 .page 158 159 | srcnum = group | fp->idfsrc; 160 161 161 move.w GROUP(A6),D0 162 162 ext.l D0 … … 165 165 or D1,D0 166 166 move D0,SRCNUM(A6) 167 * 168 *vep = &valents[srcnum];169 * 167 168 | vep = &valents[srcnum]; 169 170 170 add.l D0,D0 171 171 move.l D0,D1 … … 174 174 add.l #_valents,D0 175 175 move.l D0,VEP(A6) 176 * 177 *smp = vpsms[vp];178 * 176 177 | smp = vpsms[vp]; 178 179 179 move VP(A6),A0 180 180 add.l A0,A0 … … 182 182 add.l #_vpsms,A0 183 183 move.l (A0),A_SMP 184 * 185 *if (srcnum NE smp->sm) {186 * 184 185 | if (srcnum NE smp->sm) { 186 187 187 clr D0 188 188 move 10(A_SMP),D0 189 189 cmp SRCNUM(A6),D0 190 190 beq F00L113 191 * 192 *(smp->prv)->nxt = smp->nxt;193 * 191 192 | (smp->prv)->nxt = smp->nxt; 193 194 194 move.l 4(A_SMP),A0 195 195 move.l (A_SMP),(A0) 196 * 197 *(smp->nxt)->prv = smp->prv;198 * 196 197 | (smp->nxt)->prv = smp->prv; 198 199 199 move.l (A_SMP),A0 200 200 move.l 4(A_SMP),4(A0) 201 * 202 * smp->prv = (struct sment *)vep;203 * 201 202 | smp->prv = (struct sment |)vep; 203 204 204 move.l VEP(A6),4(A_SMP) 205 * 206 *smp->nxt = vep->nxt;207 * 205 206 | smp->nxt = vep->nxt; 207 208 208 move.l VEP(A6),A0 209 209 move.l (A0),(A_SMP) 210 * 211 *(vep->nxt)->prv = smp;212 * 210 211 | (vep->nxt)->prv = smp; 212 213 213 move.l VEP(A6),A0 214 214 move.l (A0),A0 215 215 move.l A_SMP,4(A0) 216 * 217 *vep->nxt = smp;218 * 216 217 | vep->nxt = smp; 218 219 219 move.l VEP(A6),A0 220 220 move.l A_SMP,(A0) 221 * 222 *smp->sm = srcnum;223 * 221 222 | smp->sm = srcnum; 223 224 224 move SRCNUM(A6),10(A_SMP) 225 * 226 *}227 * 228 *mltval = fp->idfmlt;229 * 225 226 | } 227 228 | mltval = fp->idfmlt; 229 230 230 F00L113: move 2(A_FP),MLTVAL(A6) 231 * 232 .page 233 * 234 *switch (fp->idfsrc) {235 * 231 232 .page 233 234 | switch (fp->idfsrc) { 235 236 236 move.b 4(A_FP),D0 237 237 ext.w d0 238 238 cmp #10,D0 239 239 bhi F00L122 240 * 240 241 241 asl #2,D0 242 242 lea F00L123,A0 243 243 movea.l 0(A0,D0.W),A0 244 244 jmp (A0) 245 * 246 *case SM_NONE:247 *mltval = 0;248 * 245 246 | case SM_NONE: 247 | mltval = 0; 248 249 249 F00L116: clr MLTVAL(A6) 250 * 251 *tsrcval = 0;252 * 250 251 | tsrcval = 0; 252 253 253 clr TSRCVAL(A6) 254 * 255 *break;256 * 254 255 | break; 256 257 257 bra F00L114 258 * 259 *case SM_RAND:260 *tsrcval = xgetran(mltval);261 * 258 259 | case SM_RAND: 260 | tsrcval = xgetran(mltval); 261 262 262 F00L117: move MLTVAL(A6),(sp) 263 263 jsr _xgetran 264 264 move D0,TSRCVAL(A6) 265 * 266 *break;267 * 265 266 | break; 267 268 268 bra F00L114 269 * 270 *case SM_PTCH:271 *tsrcval = pch;272 * 269 270 | case SM_PTCH: 271 | tsrcval = pch; 272 273 273 F00L118: move PCH(A6),TSRCVAL(A6) 274 * 275 *break;276 * 274 275 | break; 276 277 277 bra F00L114 278 * 279 .page 280 * 281 *case SM_FREQ:282 *tsrcval = ptoftab[(pch >> 7) & 0x00FF];283 * 278 279 .page 280 281 | case SM_FREQ: 282 | tsrcval = ptoftab[(pch >> 7) & 0x00FF]; 283 284 284 F00L119: move.w PCH(A6),D0 285 285 asr.w #7,D0 286 and.w # $00FF,D0286 and.w #0x00FF,D0 287 287 move.w D0,A0 288 288 add.l A0,A0 289 289 add.l #_ptoftab,A0 290 290 move.w (A0),TSRCVAL(A6) 291 * 292 *break;293 * 291 292 | break; 293 294 294 bra F00L114 295 * 296 *case SM_KVEL:297 *tsrcval = veltab[trg];298 * 295 296 | case SM_KVEL: 297 | tsrcval = veltab[trg]; 298 299 299 F00L120: move.w TRG(A6),A0 300 300 add.l A0,A0 301 301 add.l #_veltab,A0 302 302 move.w (A0),TSRCVAL(A6) 303 * 304 *break;305 * 303 304 | break; 305 306 306 bra F00L114 307 * 308 *case SM_KPRS:309 *tsrcval = prstab[trg];310 * 307 308 | case SM_KPRS: 309 | tsrcval = prstab[trg]; 310 311 311 F00L121: move.w TRG(A6),A0 312 312 add.l A0,A0 313 313 add.l #_prstab,A0 314 314 move.w (A0),TSRCVAL(A6) 315 * 316 *break;317 * 315 316 | break; 317 318 318 bra F00L114 319 * 320 *default:321 *tsrcval = vep->val;322 * 319 320 | default: 321 | tsrcval = vep->val; 322 323 323 F00L122: move.l VEP(A6),A0 324 324 move.w 8(A0),TSRCVAL(A6) 325 * 326 *}327 * 328 .page 329 * 330 *srcval = addpch(tsrcval, 0);331 * 325 326 | } 327 328 .page 329 330 | srcval = addpch(tsrcval, 0); 331 332 332 F00L114: move.w TSRCVAL(A6),D0 333 333 ext.l D0 334 334 asr.l #5,D0 335 *sub.l #500,D0335 | sub.l #500,D0 336 336 asl.l #LSPCH,D0 337 337 cmp.l #PITCHMAX,D0 338 338 ble F00L129A 339 * 339 340 340 move.l #PITCHMAX,D0 341 * 341 342 342 F00L129A: move D0,SRCVAL(A6) 343 * 344 .page 345 * 346 *if (pt->ipvsrc) {347 * 343 344 .page 345 346 | if (pt->ipvsrc) { 347 348 348 F00L124: move.l PT(A6),A0 349 349 tst.b 6(A0) 350 350 beq F00L136 351 * 352 *switch (pt->ipvsrc) {353 * 351 352 | switch (pt->ipvsrc) { 353 354 354 move.l PT(A6),A0 355 355 move.b 6(A0),D0 … … 358 358 cmp #9,D0 359 359 bhi F00L144 360 * 360 361 361 asl #2,D0 362 362 lea F00L145,A0 363 363 move.l 0(A0,D0.W),A0 364 364 jmp (A0) 365 * 366 *case SM_RAND:367 *ltmp = xgetran(pt_>ipvmlt);368 * 365 366 | case SM_RAND: 367 | ltmp = xgetran(pt_>ipvmlt); 368 369 369 F00L139: move.l PT(A6),A0 370 370 move 4(A0),(sp) … … 372 372 ext.l D0 373 373 move.l D0,LTMP(A6) 374 * 375 *break;376 * 374 375 | break; 376 377 377 bra F00L137 378 * 379 *case SM_PTCH:380 *ltmp = pch;381 * 378 379 | case SM_PTCH: 380 | ltmp = pch; 381 382 382 F00L140: move PCH(A6),A0 383 383 move.l A0,LTMP(A6) 384 * 385 *break;386 * 384 385 | break; 386 387 387 bra F00L137 388 * 389 .page 390 * 391 *case SM_FREQ:392 *ltmp = ptoftab[(pch >> 7) & 0x00FF];393 * 388 389 .page 390 391 | case SM_FREQ: 392 | ltmp = ptoftab[(pch >> 7) & 0x00FF]; 393 394 394 F00L141: move PCH(A6),D0 395 395 asr #7,D0 … … 401 401 ext.l D0 402 402 move.l D0,LTMP(A6) 403 * 404 *break;405 * 403 404 | break; 405 406 406 bra F00L137 407 * 408 *case SM_KVEL:409 *ltmp = veltab[trg];410 * 407 408 | case SM_KVEL: 409 | ltmp = veltab[trg]; 410 411 411 F00L142: move TRG(A6),A0 412 412 add.l A0,A0 … … 415 415 ext.l D0 416 416 move.l D0,LTMP(A6) 417 * 418 *break;419 * 417 418 | break; 419 420 420 bra F00L137 421 * 422 .page 423 * 424 *case SM_KPRS:425 *ltmp = prstab[trg];426 * 421 422 .page 423 424 | case SM_KPRS: 425 | ltmp = prstab[trg]; 426 427 427 F00L143: move TRG(A6),A0 428 428 add.l A0,A0 … … 431 431 ext.l D0 432 432 move.l D0,LTMP(A6) 433 * 434 *break;435 * 433 434 | break; 435 436 436 bra F00L137 437 * 438 .page 439 * 440 *default:441 *ltmp = valents[group | pt->ipvsrc].val;442 * 437 438 .page 439 440 | default: 441 | ltmp = valents[group | pt->ipvsrc].val; 442 443 443 F00L144: move.l PT(A6),A0 444 444 clr.l D0 … … 454 454 move 8(A0,A1.l),D0 455 455 move.l D0,LTMP(A6) 456 * 457 *}458 * 459 * 460 .page 461 * 462 * ltmp = (ltmp *pt->ipvmlt) >> 15;463 * 456 457 | } 458 459 460 .page 461 462 | ltmp = (ltmp | pt->ipvmlt) >> 15; 463 464 464 F00L137: move.l PT(A6),A0 465 465 move.w 4(A0),D0 … … 469 469 asr.l D1,D0 470 470 move.l D0,LTMP(A6) 471 * 472 *ltmp += (long)pt->ipval;473 * 471 472 | ltmp += (long)pt->ipval; 473 474 474 move.l PT(A6),A0 475 475 move 2(A0),D0 476 476 ext.l D0 477 477 add.l D0,LTMP(A6) 478 * 479 *if (ltmp GT (long)VALMAX)480 *ltmp = (long)VALMAX;481 * 478 479 | if (ltmp GT (long)VALMAX) 480 | ltmp = (long)VALMAX; 481 482 482 cmp.l #VALMAX,LTMP(A6) 483 483 ble F00L146 484 * 484 485 485 move.l #VALMAX,LTMP(A6) 486 486 bra F00L147 487 * 488 *else if (ltmp LT (long)VALMIN)489 *ltmp = (long)VALMIN;490 * 487 488 | else if (ltmp LT (long)VALMIN) 489 | ltmp = (long)VALMIN; 490 491 491 F00L146: cmp.l #VALMIN,LTMP(A6) 492 492 bge F00L147 493 * 493 494 494 move.l #VALMIN,LTMP(A6) 495 * 496 *tfpval = (short)ltmp;497 * 495 496 | tfpval = (short)ltmp; 497 498 498 F00L147: move.w LTMP+2(A6),TFPVAL(A6) 499 499 bra F00L149 500 * 501 *} else {502 * 503 *tfpval = pt->ipval;504 * 500 501 | } else { 502 503 | tfpval = pt->ipval; 504 505 505 F00L136: move.l PT(A6),A0 506 506 move 2(A0),TFPVAL(A6) 507 * 508 *}509 * 510 .page 511 * 512 *fpmant = (((long)pt->iptim & 0x0000FFF0L)513 * *((long)timemlt & 0x0000FFFFL)) >> 15;514 * 507 508 | } 509 510 .page 511 512 | fpmant = (((long)pt->iptim & 0x0000FFF0L) 513 | | ((long)timemlt & 0x0000FFFFL)) >> 15; 514 515 515 F00L149: move.l PT(A6),A0 516 516 move.w (A0),D0 517 517 move.w D0,D2 518 andi.w # $FFF0,D0518 andi.w #0xFFF0,D0 519 519 move.w _timemlt,D1 520 520 muls D1,D0 … … 522 522 asr.l D1,D0 523 523 move D0,R_FPMANT 524 * 525 *fpexp = expbit[pt->iptim & 0x000F];526 * 527 and # $000F,D2524 525 | fpexp = expbit[pt->iptim & 0x000F]; 526 527 and #0x000F,D2 528 528 move D2,A0 529 529 add.l A0,A0 530 530 add.l #_expbit,A0 531 531 move (A0),R_FPEXP 532 * 533 .page 534 * 535 *octype = ip->idhos1c & OC_MOD;536 * 532 533 .page 534 535 | octype = ip->idhos1c & OC_MOD; 536 537 537 F00L152: move.l IP(A6),A0 538 538 move.b 74(A0),D0 539 539 and #3,D0 540 * 541 *if ((octype EQ OC_FRQ) OR (octype EQ OC_PCH))542 * 540 541 | if ((octype EQ OC_FRQ) OR (octype EQ OC_PCH)) 542 543 543 cmp #2,D0 544 544 beq F00L1001 545 * 545 546 546 cmp #3,D0 547 547 bne F00L153 548 * 549 *fp->idfpch = ip->idhos1v;550 * 548 549 | fp->idfpch = ip->idhos1v; 550 551 551 F00L1001: move.l IP(A6),A0 552 552 move 78(A0),(A_FP) 553 553 bra F00L154 554 * 555 *else556 *fp->idfpch = pch + ip->idhos1v;557 * 554 555 | else 556 | fp->idfpch = pch + ip->idhos1v; 557 558 558 F00L153: move.w PCH(A6),D0 559 559 ext.l D0 … … 561 561 ext.l D1 562 562 add.l d1,d0 563 * 564 *if (fp->idfpch > PITCHMAX)565 *fp->idfpch = PITCHMAX;566 * 563 564 | if (fp->idfpch > PITCHMAX) 565 | fp->idfpch = PITCHMAX; 566 567 567 cmp.l #PITCHMAX,d0 568 568 ble F00153A 569 * 569 570 570 move.l #PITCHMAX,d0 571 * 571 572 572 F00153A: move.w d0,(A_FP) 573 * 574 *fpval = addpch(tfpval, fp->idfpch);575 * 573 574 | fpval = addpch(tfpval, fp->idfpch); 575 576 576 F00L154: move.w TFPVAL(A6),D1 577 577 ext.l D1 … … 584 584 cmp.l #PITCHMAX,D0 585 585 ble F00L154A 586 * 586 587 587 move.l #PITCHMAX,D0 588 * 588 589 589 F00L154A: move D0,R_FPVAL 590 * 591 .page 592 * 590 591 .page 592 593 593 move.b 5(A_FP),D0 594 594 ext.w D0 595 595 sub.w #1,D0 596 596 movea.l PT(A6),A0 597 * 598 *oldi = setipl(FPU_DI);599 * 597 598 | oldi = setipl(FPU_DI); 599 600 600 move sr,OLDI(A6) 601 601 move #FPU_DI,sr 602 * 602 603 603 F00L168: clr.b 10(A0) 604 604 add.l #12,A0 605 605 dbra D0,F00L168 606 * 607 .page 608 * 609 *fp->idftmd ^= I_NVBITS;610 * 606 607 .page 608 609 | fp->idftmd ^= I_NVBITS; 610 611 611 F00L165: eor.b #24,7(A_FP) 612 * 613 *fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;614 * 612 613 | fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003; 614 615 615 move.b 7(A_FP),R_FPCTL 616 616 and #28,R_FPCTL 617 617 or #3,R_FPCTL 618 * 619 *fp->idfcpt = fp->idfpt1;620 * 618 619 | fp->idfcpt = fp->idfpt1; 620 621 621 move.b 6(A_FP),8(A_FP) 622 * 623 *fp->idftmd |= I_ACTIVE;624 * 622 623 | fp->idftmd |= I_ACTIVE; 624 625 625 or.b #2,7(A_FP) 626 * 627 *fp->idftrf = trg;628 * 626 627 | fp->idftrf = trg; 628 629 629 move TRG(A6),10(A_FP) 630 * 631 * *(fpu + (long)FPU_TCV1) = srcval;632 * 633 move SRCVAL(A6), $8(A_FPU)634 * 635 *++octype;636 * 630 631 | |(fpu + (long)FPU_TCV1) = srcval; 632 633 move SRCVAL(A6),0x8(A_FPU) 634 635 | ++octype; 636 637 637 add #1,OCTYPE(A6) 638 * 639 * *(fpu + (long)FPU_TSF1) = mltval;640 * 641 move MLTVAL(A6), $A(A_FPU)642 * 643 *++octype;644 * 638 639 | |(fpu + (long)FPU_TSF1) = mltval; 640 641 move MLTVAL(A6),0xA(A_FPU) 642 643 | ++octype; 644 645 645 add #1,OCTYPE(A6) 646 * 647 * *(fpu + (long)FPU_TMNT) = fpmant;648 * 649 move R_FPMANT, $14(A_FPU)650 * 651 *++octype;652 * 646 647 | |(fpu + (long)FPU_TMNT) = fpmant; 648 649 move R_FPMANT,0x14(A_FPU) 650 651 | ++octype; 652 653 653 add #1,OCTYPE(A6) 654 * 655 * *(fpu + (long)FPU_TEXP) = fpexp;656 * 657 move R_FPEXP, $16(A_FPU)658 * 659 *++octype;660 * 654 655 | |(fpu + (long)FPU_TEXP) = fpexp; 656 657 move R_FPEXP,0x16(A_FPU) 658 659 | ++octype; 660 661 661 add #1,OCTYPE(A6) 662 * 663 .page 664 * 665 *if (fp->idftmd & I_VNSUBN)666 * 662 663 .page 664 665 | if (fp->idftmd & I_VNSUBN) 666 667 667 btst #3,7(A_FP) 668 668 beq F00L169 669 * 670 * *(fpu + (long)FPU_TNV1) = fpval;671 * 672 move R_FPVAL, $1C(A_FPU)669 670 | |(fpu + (long)FPU_TNV1) = fpval; 671 672 move R_FPVAL,0x1C(A_FPU) 673 673 bra F00L170 674 * 675 *else676 * *(fpu + (long)FPU_TNV0) = fpval;677 * 674 675 | else 676 | |(fpu + (long)FPU_TNV0) = fpval; 677 678 678 F00L169: move R_FPVAL,2(A_FPU) 679 * 680 *++octype;681 * 679 680 | ++octype; 681 682 682 F00L170: add #1,OCTYPE(A6) 683 * 684 * *(fpu + (long)FPU_TCTL) = fpctl;685 * 683 684 | |(fpu + (long)FPU_TCTL) = fpctl; 685 686 686 move R_FPCTL,(A_FPU) 687 * 688 *setipl(oldi);689 * 687 688 | setipl(oldi); 689 690 690 move OLDI(A6),sr 691 *}692 * 693 .page 694 *------------------------------------------------------------------------------695 *Start function 1 -- Frq 2696 *------------------------------------------------------------------------------697 *if (legato) {698 * 699 *legato = 0;700 *return;701 *}691 | } 692 693 .page 694 | ------------------------------------------------------------------------------ 695 | Start function 1 -- Frq 2 696 | ------------------------------------------------------------------------------ 697 | if (legato) { 698 699 | legato = 0; 700 | return; 701 | } 702 702 FN01: tst.w _legato 703 703 beq FN01AA 704 * 704 705 705 clr.w _legato 706 706 bra FNEXIT 707 * 708 *if (ip->idhfnc[1].idftmd & I_TM_KEY) {709 * 707 708 | if (ip->idhfnc[1].idftmd & I_TM_KEY) { 709 710 710 FN01AA: move.l IP(A6),A0 711 711 move.b 105(A0),D0 … … 714 714 btst #0,D0 715 715 bne FN01A 716 * 716 717 717 jmp FN02 718 * 719 *vp = (vce << 4) + 3;720 * 718 719 | vp = (vce << 4) + 3; 720 721 721 FN01A: move VCE(A6),D0 722 722 asl #4,D0 723 723 add.w #3,D0 724 724 move D0,VP(A6) 725 * 726 *fpu = io_fpu + FPU_OFNC + (vp << 4);727 * 725 726 | fpu = io_fpu + FPU_OFNC + (vp << 4); 727 728 728 asl #5,D0 729 729 ext.l D0 730 730 move.l D0,A_FPU 731 add.l #_io_fpu+ $4000,A_FPU732 * 733 *fp = &ip->idhfnc[1];734 * 731 add.l #_io_fpu+0x4000,A_FPU 732 733 | fp = &ip->idhfnc[1]; 734 735 735 move.l #12,A_FP 736 736 add.l IP(A6),A_FP 737 737 add.l #86,A_FP 738 * 739 *pt = &ip->idhpnt[fp->idfpt1];740 * 738 739 | pt = &ip->idhpnt[fp->idfpt1]; 740 741 741 clr.l D0 742 742 move.b 6(A_FP),D0 … … 748 748 add.l #242,D0 749 749 move.l D0,PT(A6) 750 * 751 .page 752 * 753 *srcnum = group | fp->idfsrc;754 * 750 751 .page 752 753 | srcnum = group | fp->idfsrc; 754 755 755 move.w GROUP(A6),D0 756 756 ext.l D0 … … 759 759 or D1,D0 760 760 move D0,SRCNUM(A6) 761 * 762 *vep = &valents[srcnum];763 * 761 762 | vep = &valents[srcnum]; 763 764 764 add.l D0,D0 765 765 move.l D0,D1 … … 768 768 add.l #_valents,D0 769 769 move.l D0,VEP(A6) 770 * 771 *smp = vpsms[vp];772 * 770 771 | smp = vpsms[vp]; 772 773 773 move VP(A6),A0 774 774 add.l A0,A0 … … 776 776 add.l #_vpsms,A0 777 777 move.l (A0),A_SMP 778 * 779 *if (srcnum NE smp->sm) {780 * 778 779 | if (srcnum NE smp->sm) { 780 781 781 clr D0 782 782 move 10(A_SMP),D0 783 783 cmp SRCNUM(A6),D0 784 784 beq F01L113 785 * 786 *(smp->prv)->nxt = smp->nxt;787 * 785 786 | (smp->prv)->nxt = smp->nxt; 787 788 788 move.l 4(A_SMP),A0 789 789 move.l (A_SMP),(A0) 790 * 791 *(smp->nxt)->prv = smp->prv;792 * 790 791 | (smp->nxt)->prv = smp->prv; 792 793 793 move.l (A_SMP),A0 794 794 move.l 4(A_SMP),4(A0) 795 * 796 * smp->prv = (struct sment *)vep;797 * 795 796 | smp->prv = (struct sment |)vep; 797 798 798 move.l VEP(A6),4(A_SMP) 799 * 800 *smp->nxt = vep->nxt;801 * 799 800 | smp->nxt = vep->nxt; 801 802 802 move.l VEP(A6),A0 803 803 move.l (A0),(A_SMP) 804 * 805 *(vep->nxt)->prv = smp;806 * 804 805 | (vep->nxt)->prv = smp; 806 807 807 move.l VEP(A6),A0 808 808 move.l (A0),A0 809 809 move.l A_SMP,4(A0) 810 * 811 *vep->nxt = smp;812 * 810 811 | vep->nxt = smp; 812 813 813 move.l VEP(A6),A0 814 814 move.l A_SMP,(A0) 815 * 816 *smp->sm = srcnum;817 * 815 816 | smp->sm = srcnum; 817 818 818 move SRCNUM(A6),10(A_SMP) 819 * 820 *}821 * 822 *mltval = fp->idfmlt;823 * 819 820 | } 821 822 | mltval = fp->idfmlt; 823 824 824 F01L113: move 2(A_FP),MLTVAL(A6) 825 * 826 .page 827 * 828 *switch (fp->idfsrc) {829 * 825 826 .page 827 828 | switch (fp->idfsrc) { 829 830 830 move.b 4(A_FP),D0 831 831 ext.w d0 832 832 cmp #10,D0 833 833 bhi F01L122 834 * 834 835 835 asl #2,D0 836 836 lea F01L123,A0 837 837 movea.l 0(A0,D0.W),A0 838 838 jmp (A0) 839 * 840 *case SM_NONE:841 *mltval = 0;842 * 839 840 | case SM_NONE: 841 | mltval = 0; 842 843 843 F01L116: clr MLTVAL(A6) 844 * 845 *tsrcval = 0;846 * 844 845 | tsrcval = 0; 846 847 847 clr TSRCVAL(A6) 848 * 849 *break;850 * 848 849 | break; 850 851 851 bra F01L114 852 * 853 *case SM_RAND:854 *tsrcval = xgetran(mltval);855 * 852 853 | case SM_RAND: 854 | tsrcval = xgetran(mltval); 855 856 856 F01L117: move MLTVAL(A6),(sp) 857 857 jsr _xgetran 858 858 move D0,TSRCVAL(A6) 859 * 860 *break;861 * 859 860 | break; 861 862 862 bra F01L114 863 * 864 *case SM_PTCH:865 *tsrcval = pch;866 * 863 864 | case SM_PTCH: 865 | tsrcval = pch; 866 867 867 F01L118: move PCH(A6),TSRCVAL(A6) 868 * 869 *break;870 * 868 869 | break; 870 871 871 bra F01L114 872 * 873 .page 874 * 875 *case SM_FREQ:876 *tsrcval = ptoftab[(pch >> 7) & 0x00FF];877 * 872 873 .page 874 875 | case SM_FREQ: 876 | tsrcval = ptoftab[(pch >> 7) & 0x00FF]; 877 878 878 F01L119: move PCH(A6),D0 879 879 asr #7,D0 … … 883 883 add.l #_ptoftab,A0 884 884 move (A0),TSRCVAL(A6) 885 * 886 *break;887 * 885 886 | break; 887 888 888 bra F01L114 889 * 890 *case SM_KVEL:891 *tsrcval = veltab[trg];892 * 889 890 | case SM_KVEL: 891 | tsrcval = veltab[trg]; 892 893 893 F01L120: move TRG(A6),A0 894 894 add.l A0,A0 895 895 add.l #_veltab,A0 896 896 move (A0),TSRCVAL(A6) 897 * 898 *break;899 * 897 898 | break; 899 900 900 bra F01L114 901 * 902 *case SM_KPRS:903 *tsrcval = prstab[trg];904 * 901 902 | case SM_KPRS: 903 | tsrcval = prstab[trg]; 904 905 905 F01L121: move TRG(A6),A0 906 906 add.l A0,A0 907 907 add.l #_prstab,A0 908 908 move (A0),TSRCVAL(A6) 909 * 910 *break;911 * 909 910 | break; 911 912 912 bra F01L114 913 * 914 *default:915 *tsrcval = vep->val;916 * 913 914 | default: 915 | tsrcval = vep->val; 916 917 917 F01L122: move.l VEP(A6),A0 918 918 move 8(A0),TSRCVAL(A6) 919 * 920 *}921 * 922 .page 923 * 924 *srcval = addpch(tsrcval, 0);925 * 919 920 | } 921 922 .page 923 924 | srcval = addpch(tsrcval, 0); 925 926 926 F01L114: move.w TSRCVAL(A6),D0 927 927 ext.l D0 928 928 asr.l #5,D0 929 *sub.l #500,D0929 | sub.l #500,D0 930 930 asl.l #LSPCH,D0 931 931 cmp.l #PITCHMAX,D0 932 932 ble F01L129A 933 * 933 934 934 move.l #PITCHMAX,D0 935 * 935 936 936 F01L129A: move D0,SRCVAL(A6) 937 * 938 .page 939 * 940 *if (pt->ipvsrc) {941 * 937 938 .page 939 940 | if (pt->ipvsrc) { 941 942 942 F01L124: move.l PT(A6),A0 943 943 tst.b 6(A0) 944 944 beq F01L136 945 * 946 *switch (pt->ipvsrc) {947 * 945 946 | switch (pt->ipvsrc) { 947 948 948 move.l PT(A6),A0 949 949 move.b 6(A0),D0 … … 952 952 cmp #9,D0 953 953 bhi F01L144 954 * 954 955 955 asl #2,D0 956 956 lea F01L145,A0 957 957 move.l 0(A0,D0.W),A0 958 958 jmp (A0) 959 * 960 *case SM_RAND:961 *ltmp = xgetran(pt_>ipvmlt);962 * 959 960 | case SM_RAND: 961 | ltmp = xgetran(pt_>ipvmlt); 962 963 963 F01L139: move.l PT(A6),A0 964 964 move 4(A0),(sp) … … 966 966 ext.l D0 967 967 move.l D0,LTMP(A6) 968 * 969 *break;970 * 968 969 | break; 970 971 971 bra F01L137 972 * 973 *case SM_PTCH:974 *ltmp = pch;975 * 972 973 | case SM_PTCH: 974 | ltmp = pch; 975 976 976 F01L140: move PCH(A6),A0 977 977 move.l A0,LTMP(A6) 978 * 979 *break;980 * 978 979 | break; 980 981 981 bra F01L137 982 * 983 .page 984 * 985 *case SM_FREQ:986 *ltmp = ptoftab[(pch >> 7) & 0x00FF];987 * 982 983 .page 984 985 | case SM_FREQ: 986 | ltmp = ptoftab[(pch >> 7) & 0x00FF]; 987 988 988 F01L141: move PCH(A6),D0 989 989 asr #7,D0 … … 995 995 ext.l D0 996 996 move.l D0,LTMP(A6) 997 * 998 *break;999 * 997 998 | break; 999 1000 1000 bra F01L137 1001 * 1002 *case SM_KVEL:1003 *ltmp = veltab[trg];1004 * 1001 1002 | case SM_KVEL: 1003 | ltmp = veltab[trg]; 1004 1005 1005 F01L142: move TRG(A6),A0 1006 1006 add.l A0,A0 … … 1009 1009 ext.l D0 1010 1010 move.l D0,LTMP(A6) 1011 * 1012 *break;1013 * 1011 1012 | break; 1013 1014 1014 bra F01L137 1015 * 1016 .page 1017 * 1018 *case SM_KPRS:1019 *ltmp = prstab[trg];1020 * 1015 1016 .page 1017 1018 | case SM_KPRS: 1019 | ltmp = prstab[trg]; 1020 1021 1021 F01L143: move TRG(A6),A0 1022 1022 add.l A0,A0 … … 1025 1025 ext.l D0 1026 1026 move.l D0,LTMP(A6) 1027 * 1028 *break;1029 * 1027 1028 | break; 1029 1030 1030 bra F01L137 1031 * 1032 .page 1033 * 1034 *default:1035 *ltmp = valents[group | pt->ipvsrc].val;1036 * 1031 1032 .page 1033 1034 | default: 1035 | ltmp = valents[group | pt->ipvsrc].val; 1036 1037 1037 F01L144: move.l PT(A6),A0 1038 1038 clr.l D0 … … 1048 1048 move 8(A0,A1.l),D0 1049 1049 move.l D0,LTMP(A6) 1050 * 1051 *}1052 * 1053 * 1054 .page 1055 * 1056 * ltmp = (ltmp *pt->ipvmlt) >> 15;1057 * 1050 1051 | } 1052 1053 1054 .page 1055 1056 | ltmp = (ltmp | pt->ipvmlt) >> 15; 1057 1058 1058 F01L137: move.l PT(A6),A0 1059 1059 move.w 4(A0),D0 … … 1063 1063 asr.l D1,D0 1064 1064 move.l D0,LTMP(A6) 1065 * 1066 *ltmp += (long)pt->ipval;1067 * 1065 1066 | ltmp += (long)pt->ipval; 1067 1068 1068 move.l PT(A6),A0 1069 1069 move 2(A0),D0 1070 1070 ext.l D0 1071 1071 add.l D0,LTMP(A6) 1072 * 1073 *if (ltmp GT (long)VALMAX)1074 *ltmp = (long)VALMAX;1075 * 1072 1073 | if (ltmp GT (long)VALMAX) 1074 | ltmp = (long)VALMAX; 1075 1076 1076 cmp.l #VALMAX,LTMP(A6) 1077 1077 ble F01L146 1078 * 1078 1079 1079 move.l #VALMAX,LTMP(A6) 1080 1080 bra F01L147 1081 * 1082 *else if (ltmp LT (long)VALMIN)1083 *ltmp = (long)VALMIN;1084 * 1081 1082 | else if (ltmp LT (long)VALMIN) 1083 | ltmp = (long)VALMIN; 1084 1085 1085 F01L146: cmp.l #VALMIN,LTMP(A6) 1086 1086 bge F01L147 1087 * 1087 1088 1088 move.l #VALMIN,LTMP(A6) 1089 * 1090 *tfpval = (short)ltmp;1091 * 1089 1090 | tfpval = (short)ltmp; 1091 1092 1092 F01L147: move.w LTMP+2(A6),TFPVAL(A6) 1093 1093 bra F01L149 1094 * 1095 *} else {1096 * 1097 *tfpval = pt->ipval;1098 * 1094 1095 | } else { 1096 1097 | tfpval = pt->ipval; 1098 1099 1099 F01L136: move.l PT(A6),A0 1100 1100 move 2(A0),TFPVAL(A6) 1101 * 1102 *}1103 * 1104 .page 1105 * 1106 *fpmant = (((long)pt->iptom & 0x0000FFF0L)1107 * *((long)timemlt & 0x0000FFFFL)) >> 15;1108 * 1101 1102 | } 1103 1104 .page 1105 1106 | fpmant = (((long)pt->iptom & 0x0000FFF0L) 1107 | | ((long)timemlt & 0x0000FFFFL)) >> 15; 1108 1109 1109 F01L149: move.l PT(A6),A0 1110 1110 move.w (A0),D0 1111 1111 move.w D0,D2 1112 andi.w # $FFF0,D01112 andi.w #0xFFF0,D0 1113 1113 move.w _timemlt,D1 1114 1114 muls D1,D0 … … 1116 1116 asr.l D1,D0 1117 1117 move D0,R_FPMANT 1118 * 1119 *fpexp = expbit[pt->iptim & 0x000F];1120 * 1121 and # $000F,D21118 1119 | fpexp = expbit[pt->iptim & 0x000F]; 1120 1121 and #0x000F,D2 1122 1122 move D2,A0 1123 1123 add.l A0,A0 1124 1124 add.l #_expbit,A0 1125 1125 move (A0),R_FPEXP 1126 * 1127 .page 1128 * 1129 *fp->idfpch = ip->idhos2v;1130 * 1126 1127 .page 1128 1129 | fp->idfpch = ip->idhos2v; 1130 1131 1131 F01L155: move.l IP(A6),A0 1132 1132 move.w 80(A0),(A_FP) 1133 * 1134 *fpval = addpch(tfpval, fp_>idfpch);1135 * 1133 1134 | fpval = addpch(tfpval, fp_>idfpch); 1135 1136 1136 move.w TFPVAL(A6),D1 1137 1137 ext.l D1 … … 1144 1144 cmp.l #PITCHMAX,D0 1145 1145 ble F01L155A 1146 * 1146 1147 1147 move.l #PITCHMAX,D0 1148 * 1148 1149 1149 F01L155A: move D0,R_FPVAL 1150 * 1151 .page 1152 * 1150 1151 .page 1152 1153 1153 move.b 5(A_FP),D0 1154 1154 ext.w D0 1155 1155 sub.w #1,D0 1156 1156 movea.l PT(A6),A0 1157 * 1158 *oldi = setipl(FPU_DI);1159 * 1157 1158 | oldi = setipl(FPU_DI); 1159 1160 1160 move sr,OLDI(A6) 1161 1161 move #FPU_DI,sr 1162 * 1162 1163 1163 F01L168: clr.b 10(A0) 1164 1164 add.l #12,a0 1165 1165 dbra D0,F01L168 1166 * 1167 .page 1168 * 1169 *fp->idftmd ^= I_NVBITS;1170 * 1166 1167 .page 1168 1169 | fp->idftmd ^= I_NVBITS; 1170 1171 1171 F01L165: eor.b #24,7(A_FP) 1172 * 1173 *fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;1174 * 1172 1173 | fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003; 1174 1175 1175 move.b 7(A_FP),R_FPCTL 1176 1176 and #28,R_FPCTL 1177 1177 or #3,R_FPCTL 1178 * 1179 *fp->idfcpt = fp->idfpt1;1180 * 1178 1179 | fp->idfcpt = fp->idfpt1; 1180 1181 1181 move.b 6(A_FP),8(A_FP) 1182 * 1183 *fp->idftmd |= I_ACTIVE;1184 * 1182 1183 | fp->idftmd |= I_ACTIVE; 1184 1185 1185 or.b #2,7(A_FP) 1186 * 1187 *fp->idftrf = trg;1188 * 1186 1187 | fp->idftrf = trg; 1188 1189 1189 move TRG(A6),10(A_FP) 1190 * 1191 * *(fpu + (long)FPU_TCV1) = srcval;1192 * 1193 move SRCVAL(A6), $8(A_FPU)1194 * 1195 *++octype;1196 * 1190 1191 | |(fpu + (long)FPU_TCV1) = srcval; 1192 1193 move SRCVAL(A6),0x8(A_FPU) 1194 1195 | ++octype; 1196 1197 1197 add #1,OCTYPE(A6) 1198 * 1199 * *(fpu + (long)FPU_TSF1) = mltval;1200 * 1201 move MLTVAL(A6), $A(A_FPU)1202 * 1203 *++octype;1204 * 1198 1199 | |(fpu + (long)FPU_TSF1) = mltval; 1200 1201 move MLTVAL(A6),0xA(A_FPU) 1202 1203 | ++octype; 1204 1205 1205 add #1,OCTYPE(A6) 1206 * 1207 * *(fpu + (long)FPU_TMNT) = fpmant;1208 * 1209 move R_FPMANT, $14(A_FPU)1210 * 1211 *++octype;1212 * 1206 1207 | |(fpu + (long)FPU_TMNT) = fpmant; 1208 1209 move R_FPMANT,0x14(A_FPU) 1210 1211 | ++octype; 1212 1213 1213 add #1,OCTYPE(A6) 1214 * 1215 * *(fpu + (long)FPU_TEXP) = fpexp;1216 * 1217 move R_FPEXP, $16(A_FPU)1218 * 1219 *++octype;1220 * 1214 1215 | |(fpu + (long)FPU_TEXP) = fpexp; 1216 1217 move R_FPEXP,0x16(A_FPU) 1218 1219 | ++octype; 1220 1221 1221 add #1,OCTYPE(A6) 1222 * 1223 .page 1224 * 1225 *if (fp->idftmd & I_VNSUBN)1226 * 1222 1223 .page 1224 1225 | if (fp->idftmd & I_VNSUBN) 1226 1227 1227 btst #3,7(A_FP) 1228 1228 beq F01L169 1229 * 1230 * *(fpu + (long)FPU_TNV1) = fpval;1231 * 1232 move R_FPVAL, $1C(A_FPU)1229 1230 | |(fpu + (long)FPU_TNV1) = fpval; 1231 1232 move R_FPVAL,0x1C(A_FPU) 1233 1233 bra F01L170 1234 * 1235 *else1236 * *(fpu + (long)FPU_TNV0) = fpval;1237 * 1234 1235 | else 1236 | |(fpu + (long)FPU_TNV0) = fpval; 1237 1238 1238 F01L169: move R_FPVAL,2(A_FPU) 1239 * 1240 *++octype;1241 * 1239 1240 | ++octype; 1241 1242 1242 F01L170: add #1,OCTYPE(A6) 1243 * 1244 * *(fpu + (long)FPU_TCTL) = fpctl;1245 * 1243 1244 | |(fpu + (long)FPU_TCTL) = fpctl; 1245 1246 1246 move R_FPCTL,(A_FPU) 1247 * 1248 *setipl(oldi);1249 * 1247 1248 | setipl(oldi); 1249 1250 1250 move OLDI(A6),sr 1251 * 1252 .page 1253 *------------------------------------------------------------------------------1254 *Start function 2 -- Frq 31255 *------------------------------------------------------------------------------1256 * 1257 *if (ip->idhfnc[2].idftmd & I_TM_KEY) {1258 * 1251 1252 .page 1253 | ------------------------------------------------------------------------------ 1254 | Start function 2 -- Frq 3 1255 | ------------------------------------------------------------------------------ 1256 1257 | if (ip->idhfnc[2].idftmd & I_TM_KEY) { 1258 1259 1259 FN02: move.l IP(A6),A0 1260 1260 move.b 117(A0),D0 … … 1263 1263 btst #0,D0 1264 1264 bne FN02A 1265 * 1265 1266 1266 jmp FN03 1267 * 1268 *vp = (vce << 4) + 5;1269 * 1267 1268 | vp = (vce << 4) + 5; 1269 1270 1270 FN02A: move VCE(A6),D0 1271 1271 asl #4,D0 1272 1272 add.w #5,D0 1273 1273 move D0,VP(A6) 1274 * 1275 *fpu = io_fpu + FPU_OFNC + (vp << 4);1276 * 1274 1275 | fpu = io_fpu + FPU_OFNC + (vp << 4); 1276 1277 1277 asl #5,D0 1278 1278 ext.l D0 1279 1279 move.l D0,A_FPU 1280 add.l #_io_fpu+ $4000,A_FPU1281 * 1282 *fp = &ip->idhfnc[2];1283 * 1280 add.l #_io_fpu+0x4000,A_FPU 1281 1282 | fp = &ip->idhfnc[2]; 1283 1284 1284 move.l #24,A_FP 1285 1285 add.l IP(A6),A_FP 1286 1286 add.l #86,A_FP 1287 * 1288 *pt = &ip->idhpnt[fp->idfpt1];1289 * 1287 1288 | pt = &ip->idhpnt[fp->idfpt1]; 1289 1290 1290 clr.l D0 1291 1291 move.b 6(A_FP),D0 … … 1297 1297 add.l #242,D0 1298 1298 move.l D0,PT(A6) 1299 * 1300 .page 1301 * 1302 *srcnum = group | fp->idfsrc;1303 * 1299 1300 .page 1301 1302 | srcnum = group | fp->idfsrc; 1303 1304 1304 move.w GROUP(A6),D0 1305 1305 ext.l D0 … … 1308 1308 or D1,D0 1309 1309 move D0,SRCNUM(A6) 1310 * 1311 *vep = &valents[srcnum];1312 * 1310 1311 | vep = &valents[srcnum]; 1312 1313 1313 add.l D0,D0 1314 1314 move.l D0,D1 … … 1317 1317 add.l #_valents,D0 1318 1318 move.l D0,VEP(A6) 1319 * 1320 *smp = vpsms[vp];1321 * 1319 1320 | smp = vpsms[vp]; 1321 1322 1322 move VP(A6),A0 1323 1323 add.l A0,A0 … … 1325 1325 add.l #_vpsms,A0 1326 1326 move.l (A0),A_SMP 1327 * 1328 *if (srcnum NE smp->sm) {1329 * 1327 1328 | if (srcnum NE smp->sm) { 1329 1330 1330 clr D0 1331 1331 move 10(A_SMP),D0 1332 1332 cmp SRCNUM(A6),D0 1333 1333 beq F02L113 1334 * 1335 *(smp->prv)->nxt = smp->nxt;1336 * 1334 1335 | (smp->prv)->nxt = smp->nxt; 1336 1337 1337 move.l 4(A_SMP),A0 1338 1338 move.l (A_SMP),(A0) 1339 * 1340 *(smp->nxt)->prv = smp->prv;1341 * 1339 1340 | (smp->nxt)->prv = smp->prv; 1341 1342 1342 move.l (A_SMP),A0 1343 1343 move.l 4(A_SMP),4(A0) 1344 * 1345 * smp->prv = (struct sment *)vep;1346 * 1344 1345 | smp->prv = (struct sment |)vep; 1346 1347 1347 move.l VEP(A6),4(A_SMP) 1348 * 1349 *smp->nxt = vep->nxt;1350 * 1348 1349 | smp->nxt = vep->nxt; 1350 1351 1351 move.l VEP(A6),A0 1352 1352 move.l (A0),(A_SMP) 1353 * 1354 *(vep->nxt)->prv = smp;1355 * 1353 1354 | (vep->nxt)->prv = smp; 1355 1356 1356 move.l VEP(A6),A0 1357 1357 move.l (A0),A0 1358 1358 move.l A_SMP,4(A0) 1359 * 1360 *vep->nxt = smp;1361 * 1359 1360 | vep->nxt = smp; 1361 1362 1362 move.l VEP(A6),A0 1363 1363 move.l A_SMP,(A0) 1364 * 1365 *smp->sm = srcnum;1366 * 1364 1365 | smp->sm = srcnum; 1366 1367 1367 move SRCNUM(A6),10(A_SMP) 1368 * 1369 *}1370 * 1371 *mltval = fp->idfmlt;1372 * 1368 1369 | } 1370 1371 | mltval = fp->idfmlt; 1372 1373 1373 F02L113: move 2(A_FP),MLTVAL(A6) 1374 * 1375 .page 1376 * 1377 *switch (fp->idfsrc) {1378 * 1374 1375 .page 1376 1377 | switch (fp->idfsrc) { 1378 1379 1379 move.b 4(A_FP),D0 1380 1380 ext.w d0 1381 1381 cmp #10,D0 1382 1382 bhi F02L122 1383 * 1383 1384 1384 asl #2,D0 1385 1385 lea F02L123,A0 1386 1386 movea.l 0(A0,D0.W),A0 1387 1387 jmp (A0) 1388 * 1389 *case SM_NONE:1390 *mltval = 0;1391 * 1388 1389 | case SM_NONE: 1390 | mltval = 0; 1391 1392 1392 F02L116: clr MLTVAL(A6) 1393 * 1394 *tsrcval = 0;1395 * 1393 1394 | tsrcval = 0; 1395 1396 1396 clr TSRCVAL(A6) 1397 * 1398 *break;1399 * 1397 1398 | break; 1399 1400 1400 bra F02L114 1401 * 1402 *case SM_RAND:1403 *tsrcval = xgetran(mltval);1404 * 1401 1402 | case SM_RAND: 1403 | tsrcval = xgetran(mltval); 1404 1405 1405 F02L117: move MLTVAL(A6),(sp) 1406 1406 jsr _xgetran 1407 1407 move D0,TSRCVAL(A6) 1408 * 1409 *break;1410 * 1408 1409 | break; 1410 1411 1411 bra F02L114 1412 * 1413 *case SM_PTCH:1414 *tsrcval = pch;1415 * 1412 1413 | case SM_PTCH: 1414 | tsrcval = pch; 1415 1416 1416 F02L118: move PCH(A6),TSRCVAL(A6) 1417 * 1418 *break;1419 * 1417 1418 | break; 1419 1420 1420 bra F02L114 1421 * 1422 .page 1423 * 1424 *case SM_FREQ:1425 *tsrcval = ptoftab[(pch >> 7) & 0x00FF];1426 * 1421 1422 .page 1423 1424 | case SM_FREQ: 1425 | tsrcval = ptoftab[(pch >> 7) & 0x00FF]; 1426 1427 1427 F02L119: move PCH(A6),D0 1428 1428 asr #7,D0 … … 1432 1432 add.l #_ptoftab,A0 1433 1433 move (A0),TSRCVAL(A6) 1434 * 1435 *break;1436 * 1434 1435 | break; 1436 1437 1437 bra F02L114 1438 * 1439 *case SM_KVEL:1440 *tsrcval = veltab[trg];1441 * 1438 1439 | case SM_KVEL: 1440 | tsrcval = veltab[trg]; 1441 1442 1442 F02L120: move TRG(A6),A0 1443 1443 add.l A0,A0 1444 1444 add.l #_veltab,A0 1445 1445 move (A0),TSRCVAL(A6) 1446 * 1447 *break;1448 * 1446 1447 | break; 1448 1449 1449 bra F02L114 1450 * 1451 *case SM_KPRS:1452 *tsrcval = prstab[trg];1453 * 1450 1451 | case SM_KPRS: 1452 | tsrcval = prstab[trg]; 1453 1454 1454 F02L121: move TRG(A6),A0 1455 1455 add.l A0,A0 1456 1456 add.l #_prstab,A0 1457 1457 move (A0),TSRCVAL(A6) 1458 * 1459 *break;1460 * 1458 1459 | break; 1460 1461 1461 bra F02L114 1462 * 1463 *default:1464 *tsrcval = vep->val;1465 * 1462 1463 | default: 1464 | tsrcval = vep->val; 1465 1466 1466 F02L122: move.l VEP(A6),A0 1467 1467 move 8(A0),TSRCVAL(A6) 1468 * 1469 *}1470 * 1471 .page 1472 * 1473 *srcval = addpch(tsrcval, 0);1474 * 1468 1469 | } 1470 1471 .page 1472 1473 | srcval = addpch(tsrcval, 0); 1474 1475 1475 F02L114: move.w TSRCVAL(A6),D0 1476 1476 ext.l D0 1477 1477 asr.l #5,D0 1478 *sub.l #500,D01478 | sub.l #500,D0 1479 1479 asl.l #LSPCH,D0 1480 1480 cmp.l #PITCHMAX,D0 1481 1481 ble F02L129A 1482 * 1482 1483 1483 move.l #PITCHMAX,D0 1484 * 1484 1485 1485 F02L129A: move D0,SRCVAL(A6) 1486 * 1487 .page 1488 * 1489 *if (pt->ipvsrc) {1490 * 1486 1487 .page 1488 1489 | if (pt->ipvsrc) { 1490 1491 1491 F02L124: move.l PT(A6),A0 1492 1492 tst.b 6(A0) 1493 1493 beq F02L136 1494 * 1495 *switch (pt->ipvsrc) {1496 * 1494 1495 | switch (pt->ipvsrc) { 1496 1497 1497 move.l PT(A6),A0 1498 1498 move.b 6(A0),D0 … … 1501 1501 cmp #9,D0 1502 1502 bhi F02L144 1503 * 1503 1504 1504 asl #2,D0 1505 1505 lea F02L145,A0 1506 1506 move.l 0(A0,D0.W),A0 1507 1507 jmp (A0) 1508 * 1509 *case SM_RAND:1510 *ltmp = xgetran(pt_>ipvmlt);1511 * 1508 1509 | case SM_RAND: 1510 | ltmp = xgetran(pt_>ipvmlt); 1511 1512 1512 F02L139: move.l PT(A6),A0 1513 1513 move 4(A0),(sp) … … 1515 1515 ext.l D0 1516 1516 move.l D0,LTMP(A6) 1517 * 1518 *break;1519 * 1517 1518 | break; 1519 1520 1520 bra F02L137 1521 * 1522 *case SM_PTCH:1523 *ltmp = pch;1524 * 1521 1522 | case SM_PTCH: 1523 | ltmp = pch; 1524 1525 1525 F02L140: move PCH(A6),A0 1526 1526 move.l A0,LTMP(A6) 1527 * 1528 *break;1529 * 1527 1528 | break; 1529 1530 1530 bra F02L137 1531 * 1532 .page 1533 * 1534 *case SM_FREQ:1535 *ltmp = ptoftab[(pch >> 7) & 0x00FF];1536 * 1531 1532 .page 1533 1534 | case SM_FREQ: 1535 | ltmp = ptoftab[(pch >> 7) & 0x00FF]; 1536 1537 1537 F02L141: move PCH(A6),D0 1538 1538 asr #7,D0 … … 1544 1544 ext.l D0 1545 1545 move.l D0,LTMP(A6) 1546 * 1547 *break;1548 * 1546 1547 | break; 1548 1549 1549 bra F02L137 1550 * 1551 *case SM_KVEL:1552 *ltmp = veltab[trg];1553 * 1550 1551 | case SM_KVEL: 1552 | ltmp = veltab[trg]; 1553 1554 1554 F02L142: move TRG(A6),A0 1555 1555 add.l A0,A0 … … 1558 1558 ext.l D0 1559 1559 move.l D0,LTMP(A6) 1560 * 1561 *break;1562 * 1560 1561 | break; 1562 1563 1563 bra F02L137 1564 * 1565 .page 1566 * 1567 *case SM_KPRS:1568 *ltmp = prstab[trg];1569 * 1564 1565 .page 1566 1567 | case SM_KPRS: 1568 | ltmp = prstab[trg]; 1569 1570 1570 F02L143: move TRG(A6),A0 1571 1571 add.l A0,A0 … … 1574 1574 ext.l D0 1575 1575 move.l D0,LTMP(A6) 1576 * 1577 *break;1578 * 1576 1577 | break; 1578 1579 1579 bra F02L137 1580 * 1581 .page 1582 * 1583 *default:1584 *ltmp = valents[group | pt->ipvsrc].val;1585 * 1580 1581 .page 1582 1583 | default: 1584 | ltmp = valents[group | pt->ipvsrc].val; 1585 1586 1586 F02L144: move.l PT(A6),A0 1587 1587 clr.l D0 … … 1597 1597 move 8(A0,A1.l),D0 1598 1598 move.l D0,LTMP(A6) 1599 * 1600 *}1601 * 1602 * 1603 .page 1604 * 1605 * ltmp = (ltmp *pt->ipvmlt) >> 15;1606 * 1599 1600 | } 1601 1602 1603 .page 1604 1605 | ltmp = (ltmp | pt->ipvmlt) >> 15; 1606 1607 1607 F02L137: move.l PT(A6),A0 1608 1608 move.w 4(A0),D0 … … 1612 1612 asr.l D1,D0 1613 1613 move.l D0,LTMP(A6) 1614 * 1615 *ltmp += (long)pt->ipval;1616 * 1614 1615 | ltmp += (long)pt->ipval; 1616 1617 1617 move.l PT(A6),A0 1618 1618 move 2(A0),D0 1619 1619 ext.l D0 1620 1620 add.l D0,LTMP(A6) 1621 * 1622 *if (ltmp GT (long)VALMAX)1623 *ltmp = (long)VALMAX;1624 * 1621 1622 | if (ltmp GT (long)VALMAX) 1623 | ltmp = (long)VALMAX; 1624 1625 1625 cmp.l #VALMAX,LTMP(A6) 1626 1626 ble F02L146 1627 * 1627 1628 1628 move.l #VALMAX,LTMP(A6) 1629 1629 bra F02L147 1630 * 1631 *else if (ltmp LT (long)VALMIN)1632 *ltmp = (long)VALMIN;1633 * 1630 1631 | else if (ltmp LT (long)VALMIN) 1632 | ltmp = (long)VALMIN; 1633 1634 1634 F02L146: cmp.l #VALMIN,LTMP(A6) 1635 1635 bge F02L147 1636 * 1636 1637 1637 move.l #VALMIN,LTMP(A6) 1638 * 1639 *tfpval = (short)ltmp;1640 * 1638 1639 | tfpval = (short)ltmp; 1640 1641 1641 F02L147: move.w LTMP+2(A6),TFPVAL(A6) 1642 1642 bra F02L149 1643 * 1644 *} else {1645 * 1646 *tfpval = pt->ipval;1647 * 1643 1644 | } else { 1645 1646 | tfpval = pt->ipval; 1647 1648 1648 F02L136: move.l PT(A6),A0 1649 1649 move 2(A0),TFPVAL(A6) 1650 * 1651 *}1652 * 1653 .page 1654 * 1655 *fpmant = (((long)pt->iptom & 0x0000FFF0L)1656 * *((long)timemlt & 0x0000FFFFL)) >> 15;1657 * 1650 1651 | } 1652 1653 .page 1654 1655 | fpmant = (((long)pt->iptom & 0x0000FFF0L) 1656 | | ((long)timemlt & 0x0000FFFFL)) >> 15; 1657 1658 1658 F02L149: move.l PT(A6),A0 1659 1659 move.w (A0),D0 1660 1660 move.w D0,D2 1661 andi.w # $FFF0,D01661 andi.w #0xFFF0,D0 1662 1662 move.w _timemlt,D1 1663 1663 muls D1,D0 … … 1665 1665 asr.l D1,D0 1666 1666 move D0,R_FPMANT 1667 * 1668 *fpexp = expbit[pt->iptim & 0x000F];1669 * 1670 and # $000F,D21667 1668 | fpexp = expbit[pt->iptim & 0x000F]; 1669 1670 and #0x000F,D2 1671 1671 move D2,A0 1672 1672 add.l A0,A0 1673 1673 add.l #_expbit,A0 1674 1674 move (A0),R_FPEXP 1675 * 1676 .page 1677 * 1678 *fp->idfpch = ip->idhos3v;1679 * 1675 1676 .page 1677 1678 | fp->idfpch = ip->idhos3v; 1679 1680 1680 F02L156: move.l IP(A6),A0 1681 1681 move.w 82(A0),(A_FP) 1682 * 1683 *fpval = addpch(tfpval, fp->idfpch);1684 * 1682 1683 | fpval = addpch(tfpval, fp->idfpch); 1684 1685 1685 move.w TFPVAL(A6),D1 1686 1686 ext.l D1 … … 1693 1693 cmp.l #PITCHMAX,D0 1694 1694 ble F02L156A 1695 * 1695 1696 1696 move.l #PITCHMAX,D0 1697 * 1697 1698 1698 F02L156A: move D0,R_FPVAL 1699 * 1700 .page 1701 * 1699 1700 .page 1701 1702 1702 move.b 5(A_FP),D0 1703 1703 ext.w D0 1704 1704 sub.w #1,D0 1705 1705 movea.l PT(A6),A0 1706 * 1707 *oldi = setipl(FPU_DI);1708 * 1706 1707 | oldi = setipl(FPU_DI); 1708 1709 1709 move sr,OLDI(A6) 1710 1710 move #FPU_DI,sr 1711 * 1711 1712 1712 F02L168: clr.b 10(A0) 1713 1713 add.l #12,a0 1714 1714 dbra D0,F02L168 1715 * 1716 .page 1717 * 1718 *fp->idftmd ^= I_NVBITS;1719 * 1715 1716 .page 1717 1718 | fp->idftmd ^= I_NVBITS; 1719 1720 1720 F02L165: eor.b #24,7(A_FP) 1721 * 1722 *fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;1723 * 1721 1722 | fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003; 1723 1724 1724 move.b 7(A_FP),R_FPCTL 1725 1725 and #28,R_FPCTL 1726 1726 or #3,R_FPCTL 1727 * 1728 *fp->idfcpt = fp->idfpt1;1729 * 1727 1728 | fp->idfcpt = fp->idfpt1; 1729 1730 1730 move.b 6(A_FP),8(A_FP) 1731 * 1732 *fp->idftmd |= I_ACTIVE;1733 * 1731 1732 | fp->idftmd |= I_ACTIVE; 1733 1734 1734 or.b #2,7(A_FP) 1735 * 1736 *fp->idftrf = trg;1737 * 1735 1736 | fp->idftrf = trg; 1737 1738 1738 move TRG(A6),10(A_FP) 1739 * 1740 * *(fpu + (long)FPU_TCV1) = srcval;1741 * 1742 move SRCVAL(A6), $8(A_FPU)1743 * 1744 *++octype;1745 * 1739 1740 | |(fpu + (long)FPU_TCV1) = srcval; 1741 1742 move SRCVAL(A6),0x8(A_FPU) 1743 1744 | ++octype; 1745 1746 1746 add #1,OCTYPE(A6) 1747 * 1748 * *(fpu + (long)FPU_TSF1) = mltval;1749 * 1750 move MLTVAL(A6), $A(A_FPU)1751 * 1752 *++octype;1753 * 1747 1748 | |(fpu + (long)FPU_TSF1) = mltval; 1749 1750 move MLTVAL(A6),0xA(A_FPU) 1751 1752 | ++octype; 1753 1754 1754 add #1,OCTYPE(A6) 1755 * 1756 * *(fpu + (long)FPU_TMNT) = fpmant;1757 * 1758 move R_FPMANT, $14(A_FPU)1759 * 1760 *++octype;1761 * 1755 1756 | |(fpu + (long)FPU_TMNT) = fpmant; 1757 1758 move R_FPMANT,0x14(A_FPU) 1759 1760 | ++octype; 1761 1762 1762 add #1,OCTYPE(A6) 1763 * 1764 * *(fpu + (long)FPU_TEXP) = fpexp;1765 * 1766 move R_FPEXP, $16(A_FPU)1767 * 1768 *++octype;1769 * 1763 1764 | |(fpu + (long)FPU_TEXP) = fpexp; 1765 1766 move R_FPEXP,0x16(A_FPU) 1767 1768 | ++octype; 1769 1770 1770 add #1,OCTYPE(A6) 1771 * 1772 .page 1773 * 1774 *if (fp->idftmd & I_VNSUBN)1775 * 1771 1772 .page 1773 1774 | if (fp->idftmd & I_VNSUBN) 1775 1776 1776 btst #3,7(A_FP) 1777 1777 beq F02L169 1778 * 1779 * *(fpu + (long)FPU_TNV1) = fpval;1780 * 1781 move R_FPVAL, $1C(A_FPU)1778 1779 | |(fpu + (long)FPU_TNV1) = fpval; 1780 1781 move R_FPVAL,0x1C(A_FPU) 1782 1782 bra F02L170 1783 * 1784 *else1785 * *(fpu + (long)FPU_TNV0) = fpval;1786 * 1783 1784 | else 1785 | |(fpu + (long)FPU_TNV0) = fpval; 1786 1787 1787 F02L169: move R_FPVAL,2(A_FPU) 1788 * 1789 *++octype;1790 * 1788 1789 | ++octype; 1790 1791 1791 F02L170: add #1,OCTYPE(A6) 1792 * 1793 * *(fpu + (long)FPU_TCTL) = fpctl;1794 * 1792 1793 | |(fpu + (long)FPU_TCTL) = fpctl; 1794 1795 1795 move R_FPCTL,(A_FPU) 1796 * 1797 *setipl(oldi);1798 * 1796 1797 | setipl(oldi); 1798 1799 1799 move OLDI(A6),sr 1800 * 1801 .page 1802 *------------------------------------------------------------------------------1803 *Start function 3 -- Frq 41804 *------------------------------------------------------------------------------1805 * 1806 *if (ip->idhfnc[3].idftmd & I_TM_KEY) {1807 * 1800 1801 .page 1802 | ------------------------------------------------------------------------------ 1803 | Start function 3 -- Frq 4 1804 | ------------------------------------------------------------------------------ 1805 1806 | if (ip->idhfnc[3].idftmd & I_TM_KEY) { 1807 1808 1808 FN03: move.l IP(A6),A0 1809 1809 move.b 129(A0),D0 … … 1812 1812 btst #0,D0 1813 1813 bne FN03A 1814 * 1814 1815 1815 jmp FN04 1816 * 1817 *vp = (vce << 4) + 7;1818 * 1816 1817 | vp = (vce << 4) + 7; 1818 1819 1819 FN03A: move VCE(A6),D0 1820 1820 asl #4,D0 1821 1821 add.w #7,D0 1822 1822 move D0,VP(A6) 1823 * 1824 *fpu = io_fpu + FPU_OFNC + (vp << 4);1825 * 1823 1824 | fpu = io_fpu + FPU_OFNC + (vp << 4); 1825 1826 1826 asl #5,D0 1827 1827 ext.l D0 1828 1828 move.l D0,A_FPU 1829 add.l #_io_fpu+ $4000,A_FPU1830 * 1831 *fp = &ip->idhfnc[3];1832 * 1829 add.l #_io_fpu+0x4000,A_FPU 1830 1831 | fp = &ip->idhfnc[3]; 1832 1833 1833 move.l #36,A_FP 1834 1834 add.l IP(A6),A_FP 1835 1835 add.l #86,A_FP 1836 * 1837 *pt = &ip->idhpnt[fp->idfpt1];1838 * 1836 1837 | pt = &ip->idhpnt[fp->idfpt1]; 1838 1839 1839 clr.l D0 1840 1840 move.b 6(A_FP),D0 … … 1846 1846 add.l #242,D0 1847 1847 move.l D0,PT(A6) 1848 * 1849 .page 1850 * 1851 *srcnum = group | fp->idfsrc;1852 * 1848 1849 .page 1850 1851 | srcnum = group | fp->idfsrc; 1852 1853 1853 move.w GROUP(A6),D0 1854 1854 ext.l D0 … … 1857 1857 or D1,D0 1858 1858 move D0,SRCNUM(A6) 1859 * 1860 *vep = &valents[srcnum];1861 * 1859 1860 | vep = &valents[srcnum]; 1861 1862 1862 add.l D0,D0 1863 1863 move.l D0,D1 … … 1866 1866 add.l #_valents,D0 1867 1867 move.l D0,VEP(A6) 1868 * 1869 *smp = vpsms[vp];1870 * 1868 1869 | smp = vpsms[vp]; 1870 1871 1871 move VP(A6),A0 1872 1872 add.l A0,A0 … … 1874 1874 add.l #_vpsms,A0 1875 1875 move.l (A0),A_SMP 1876 * 1877 *if (srcnum NE smp->sm) {1878 * 1876 1877 | if (srcnum NE smp->sm) { 1878 1879 1879 clr D0 1880 1880 move 10(A_SMP),D0 1881 1881 cmp SRCNUM(A6),D0 1882 1882 beq F03L113 1883 * 1884 *(smp->prv)->nxt = smp->nxt;1885 * 1883 1884 | (smp->prv)->nxt = smp->nxt; 1885 1886 1886 move.l 4(A_SMP),A0 1887 1887 move.l (A_SMP),(A0) 1888 * 1889 *(smp->nxt)->prv = smp->prv;1890 * 1888 1889 | (smp->nxt)->prv = smp->prv; 1890 1891 1891 move.l (A_SMP),A0 1892 1892 move.l 4(A_SMP),4(A0) 1893 * 1894 * smp->prv = (struct sment *)vep;1895 * 1893 1894 | smp->prv = (struct sment |)vep; 1895 1896 1896 move.l VEP(A6),4(A_SMP) 1897 * 1898 *smp->nxt = vep->nxt;1899 * 1897 1898 | smp->nxt = vep->nxt; 1899 1900 1900 move.l VEP(A6),A0 1901 1901 move.l (A0),(A_SMP) 1902 * 1903 *(vep->nxt)->prv = smp;1904 * 1902 1903 | (vep->nxt)->prv = smp; 1904 1905 1905 move.l VEP(A6),A0 1906 1906 move.l (A0),A0 1907 1907 move.l A_SMP,4(A0) 1908 * 1909 *vep->nxt = smp;1910 * 1908 1909 | vep->nxt = smp; 1910 1911 1911 move.l VEP(A6),A0 1912 1912 move.l A_SMP,(A0) 1913 * 1914 *smp->sm = srcnum;1915 * 1913 1914 | smp->sm = srcnum; 1915 1916 1916 move SRCNUM(A6),10(A_SMP) 1917 * 1918 *}1919 * 1920 *mltval = fp->idfmlt;1921 * 1917 1918 | } 1919 1920 | mltval = fp->idfmlt; 1921 1922 1922 F03L113: move 2(A_FP),MLTVAL(A6) 1923 * 1924 .page 1925 * 1926 *switch (fp->idfsrc) {1927 * 1923 1924 .page 1925 1926 | switch (fp->idfsrc) { 1927 1928 1928 move.b 4(A_FP),D0 1929 1929 ext.w d0 1930 1930 cmp #10,D0 1931 1931 bhi F03L122 1932 * 1932 1933 1933 asl #2,D0 1934 1934 lea F03L123,A0 1935 1935 movea.l 0(A0,D0.W),A0 1936 1936 jmp (A0) 1937 * 1938 *case SM_NONE:1939 *mltval = 0;1940 * 1937 1938 | case SM_NONE: 1939 | mltval = 0; 1940 1941 1941 F03L116: clr MLTVAL(A6) 1942 * 1943 *tsrcval = 0;1944 * 1942 1943 | tsrcval = 0; 1944 1945 1945 clr TSRCVAL(A6) 1946 * 1947 *break;1948 * 1946 1947 | break; 1948 1949 1949 bra F03L114 1950 * 1951 *case SM_RAND:1952 *tsrcval = xgetran(mltval);1953 * 1950 1951 | case SM_RAND: 1952 | tsrcval = xgetran(mltval); 1953 1954 1954 F03L117: move MLTVAL(A6),(sp) 1955 1955 jsr _xgetran 1956 1956 move D0,TSRCVAL(A6) 1957 * 1958 *break;1959 * 1957 1958 | break; 1959 1960 1960 bra F03L114 1961 * 1962 *case SM_PTCH:1963 *tsrcval = pch;1964 * 1961 1962 | case SM_PTCH: 1963 | tsrcval = pch; 1964 1965 1965 F03L118: move PCH(A6),TSRCVAL(A6) 1966 * 1967 *break;1968 * 1966 1967 | break; 1968 1969 1969 bra F03L114 1970 * 1971 .page 1972 * 1973 *case SM_FREQ:1974 *tsrcval = ptoftab[(pch >> 7) & 0x00FF];1975 * 1970 1971 .page 1972 1973 | case SM_FREQ: 1974 | tsrcval = ptoftab[(pch >> 7) & 0x00FF]; 1975 1976 1976 F03L119: move PCH(A6),D0 1977 1977 asr #7,D0 … … 1981 1981 add.l #_ptoftab,A0 1982 1982 move (A0),TSRCVAL(A6) 1983 * 1984 *break;1985 * 1983 1984 | break; 1985 1986 1986 bra F03L114 1987 * 1988 *case SM_KVEL:1989 *tsrcval = veltab[trg];1990 * 1987 1988 | case SM_KVEL: 1989 | tsrcval = veltab[trg]; 1990 1991 1991 F03L120: move TRG(A6),A0 1992 1992 add.l A0,A0 1993 1993 add.l #_veltab,A0 1994 1994 move (A0),TSRCVAL(A6) 1995 * 1996 *break;1997 * 1995 1996 | break; 1997 1998 1998 bra F03L114 1999 * 2000 *case SM_KPRS:2001 *tsrcval = prstab[trg];2002 * 1999 2000 | case SM_KPRS: 2001 | tsrcval = prstab[trg]; 2002 2003 2003 F03L121: move TRG(A6),A0 2004 2004 add.l A0,A0 2005 2005 add.l #_prstab,A0 2006 2006 move (A0),TSRCVAL(A6) 2007 * 2008 *break;2009 * 2007 2008 | break; 2009 2010 2010 bra F03L114 2011 * 2012 *default:2013 *tsrcval = vep->val;2014 * 2011 2012 | default: 2013 | tsrcval = vep->val; 2014 2015 2015 F03L122: move.l VEP(A6),A0 2016 2016 move 8(A0),TSRCVAL(A6) 2017 * 2018 *}2019 * 2020 .page 2021 * 2022 *srcval = addpch(tsrcval, 0);2023 * 2017 2018 | } 2019 2020 .page 2021 2022 | srcval = addpch(tsrcval, 0); 2023 2024 2024 F03L114: move.w TSRCVAL(A6),D0 2025 2025 ext.l D0 2026 2026 asr.l #5,D0 2027 *sub.l #500,D02027 | sub.l #500,D0 2028 2028 asl.l #LSPCH,D0 2029 2029 cmp.l #PITCHMAX,D0 2030 2030 ble F03L129A 2031 * 2031 2032 2032 move.l #PITCHMAX,D0 2033 2033 2034 2034 F03L129A: move D0,SRCVAL(A6) 2035 * 2036 .page 2037 * 2038 *if (pt->ipvsrc) {2039 * 2035 2036 .page 2037 2038 | if (pt->ipvsrc) { 2039 2040 2040 F03L124: move.l PT(A6),A0 2041 2041 tst.b 6(A0) 2042 2042 beq F03L136 2043 * 2044 *switch (pt->ipvsrc) {2045 * 2043 2044 | switch (pt->ipvsrc) { 2045 2046 2046 move.l PT(A6),A0 2047 2047 move.b 6(A0),D0 … … 2050 2050 cmp #9,D0 2051 2051 bhi F03L144 2052 * 2052 2053 2053 asl #2,D0 2054 2054 lea F03L145,A0 2055 2055 move.l 0(A0,D0.W),A0 2056 2056 jmp (A0) 2057 * 2058 *case SM_RAND:2059 *ltmp = xgetran(pt_>ipvmlt);2060 * 2057 2058 | case SM_RAND: 2059 | ltmp = xgetran(pt_>ipvmlt); 2060 2061 2061 F03L139: move.l PT(A6),A0 2062 2062 move 4(A0),(sp) … … 2064 2064 ext.l D0 2065 2065 move.l D0,LTMP(A6) 2066 * 2067 *break;2068 * 2066 2067 | break; 2068 2069 2069 bra F03L137 2070 * 2071 *case SM_PTCH:2072 *ltmp = pch;2073 * 2070 2071 | case SM_PTCH: 2072 | ltmp = pch; 2073 2074 2074 F03L140: move PCH(A6),A0 2075 2075 move.l A0,LTMP(A6) 2076 * 2077 *break;2078 * 2076 2077 | break; 2078 2079 2079 bra F03L137 2080 * 2081 .page 2082 * 2083 *case SM_FREQ:2084 *ltmp = ptoftab[(pch >> 7) & 0x00FF];2085 * 2080 2081 .page 2082 2083 | case SM_FREQ: 2084 | ltmp = ptoftab[(pch >> 7) & 0x00FF]; 2085 2086 2086 F03L141: move PCH(A6),D0 2087 2087 asr #7,D0 … … 2093 2093 ext.l D0 2094 2094 move.l D0,LTMP(A6) 2095 * 2096 *break;2097 * 2095 2096 | break; 2097 2098 2098 bra F03L137 2099 * 2100 *case SM_KVEL:2101 *ltmp = veltab[trg];2102 * 2099 2100 | case SM_KVEL: 2101 | ltmp = veltab[trg]; 2102 2103 2103 F03L142: move TRG(A6),A0 2104 2104 add.l A0,A0 … … 2107 2107 ext.l D0 2108 2108 move.l D0,LTMP(A6) 2109 * 2110 *break;2111 * 2109 2110 | break; 2111 2112 2112 bra F03L137 2113 * 2114 .page 2115 * 2116 *case SM_KPRS:2117 *ltmp = prstab[trg];2118 * 2113 2114 .page 2115 2116 | case SM_KPRS: 2117 | ltmp = prstab[trg]; 2118 2119 2119 F03L143: move TRG(A6),A0 2120 2120 add.l A0,A0 … … 2123 2123 ext.l D0 2124 2124 move.l D0,LTMP(A6) 2125 * 2126 *break;2127 * 2125 2126 | break; 2127 2128 2128 bra F03L137 2129 * 2130 .page 2131 * 2132 *default:2133 *ltmp = valents[group | pt->ipvsrc].val;2134 * 2129 2130 .page 2131 2132 | default: 2133 | ltmp = valents[group | pt->ipvsrc].val; 2134 2135 2135 F03L144: move.l PT(A6),A0 2136 2136 clr.l D0 … … 2146 2146 move 8(A0,A1.l),D0 2147 2147 move.l D0,LTMP(A6) 2148 * 2149 *}2150 * 2151 * 2152 .page 2153 * 2154 * ltmp = (ltmp *pt->ipvmlt) >> 15;2155 * 2148 2149 | } 2150 2151 2152 .page 2153 2154 | ltmp = (ltmp | pt->ipvmlt) >> 15; 2155 2156 2156 F03L137: move.l PT(A6),A0 2157 2157 move.w 4(A0),D0 … … 2161 2161 asr.l D1,D0 2162 2162 move.l D0,LTMP(A6) 2163 * 2164 *ltmp += (long)pt->ipval;2165 * 2163 2164 | ltmp += (long)pt->ipval; 2165 2166 2166 move.l PT(A6),A0 2167 2167 move 2(A0),D0 2168 2168 ext.l D0 2169 2169 add.l D0,LTMP(A6) 2170 * 2171 *if (ltmp GT (long)VALMAX)2172 *ltmp = (long)VALMAX;2173 * 2170 2171 | if (ltmp GT (long)VALMAX) 2172 | ltmp = (long)VALMAX; 2173 2174 2174 cmp.l #VALMAX,LTMP(A6) 2175 2175 ble F03L146 2176 * 2176 2177 2177 move.l #VALMAX,LTMP(A6) 2178 2178 bra F03L147 2179 * 2180 *else if (ltmp LT (long)VALMIN)2181 *ltmp = (long)VALMIN;2182 * 2179 2180 | else if (ltmp LT (long)VALMIN) 2181 | ltmp = (long)VALMIN; 2182 2183 2183 F03L146: cmp.l #VALMIN,LTMP(A6) 2184 2184 bge F03L147 2185 * 2185 2186 2186 move.l #VALMIN,LTMP(A6) 2187 * 2188 *tfpval = (short)ltmp;2189 * 2187 2188 | tfpval = (short)ltmp; 2189 2190 2190 F03L147: move.w LTMP+2(A6),TFPVAL(A6) 2191 2191 bra F03L149 2192 * 2193 *} else {2194 * 2195 *tfpval = pt->ipval;2196 * 2192 2193 | } else { 2194 2195 | tfpval = pt->ipval; 2196 2197 2197 F03L136: move.l PT(A6),A0 2198 2198 move 2(A0),TFPVAL(A6) 2199 * 2200 *}2201 * 2202 .page 2203 * 2204 *fpmant = (((long)pt->iptom & 0x0000FFF0L)2205 * *((long)timemlt & 0x0000FFFFL)) >> 15;2206 * 2199 2200 | } 2201 2202 .page 2203 2204 | fpmant = (((long)pt->iptom & 0x0000FFF0L) 2205 | | ((long)timemlt & 0x0000FFFFL)) >> 15; 2206 2207 2207 F03L149: move.l PT(A6),A0 2208 2208 move.w (A0),D0 2209 2209 move.w D0,D2 2210 andi.w # $FFF0,D02210 andi.w #0xFFF0,D0 2211 2211 move.w _timemlt,D1 2212 2212 muls D1,D0 … … 2214 2214 asr.l D1,D0 2215 2215 move D0,R_FPMANT 2216 * 2217 *fpexp = expbit[pt->iptim & 0x000F];2218 * 2219 and # $000F,D22216 2217 | fpexp = expbit[pt->iptim & 0x000F]; 2218 2219 and #0x000F,D2 2220 2220 move D2,A0 2221 2221 add.l A0,A0 2222 2222 add.l #_expbit,A0 2223 2223 move (A0),R_FPEXP 2224 * 2225 .page 2226 * 2227 *fp->idfpch = ip->idhos4v;2228 * 2224 2225 .page 2226 2227 | fp->idfpch = ip->idhos4v; 2228 2229 2229 F03L157: move.l IP(A6),A0 2230 2230 move.w 84(A0),(A_FP) 2231 * 2232 *fpval = addpch(tfpval, fp->idfpch);2233 * 2231 2232 | fpval = addpch(tfpval, fp->idfpch); 2233 2234 2234 move.w TFPVAL(A6),D1 2235 2235 ext.l D1 … … 2242 2242 cmp.l #PITCHMAX,D0 2243 2243 ble F03L157A 2244 * 2244 2245 2245 move.l #PITCHMAX,D0 2246 * 2246 2247 2247 F03L157A: move D0,R_FPVAL 2248 * 2249 .page 2250 * 2248 2249 .page 2250 2251 2251 move.b 5(A_FP),D0 2252 2252 ext.w D0 2253 2253 sub.w #1,D0 2254 2254 movea.l PT(A6),A0 2255 * 2256 *oldi = setipl(FPU_DI);2257 * 2255 2256 | oldi = setipl(FPU_DI); 2257 2258 2258 move sr,OLDI(A6) 2259 2259 move #FPU_DI,sr 2260 * 2260 2261 2261 F03L168: clr.b 10(A0) 2262 2262 add.l #12,a0 2263 2263 dbra D0,F03L168 2264 * 2265 .page 2266 * 2267 *fp->idftmd ^= I_NVBITS;2268 * 2264 2265 .page 2266 2267 | fp->idftmd ^= I_NVBITS; 2268 2269 2269 F03L165: eor.b #24,7(A_FP) 2270 * 2271 *fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;2272 * 2270 2271 | fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003; 2272 2273 2273 move.b 7(A_FP),R_FPCTL 2274 2274 and #28,R_FPCTL 2275 2275 or #3,R_FPCTL 2276 * 2277 *fp->idfcpt = fp->idfpt1;2278 * 2276 2277 | fp->idfcpt = fp->idfpt1; 2278 2279 2279 move.b 6(A_FP),8(A_FP) 2280 * 2281 *fp->idftmd |= I_ACTIVE;2282 * 2280 2281 | fp->idftmd |= I_ACTIVE; 2282 2283 2283 or.b #2,7(A_FP) 2284 * 2285 *fp->idftrf = trg;2286 * 2284 2285 | fp->idftrf = trg; 2286 2287 2287 move TRG(A6),10(A_FP) 2288 * 2289 * *(fpu + (long)FPU_TCV1) = srcval;2290 * 2291 move SRCVAL(A6), $8(A_FPU)2292 * 2293 *++octype;2294 * 2288 2289 | |(fpu + (long)FPU_TCV1) = srcval; 2290 2291 move SRCVAL(A6),0x8(A_FPU) 2292 2293 | ++octype; 2294 2295 2295 add #1,OCTYPE(A6) 2296 * 2297 * *(fpu + (long)FPU_TSF1) = mltval;2298 * 2299 move MLTVAL(A6), $A(A_FPU)2300 * 2301 *++octype;2302 * 2296 2297 | |(fpu + (long)FPU_TSF1) = mltval; 2298 2299 move MLTVAL(A6),0xA(A_FPU) 2300 2301 | ++octype; 2302 2303 2303 add #1,OCTYPE(A6) 2304 * 2305 * *(fpu + (long)FPU_TMNT) = fpmant;2306 * 2307 move R_FPMANT, $14(A_FPU)2308 * 2309 *++octype;2310 * 2304 2305 | |(fpu + (long)FPU_TMNT) = fpmant; 2306 2307 move R_FPMANT,0x14(A_FPU) 2308 2309 | ++octype; 2310 2311 2311 add #1,OCTYPE(A6) 2312 * 2313 * *(fpu + (long)FPU_TEXP) = fpexp;2314 * 2315 move R_FPEXP, $16(A_FPU)2316 * 2317 *++octype;2318 * 2312 2313 | |(fpu + (long)FPU_TEXP) = fpexp; 2314 2315 move R_FPEXP,0x16(A_FPU) 2316 2317 | ++octype; 2318 2319 2319 add #1,OCTYPE(A6) 2320 * 2321 .page 2322 * 2323 *if (fp->idftmd & I_VNSUBN)2324 * 2320 2321 .page 2322 2323 | if (fp->idftmd & I_VNSUBN) 2324 2325 2325 btst #3,7(A_FP) 2326 2326 beq F03L169 2327 * 2328 * *(fpu + (long)FPU_TNV1) = fpval;2329 * 2330 move R_FPVAL, $1C(A_FPU)2327 2328 | |(fpu + (long)FPU_TNV1) = fpval; 2329 2330 move R_FPVAL,0x1C(A_FPU) 2331 2331 bra F03L170 2332 * 2333 *else2334 * *(fpu + (long)FPU_TNV0) = fpval;2335 * 2332 2333 | else 2334 | |(fpu + (long)FPU_TNV0) = fpval; 2335 2336 2336 F03L169: move R_FPVAL,2(A_FPU) 2337 * 2338 *++octype;2339 * 2337 2338 | ++octype; 2339 2340 2340 F03L170: add #1,OCTYPE(A6) 2341 * 2342 * *(fpu + (long)FPU_TCTL) = fpctl;2343 * 2341 2342 | |(fpu + (long)FPU_TCTL) = fpctl; 2343 2344 2344 move R_FPCTL,(A_FPU) 2345 * 2346 *setipl(oldi);2347 * 2345 2346 | setipl(oldi); 2347 2348 2348 move OLDI(A6),sr 2349 * 2350 .page 2351 *------------------------------------------------------------------------------2352 *Start function 4 -- Filtr2353 *------------------------------------------------------------------------------2354 * 2355 *if (ip->idhfnc[4].idftmd & I_TM_KEY) {2356 * 2349 2350 .page 2351 | ------------------------------------------------------------------------------ 2352 | Start function 4 -- Filtr 2353 | ------------------------------------------------------------------------------ 2354 2355 | if (ip->idhfnc[4].idftmd & I_TM_KEY) { 2356 2357 2357 FN04: move.l IP(A6),A0 2358 2358 move.b 141(A0),D0 … … 2361 2361 btst #0,D0 2362 2362 bne FN04A 2363 * 2363 2364 2364 jmp FN05 2365 * 2366 *vp = (vce << 4) + 10;2367 * 2365 2366 | vp = (vce << 4) + 10; 2367 2368 2368 FN04A: move VCE(A6),D0 2369 2369 asl #4,D0 2370 2370 add.w #10,D0 2371 2371 move D0,VP(A6) 2372 * 2373 *fpu = io_fpu + FPU_OFNC + (vp << 4);2374 * 2372 2373 | fpu = io_fpu + FPU_OFNC + (vp << 4); 2374 2375 2375 asl #5,D0 2376 2376 ext.l D0 2377 2377 move.l D0,A_FPU 2378 add.l #_io_fpu+ $4000,A_FPU2379 * 2380 *fp = &ip->idhfnc[4];2381 * 2378 add.l #_io_fpu+0x4000,A_FPU 2379 2380 | fp = &ip->idhfnc[4]; 2381 2382 2382 move.l #48,A_FP 2383 2383 add.l IP(A6),A_FP 2384 2384 add.l #86,A_FP 2385 * 2386 .page 2387 * 2388 *Added code:2389 * 2390 *output resonance via table lookup with FPU interrupts off2391 * 2385 2386 .page 2387 2388 | Added code: 2389 2390 | output resonance via table lookup with FPU interrupts off 2391 2392 2392 lea _rsntab,A0 2393 2393 clr.w D0 … … 2401 2401 ext.l D0 2402 2402 move.l D0,A0 2403 add.l #_io_fpu+ $4000,A02403 add.l #_io_fpu+0x4000,A0 2404 2404 move.w sr,OLDI(A6) 2405 2405 move.w #FPU_DI,sr 2406 2406 move.w d1,2(A0) 2407 2407 add.w #1,OCTYPE(A6) 2408 move.w d1, $1C(A0)2408 move.w d1,0x1C(A0) 2409 2409 add.w #1,OCTYPE(A6) 2410 move.w # $0015,(A0)2410 move.w #0x0015,(A0) 2411 2411 move.w OLDI(A6),sr 2412 * 2413 *pt = &ip->idhpnt[fp->idfpt1];2414 * 2412 2413 | pt = &ip->idhpnt[fp->idfpt1]; 2414 2415 2415 clr.l D0 2416 2416 move.b 6(A_FP),D0 … … 2422 2422 add.l #242,D0 2423 2423 move.l D0,PT(A6) 2424 * 2425 .page 2426 * 2427 *srcnum = group | fp->idfsrc;2428 * 2424 2425 .page 2426 2427 | srcnum = group | fp->idfsrc; 2428 2429 2429 move.w GROUP(A6),D0 2430 2430 ext.l D0 … … 2433 2433 or D1,D0 2434 2434 move D0,SRCNUM(A6) 2435 * 2436 *vep = &valents[srcnum];2437 * 2435 2436 | vep = &valents[srcnum]; 2437 2438 2438 add.l D0,D0 2439 2439 move.l D0,D1 … … 2442 2442 add.l #_valents,D0 2443 2443 move.l D0,VEP(A6) 2444 * 2445 *smp = vpsms[vp];2446 * 2444 2445 | smp = vpsms[vp]; 2446 2447 2447 move VP(A6),A0 2448 2448 add.l A0,A0 … … 2450 2450 add.l #_vpsms,A0 2451 2451 move.l (A0),A_SMP 2452 * 2453 *if (srcnum NE smp->sm) {2454 * 2452 2453 | if (srcnum NE smp->sm) { 2454 2455 2455 clr D0 2456 2456 move 10(A_SMP),D0 2457 2457 cmp SRCNUM(A6),D0 2458 2458 beq F04L113 2459 * 2460 *(smp->prv)->nxt = smp->nxt;2461 * 2459 2460 | (smp->prv)->nxt = smp->nxt; 2461 2462 2462 move.l 4(A_SMP),A0 2463 2463 move.l (A_SMP),(A0) 2464 * 2465 *(smp->nxt)->prv = smp->prv;2466 * 2464 2465 | (smp->nxt)->prv = smp->prv; 2466 2467 2467 move.l (A_SMP),A0 2468 2468 move.l 4(A_SMP),4(A0) 2469 * 2470 * smp->prv = (struct sment *)vep;2471 * 2469 2470 | smp->prv = (struct sment |)vep; 2471 2472 2472 move.l VEP(A6),4(A_SMP) 2473 * 2474 *smp->nxt = vep->nxt;2475 * 2473 2474 | smp->nxt = vep->nxt; 2475 2476 2476 move.l VEP(A6),A0 2477 2477 move.l (A0),(A_SMP) 2478 * 2479 *(vep->nxt)->prv = smp;2480 * 2478 2479 | (vep->nxt)->prv = smp; 2480 2481 2481 move.l VEP(A6),A0 2482 2482 move.l (A0),A0 2483 2483 move.l A_SMP,4(A0) 2484 * 2485 *vep->nxt = smp;2486 * 2484 2485 | vep->nxt = smp; 2486 2487 2487 move.l VEP(A6),A0 2488 2488 move.l A_SMP,(A0) 2489 * 2490 *smp->sm = srcnum;2491 * 2489 2490 | smp->sm = srcnum; 2491 2492 2492 move SRCNUM(A6),10(A_SMP) 2493 * 2494 *}2495 * 2496 *mltval = fp->idfmlt;2497 * 2493 2494 | } 2495 2496 | mltval = fp->idfmlt; 2497 2498 2498 F04L113: move 2(A_FP),MLTVAL(A6) 2499 * 2500 .page 2501 * 2502 *switch (fp->idfsrc) {2503 * 2499 2500 .page 2501 2502 | switch (fp->idfsrc) { 2503 2504 2504 move.b 4(A_FP),D0 2505 2505 ext.w d0 2506 2506 cmp #10,D0 2507 2507 bhi F04L122 2508 * 2508 2509 2509 asl #2,D0 2510 2510 lea F04L123,A0 2511 2511 movea.l 0(A0,D0.W),A0 2512 2512 jmp (A0) 2513 * 2514 *case SM_NONE:2515 *mltval = 0;2516 * 2513 2514 | case SM_NONE: 2515 | mltval = 0; 2516 2517 2517 F04L116: clr MLTVAL(A6) 2518 * 2519 *tsrcval = 0;2520 * 2518 2519 | tsrcval = 0; 2520 2521 2521 clr TSRCVAL(A6) 2522 * 2523 *break;2524 * 2522 2523 | break; 2524 2525 2525 bra F04L114 2526 * 2527 *case SM_RAND:2528 *tsrcval = xgetran(mltval);2529 * 2526 2527 | case SM_RAND: 2528 | tsrcval = xgetran(mltval); 2529 2530 2530 F04L117: move MLTVAL(A6),(sp) 2531 2531 jsr _xgetran 2532 2532 move D0,TSRCVAL(A6) 2533 * 2534 *break;2535 * 2533 2534 | break; 2535 2536 2536 bra F04L114 2537 * 2538 *case SM_PTCH:2539 *tsrcval = pch;2540 * 2537 2538 | case SM_PTCH: 2539 | tsrcval = pch; 2540 2541 2541 F04L118: move PCH(A6),TSRCVAL(A6) 2542 * 2543 *break;2544 * 2542 2543 | break; 2544 2545 2545 bra F04L114 2546 * 2547 .page 2548 * 2549 *case SM_FREQ:2550 *tsrcval = ptoftab[(pch >> 7) & 0x00FF];2551 * 2546 2547 .page 2548 2549 | case SM_FREQ: 2550 | tsrcval = ptoftab[(pch >> 7) & 0x00FF]; 2551 2552 2552 F04L119: move PCH(A6),D0 2553 2553 asr #7,D0 … … 2557 2557 add.l #_ptoftab,A0 2558 2558 move (A0),TSRCVAL(A6) 2559 * 2560 *break;2561 * 2559 2560 | break; 2561 2562 2562 bra F04L114 2563 * 2564 *case SM_KVEL:2565 *tsrcval = veltab[trg];2566 * 2563 2564 | case SM_KVEL: 2565 | tsrcval = veltab[trg]; 2566 2567 2567 F04L120: move TRG(A6),A0 2568 2568 add.l A0,A0 2569 2569 add.l #_veltab,A0 2570 2570 move (A0),TSRCVAL(A6) 2571 * 2572 *break;2573 * 2571 2572 | break; 2573 2574 2574 bra F04L114 2575 * 2576 *case SM_KPRS:2577 *tsrcval = prstab[trg];2578 * 2575 2576 | case SM_KPRS: 2577 | tsrcval = prstab[trg]; 2578 2579 2579 F04L121: move TRG(A6),A0 2580 2580 add.l A0,A0 2581 2581 add.l #_prstab,A0 2582 2582 move (A0),TSRCVAL(A6) 2583 * 2584 *break;2585 * 2583 2584 | break; 2585 2586 2586 bra F04L114 2587 * 2588 *default:2589 *tsrcval = vep->val;2590 * 2587 2588 | default: 2589 | tsrcval = vep->val; 2590 2591 2591 F04L122: move.l VEP(A6),A0 2592 2592 move 8(A0),TSRCVAL(A6) 2593 * 2594 *}2595 * 2596 .page 2597 * 2598 *ltmp = ((long)tsrcval >> 1) + ((long)tsrcval >> 2);2599 * 2593 2594 | } 2595 2596 .page 2597 2598 | ltmp = ((long)tsrcval >> 1) + ((long)tsrcval >> 2); 2599 2600 2600 F04L114: move TSRCVAL(A6),D0 2601 2601 ext.l D0 … … 2606 2606 add.l D1,D0 2607 2607 move.l D0,LTMP(A6) 2608 * 2609 *if (ltmp GT (long)VALMAX)2610 *ltmp = (long)VALMAX;2611 * 2608 2609 | if (ltmp GT (long)VALMAX) 2610 | ltmp = (long)VALMAX; 2611 2612 2612 cmp.l #VALMAX,LTMP(A6) 2613 2613 ble F04L131 2614 * 2614 2615 2615 move.l #VALMAX,LTMP(A6) 2616 2616 bra F04L132 2617 * 2618 *else if (ltmp LT (long)VALMIN)2619 *ltmp = (long)VALMIN;2620 * 2617 2618 | else if (ltmp LT (long)VALMIN) 2619 | ltmp = (long)VALMIN; 2620 2621 2621 F04L131: cmp.l #VALMIN,LTMP(A6) 2622 2622 bge F04L132 2623 * 2623 2624 2624 move.l #VALMIN,LTMP(A6) 2625 * 2626 *srcval = (short)ltmp;2627 * 2625 2626 | srcval = (short)ltmp; 2627 2628 2628 F04L132: move.l LTMP(A6),D0 2629 2629 move D0,SRCVAL(A6) 2630 * 2631 .page 2632 * 2633 *if (pt->ipvsrc) {2634 * 2630 2631 .page 2632 2633 | if (pt->ipvsrc) { 2634 2635 2635 F04L124: move.l PT(A6),A0 2636 2636 tst.b 6(A0) 2637 2637 beq F04L136 2638 * 2639 *switch (pt->ipvsrc) {2640 * 2638 2639 | switch (pt->ipvsrc) { 2640 2641 2641 move.l PT(A6),A0 2642 2642 move.b 6(A0),D0 … … 2645 2645 cmp #9,D0 2646 2646 bhi F04L144 2647 * 2647 2648 2648 asl #2,D0 2649 2649 lea F04L145,A0 2650 2650 move.l 0(A0,D0.W),A0 2651 2651 jmp (A0) 2652 * 2653 *case SM_RAND:2654 *ltmp = xgetran(pt_>ipvmlt);2655 * 2652 2653 | case SM_RAND: 2654 | ltmp = xgetran(pt_>ipvmlt); 2655 2656 2656 F04L139: move.l PT(A6),A0 2657 2657 move 4(A0),(sp) … … 2659 2659 ext.l D0 2660 2660 move.l D0,LTMP(A6) 2661 * 2662 *break;2663 * 2661 2662 | break; 2663 2664 2664 bra F04L137 2665 * 2666 *case SM_PTCH:2667 *ltmp = pch;2668 * 2665 2666 | case SM_PTCH: 2667 | ltmp = pch; 2668 2669 2669 F04L140: move PCH(A6),A0 2670 2670 move.l A0,LTMP(A6) 2671 * 2672 *break;2673 * 2671 2672 | break; 2673 2674 2674 bra F04L137 2675 * 2676 .page 2677 * 2678 *case SM_FREQ:2679 *ltmp = ptoftab[(pch >> 7) & 0x00FF];2680 * 2675 2676 .page 2677 2678 | case SM_FREQ: 2679 | ltmp = ptoftab[(pch >> 7) & 0x00FF]; 2680 2681 2681 F04L141: move PCH(A6),D0 2682 2682 asr #7,D0 … … 2688 2688 ext.l D0 2689 2689 move.l D0,LTMP(A6) 2690 * 2691 *break;2692 * 2690 2691 | break; 2692 2693 2693 bra F04L137 2694 * 2695 *case SM_KVEL:2696 *ltmp = veltab[trg];2697 * 2694 2695 | case SM_KVEL: 2696 | ltmp = veltab[trg]; 2697 2698 2698 F04L142: move TRG(A6),A0 2699 2699 add.l A0,A0 … … 2702 2702 ext.l D0 2703 2703 move.l D0,LTMP(A6) 2704 * 2705 *break;2706 * 2704 2705 | break; 2706 2707 2707 bra F04L137 2708 * 2709 .page 2710 * 2711 *case SM_KPRS:2712 *ltmp = prstab[trg];2713 * 2708 2709 .page 2710 2711 | case SM_KPRS: 2712 | ltmp = prstab[trg]; 2713 2714 2714 F04L143: move TRG(A6),A0 2715 2715 add.l A0,A0 … … 2718 2718 ext.l D0 2719 2719 move.l D0,LTMP(A6) 2720 * 2721 *break;2722 * 2720 2721 | break; 2722 2723 2723 bra F04L137 2724 * 2725 .page 2726 * 2727 *default:2728 *ltmp = valents[group | pt->ipvsrc].val;2729 * 2724 2725 .page 2726 2727 | default: 2728 | ltmp = valents[group | pt->ipvsrc].val; 2729 2730 2730 F04L144: move.l PT(A6),A0 2731 2731 clr.l D0 … … 2741 2741 move 8(A0,A1.l),D0 2742 2742 move.l D0,LTMP(A6) 2743 * 2744 *}2745 * 2746 * 2747 .page 2748 * 2749 * ltmp = (ltmp *pt->ipvmlt) >> 15;2750 * 2743 2744 | } 2745 2746 2747 .page 2748 2749 | ltmp = (ltmp | pt->ipvmlt) >> 15; 2750 2751 2751 F04L137: move.l PT(A6),A0 2752 2752 move.w 4(A0),D0 … … 2756 2756 asr.l D1,D0 2757 2757 move.l D0,LTMP(A6) 2758 * 2759 *ltmp += (long)pt->ipval;2760 * 2758 2759 | ltmp += (long)pt->ipval; 2760 2761 2761 move.l PT(A6),A0 2762 2762 move 2(A0),D0 2763 2763 ext.l D0 2764 2764 add.l D0,LTMP(A6) 2765 * 2766 *if (ltmp GT (long)VALMAX)2767 *ltmp = (long)VALMAX;2768 * 2765 2766 | if (ltmp GT (long)VALMAX) 2767 | ltmp = (long)VALMAX; 2768 2769 2769 cmp.l #VALMAX,LTMP(A6) 2770 2770 ble F04L146 2771 * 2771 2772 2772 move.l #VALMAX,LTMP(A6) 2773 2773 bra F04L147 2774 * 2775 *else if (ltmp LT (long)VALMIN)2776 *ltmp = (long)VALMIN;2777 * 2774 2775 | else if (ltmp LT (long)VALMIN) 2776 | ltmp = (long)VALMIN; 2777 2778 2778 F04L146: cmp.l #VALMIN,LTMP(A6) 2779 2779 bge F04L147 2780 * 2780 2781 2781 move.l #VALMIN,LTMP(A6) 2782 * 2783 *tfpval = (short)ltmp;2784 * 2782 2783 | tfpval = (short)ltmp; 2784 2785 2785 F04L147: move.w LTMP+2(A6),TFPVAL(A6) 2786 2786 bra F04L149 2787 * 2788 *} else {2789 * 2790 *tfpval = pt->ipval;2791 * 2787 2788 | } else { 2789 2790 | tfpval = pt->ipval; 2791 2792 2792 F04L136: move.l PT(A6),A0 2793 2793 move 2(A0),TFPVAL(A6) 2794 * 2795 *}2796 * 2797 .page 2798 * 2799 *fpmant = (((long)pt->iptom & 0x0000FFF0L)2800 * *((long)timemlt & 0x0000FFFFL)) >> 15;2801 * 2794 2795 | } 2796 2797 .page 2798 2799 | fpmant = (((long)pt->iptom & 0x0000FFF0L) 2800 | | ((long)timemlt & 0x0000FFFFL)) >> 15; 2801 2802 2802 F04L149: move.l PT(A6),A0 2803 2803 move.w (A0),D0 2804 2804 move.w D0,D2 2805 andi.w # $FFF0,D02805 andi.w #0xFFF0,D0 2806 2806 move.w _timemlt,D1 2807 2807 muls D1,D0 … … 2809 2809 asr.l D1,D0 2810 2810 move D0,R_FPMANT 2811 * 2812 *fpexp = expbit[pt->iptim & 0x000F];2813 * 2814 and # $000F,D22811 2812 | fpexp = expbit[pt->iptim & 0x000F]; 2813 2814 and #0x000F,D2 2815 2815 move D2,A0 2816 2816 add.l A0,A0 2817 2817 add.l #_expbit,A0 2818 2818 move (A0),R_FPEXP 2819 * 2820 .page 2821 * 2822 *fp->idfpch = pch;2823 * 2819 2820 .page 2821 2822 | fp->idfpch = pch; 2823 2824 2824 F04L158: move PCH(A6),(A_FP) 2825 * 2826 *ltmp = ((long)tfpval >> 1) + ((longtfpval >>2)2827 *+ (long)fp->idfpch;2828 * 2825 2826 | ltmp = ((long)tfpval >> 1) + ((longtfpval >>2) 2827 | + (long)fp->idfpch; 2828 2829 2829 move TFPVAL(A6),D0 2830 2830 ext.l D0 … … 2838 2838 add.l D1,D0 2839 2839 move.l D0,LTMP(A6) 2840 * 2841 *if (ltmp GT (long)VALMAX)2842 *ltmp = (long)VALMAX;2843 * 2840 2841 | if (ltmp GT (long)VALMAX) 2842 | ltmp = (long)VALMAX; 2843 2844 2844 cmp.l #VALMAX,LTMP(A6) 2845 2845 ble F04L159 2846 * 2846 2847 2847 move.l #VALMAX,LTMP(A6) 2848 2848 bra F04L160 2849 * 2850 *else if (ltmp LT (long)VALMIN)2851 *ltmp = (long)VALMIN;2852 * 2849 2850 | else if (ltmp LT (long)VALMIN) 2851 | ltmp = (long)VALMIN; 2852 2853 2853 F04L159: cmp.l #VALMIN,LTMP(A6) 2854 2854 bge F04L160 2855 * 2855 2856 2856 move.l #VALMIN,LTMP(A6) 2857 * 2858 *fpval = (short)ltmp;2859 * 2857 2858 | fpval = (short)ltmp; 2859 2860 2860 F04L160: move.l LTMP(A6),D0 2861 2861 move D0,R_FPVAL 2862 * 2863 .page 2864 * 2862 2863 .page 2864 2865 2865 move.b 5(A_FP),D0 2866 2866 ext.w D0 2867 2867 sub.w #1,D0 2868 2868 movea.l PT(A6),A0 2869 * 2870 *oldi = setipl(FPU_DI);2871 * 2869 2870 | oldi = setipl(FPU_DI); 2871 2872 2872 move sr,OLDI(A6) 2873 2873 move #FPU_DI,sr 2874 * 2874 2875 2875 F04L168: clr.b 10(A0) 2876 2876 add.l #12,a0 2877 2877 dbra D0,F04L168 2878 * 2879 .page 2880 * 2881 *fp->idftmd ^= I_NVBITS;2882 * 2878 2879 .page 2880 2881 | fp->idftmd ^= I_NVBITS; 2882 2883 2883 F04L165: eor.b #24,7(A_FP) 2884 * 2885 *fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;2886 * 2884 2885 | fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003; 2886 2887 2887 move.b 7(A_FP),R_FPCTL 2888 2888 and #28,R_FPCTL 2889 2889 or #3,R_FPCTL 2890 * 2891 *fp->idfcpt = fp->idfpt1;2892 * 2890 2891 | fp->idfcpt = fp->idfpt1; 2892 2893 2893 move.b 6(A_FP),8(A_FP) 2894 * 2895 *fp->idftmd |= I_ACTIVE;2896 * 2894 2895 | fp->idftmd |= I_ACTIVE; 2896 2897 2897 or.b #2,7(A_FP) 2898 * 2899 *fp->idftrf = trg;2900 * 2898 2899 | fp->idftrf = trg; 2900 2901 2901 move TRG(A6),10(A_FP) 2902 * 2903 * *(fpu + (long)FPU_TCV1) = srcval;2904 * 2905 move SRCVAL(A6), $8(A_FPU)2906 * 2907 *++octype;2908 * 2902 2903 | |(fpu + (long)FPU_TCV1) = srcval; 2904 2905 move SRCVAL(A6),0x8(A_FPU) 2906 2907 | ++octype; 2908 2909 2909 add #1,OCTYPE(A6) 2910 * 2911 * *(fpu + (long)FPU_TSF1) = mltval;2912 * 2913 move MLTVAL(A6), $A(A_FPU)2914 * 2915 *++octype;2916 * 2910 2911 | |(fpu + (long)FPU_TSF1) = mltval; 2912 2913 move MLTVAL(A6),0xA(A_FPU) 2914 2915 | ++octype; 2916 2917 2917 add #1,OCTYPE(A6) 2918 * 2919 * *(fpu + (long)FPU_TMNT) = fpmant;2920 * 2921 move R_FPMANT, $14(A_FPU)2922 * 2923 *++octype;2924 * 2918 2919 | |(fpu + (long)FPU_TMNT) = fpmant; 2920 2921 move R_FPMANT,0x14(A_FPU) 2922 2923 | ++octype; 2924 2925 2925 add #1,OCTYPE(A6) 2926 * 2927 * *(fpu + (long)FPU_TEXP) = fpexp;2928 * 2929 move R_FPEXP, $16(A_FPU)2930 * 2931 *++octype;2932 * 2926 2927 | |(fpu + (long)FPU_TEXP) = fpexp; 2928 2929 move R_FPEXP,0x16(A_FPU) 2930 2931 | ++octype; 2932 2933 2933 add #1,OCTYPE(A6) 2934 * 2935 .page 2936 * 2937 *if (fp->idftmd & I_VNSUBN)2938 * 2934 2935 .page 2936 2937 | if (fp->idftmd & I_VNSUBN) 2938 2939 2939 btst #3,7(A_FP) 2940 2940 beq F04L169 2941 * 2942 * *(fpu + (long)FPU_TNV1) = fpval;2943 * 2944 move R_FPVAL, $1C(A_FPU)2941 2942 | |(fpu + (long)FPU_TNV1) = fpval; 2943 2944 move R_FPVAL,0x1C(A_FPU) 2945 2945 bra F04L170 2946 * 2947 *else2948 * *(fpu + (long)FPU_TNV0) = fpval;2949 * 2946 2947 | else 2948 | |(fpu + (long)FPU_TNV0) = fpval; 2949 2950 2950 F04L169: move R_FPVAL,2(A_FPU) 2951 * 2952 *++octype;2953 * 2951 2952 | ++octype; 2953 2954 2954 F04L170: add #1,OCTYPE(A6) 2955 * 2956 * *(fpu + (long)FPU_TCTL) = fpctl;2957 * 2955 2956 | |(fpu + (long)FPU_TCTL) = fpctl; 2957 2958 2958 move R_FPCTL,(A_FPU) 2959 * 2960 *setipl(oldi);2961 * 2959 2960 | setipl(oldi); 2961 2962 2962 move OLDI(A6),sr 2963 * 2964 .page 2965 *------------------------------------------------------------------------------2966 *Start function 5 -- Loctn2967 *------------------------------------------------------------------------------2968 * 2969 *if (ip->idhfnc[5].idftmd & I_TM_KEY) {2970 * 2963 2964 .page 2965 | ------------------------------------------------------------------------------ 2966 | Start function 5 -- Loctn 2967 | ------------------------------------------------------------------------------ 2968 2969 | if (ip->idhfnc[5].idftmd & I_TM_KEY) { 2970 2971 2971 FN05: move.l IP(A6),A0 2972 2972 move.b 153(A0),D0 … … 2975 2975 btst #0,D0 2976 2976 bne FN05A 2977 * 2977 2978 2978 jmp FN06 2979 * 2980 *vp = (vce << 4) + 4;2981 * 2979 2980 | vp = (vce << 4) + 4; 2981 2982 2982 FN05A: move VCE(A6),D0 2983 2983 asl #4,D0 2984 2984 add.w #4,D0 2985 2985 move D0,VP(A6) 2986 * 2987 *fpu = io_fpu + FPU_OFNC + (vp << 4);2988 * 2986 2987 | fpu = io_fpu + FPU_OFNC + (vp << 4); 2988 2989 2989 asl #5,D0 2990 2990 ext.l D0 2991 2991 move.l D0,A_FPU 2992 add.l #_io_fpu+ $4000,A_FPU2993 * 2994 *fp = &ip->idhfnc[5];2995 * 2992 add.l #_io_fpu+0x4000,A_FPU 2993 2994 | fp = &ip->idhfnc[5]; 2995 2996 2996 move.l #60,A_FP 2997 2997 add.l IP(A6),A_FP 2998 2998 add.l #86,A_FP 2999 * 3000 *pt = &ip->idhpnt[fp->idfpt1];3001 * 2999 3000 | pt = &ip->idhpnt[fp->idfpt1]; 3001 3002 3002 clr.l D0 3003 3003 move.b 6(A_FP),D0 … … 3009 3009 add.l #242,D0 3010 3010 move.l D0,PT(A6) 3011 * 3012 .page 3013 * 3014 *srcnum = group | fp->idfsrc;3015 * 3011 3012 .page 3013 3014 | srcnum = group | fp->idfsrc; 3015 3016 3016 move.w GROUP(A6),D0 3017 3017 ext.l D0 … … 3020 3020 or D1,D0 3021 3021 move D0,SRCNUM(A6) 3022 * 3023 *vep = &valents[srcnum];3024 * 3022 3023 | vep = &valents[srcnum]; 3024 3025 3025 add.l D0,D0 3026 3026 move.l D0,D1 … … 3029 3029 add.l #_valents,D0 3030 3030 move.l D0,VEP(A6) 3031 * 3032 *smp = vpsms[vp];3033 * 3031 3032 | smp = vpsms[vp]; 3033 3034 3034 move VP(A6),A0 3035 3035 add.l A0,A0 … … 3037 3037 add.l #_vpsms,A0 3038 3038 move.l (A0),A_SMP 3039 * 3040 *if (srcnum NE smp->sm) {3041 * 3039 3040 | if (srcnum NE smp->sm) { 3041 3042 3042 clr D0 3043 3043 move 10(A_SMP),D0 3044 3044 cmp SRCNUM(A6),D0 3045 3045 beq F05L113 3046 * 3047 *(smp->prv)->nxt = smp->nxt;3048 * 3046 3047 | (smp->prv)->nxt = smp->nxt; 3048 3049 3049 move.l 4(A_SMP),A0 3050 3050 move.l (A_SMP),(A0) 3051 * 3052 *(smp->nxt)->prv = smp->prv;3053 * 3051 3052 | (smp->nxt)->prv = smp->prv; 3053 3054 3054 move.l (A_SMP),A0 3055 3055 move.l 4(A_SMP),4(A0) 3056 * 3057 * smp->prv = (struct sment *)vep;3058 * 3056 3057 | smp->prv = (struct sment |)vep; 3058 3059 3059 move.l VEP(A6),4(A_SMP) 3060 * 3061 *smp->nxt = vep->nxt;3062 * 3060 3061 | smp->nxt = vep->nxt; 3062 3063 3063 move.l VEP(A6),A0 3064 3064 move.l (A0),(A_SMP) 3065 * 3066 *(vep->nxt)->prv = smp;3067 * 3065 3066 | (vep->nxt)->prv = smp; 3067 3068 3068 move.l VEP(A6),A0 3069 3069 move.l (A0),A0 3070 3070 move.l A_SMP,4(A0) 3071 * 3072 *vep->nxt = smp;3073 * 3071 3072 | vep->nxt = smp; 3073 3074 3074 move.l VEP(A6),A0 3075 3075 move.l A_SMP,(A0) 3076 * 3077 *smp->sm = srcnum;3078 * 3076 3077 | smp->sm = srcnum; 3078 3079 3079 move SRCNUM(A6),10(A_SMP) 3080 * 3081 *}3082 * 3083 *mltval = fp->idfmlt;3084 * 3080 3081 | } 3082 3083 | mltval = fp->idfmlt; 3084 3085 3085 F05L113: move 2(A_FP),MLTVAL(A6) 3086 * 3087 .page 3088 * 3089 *switch (fp->idfsrc) {3090 * 3086 3087 .page 3088 3089 | switch (fp->idfsrc) { 3090 3091 3091 move.b 4(A_FP),D0 3092 3092 ext.w d0 3093 3093 cmp #10,D0 3094 3094 bhi F05L122 3095 * 3095 3096 3096 asl #2,D0 3097 3097 lea F05L123,A0 3098 3098 movea.l 0(A0,D0.W),A0 3099 3099 jmp (A0) 3100 * 3101 *case SM_NONE:3102 *mltval = 0;3103 * 3100 3101 | case SM_NONE: 3102 | mltval = 0; 3103 3104 3104 F05L116: clr MLTVAL(A6) 3105 * 3106 *tsrcval = 0;3107 * 3105 3106 | tsrcval = 0; 3107 3108 3108 clr TSRCVAL(A6) 3109 * 3110 *break;3111 * 3109 3110 | break; 3111 3112 3112 bra F05L114 3113 * 3114 *case SM_RAND:3115 *tsrcval = xgetran(mltval);3116 * 3113 3114 | case SM_RAND: 3115 | tsrcval = xgetran(mltval); 3116 3117 3117 F05L117: move MLTVAL(A6),(sp) 3118 3118 jsr _xgetran 3119 3119 move D0,TSRCVAL(A6) 3120 * 3121 *break;3122 * 3120 3121 | break; 3122 3123 3123 bra F05L114 3124 * 3125 *case SM_PTCH:3126 *tsrcval = pch;3127 * 3124 3125 | case SM_PTCH: 3126 | tsrcval = pch; 3127 3128 3128 F05L118: move PCH(A6),TSRCVAL(A6) 3129 * 3130 *break;3131 * 3129 3130 | break; 3131 3132 3132 bra F05L114 3133 * 3134 .page 3135 * 3136 *case SM_FREQ:3137 *tsrcval = ptoftab[(pch >> 7) & 0x00FF];3138 * 3133 3134 .page 3135 3136 | case SM_FREQ: 3137 | tsrcval = ptoftab[(pch >> 7) & 0x00FF]; 3138 3139 3139 F05L119: move PCH(A6),D0 3140 3140 asr #7,D0 … … 3144 3144 add.l #_ptoftab,A0 3145 3145 move (A0),TSRCVAL(A6) 3146 * 3147 *break;3148 * 3146 3147 | break; 3148 3149 3149 bra F05L114 3150 * 3151 *case SM_KVEL:3152 *tsrcval = veltab[trg];3153 * 3150 3151 | case SM_KVEL: 3152 | tsrcval = veltab[trg]; 3153 3154 3154 F05L120: move TRG(A6),A0 3155 3155 add.l A0,A0 3156 3156 add.l #_veltab,A0 3157 3157 move (A0),TSRCVAL(A6) 3158 * 3159 *break;3160 * 3158 3159 | break; 3160 3161 3161 bra F05L114 3162 * 3163 *case SM_KPRS:3164 *tsrcval = prstab[trg];3165 * 3162 3163 | case SM_KPRS: 3164 | tsrcval = prstab[trg]; 3165 3166 3166 F05L121: move TRG(A6),A0 3167 3167 add.l A0,A0 3168 3168 add.l #_prstab,A0 3169 3169 move (A0),TSRCVAL(A6) 3170 * 3171 *break;3172 * 3170 3171 | break; 3172 3173 3173 bra F05L114 3174 * 3175 *default:3176 *tsrcval = vep->val;3177 * 3174 3175 | default: 3176 | tsrcval = vep->val; 3177 3178 3178 F05L122: move.l VEP(A6),A0 3179 3179 move 8(A0),TSRCVAL(A6) 3180 * 3181 *}3182 * 3183 .page 3184 * 3185 *srcval = tsrcval;3186 * 3180 3181 | } 3182 3183 .page 3184 3185 | srcval = tsrcval; 3186 3187 3187 F05L114: move TSRCVAL(A6),SRCVAL(A6) 3188 * 3189 .page 3190 * 3191 *if (pt->ipvsrc) {3192 * 3188 3189 .page 3190 3191 | if (pt->ipvsrc) { 3192 3193 3193 F05L124: move.l PT(A6),A0 3194 3194 tst.b 6(A0) 3195 3195 beq F05L136 3196 * 3197 *switch (pt->ipvsrc) {3198 * 3196 3197 | switch (pt->ipvsrc) { 3198 3199 3199 move.l PT(A6),A0 3200 3200 move.b 6(A0),D0 … … 3203 3203 cmp #9,D0 3204 3204 bhi F05L144 3205 * 3205 3206 3206 asl #2,D0 3207 3207 lea F05L145,A0 3208 3208 move.l 0(A0,D0.W),A0 3209 3209 jmp (A0) 3210 * 3211 *case SM_RAND:3212 *ltmp = xgetran(pt_>ipvmlt);3213 * 3210 3211 | case SM_RAND: 3212 | ltmp = xgetran(pt_>ipvmlt); 3213 3214 3214 F05L139: move.l PT(A6),A0 3215 3215 move 4(A0),(sp) … … 3217 3217 ext.l D0 3218 3218 move.l D0,LTMP(A6) 3219 * 3220 *break;3221 * 3219 3220 | break; 3221 3222 3222 bra F05L137 3223 * 3224 *case SM_PTCH:3225 *ltmp = pch;3226 * 3223 3224 | case SM_PTCH: 3225 | ltmp = pch; 3226 3227 3227 F05L140: move PCH(A6),A0 3228 3228 move.l A0,LTMP(A6) 3229 * 3230 *break;3231 * 3229 3230 | break; 3231 3232 3232 bra F05L137 3233 * 3234 .page 3235 * 3236 *case SM_FREQ:3237 *ltmp = ptoftab[(pch >> 7) & 0x00FF];3238 * 3233 3234 .page 3235 3236 | case SM_FREQ: 3237 | ltmp = ptoftab[(pch >> 7) & 0x00FF]; 3238 3239 3239 F05L141: move PCH(A6),D0 3240 3240 asr #7,D0 … … 3246 3246 ext.l D0 3247 3247 move.l D0,LTMP(A6) 3248 * 3249 *break;3250 * 3248 3249 | break; 3250 3251 3251 bra F05L137 3252 * 3253 *case SM_KVEL:3254 *ltmp = veltab[trg];3255 * 3252 3253 | case SM_KVEL: 3254 | ltmp = veltab[trg]; 3255 3256 3256 F05L142: move TRG(A6),A0 3257 3257 add.l A0,A0 … … 3260 3260 ext.l D0 3261 3261 move.l D0,LTMP(A6) 3262 * 3263 *break;3264 * 3262 3263 | break; 3264 3265 3265 bra F05L137 3266 * 3267 .page 3268 * 3269 *case SM_KPRS:3270 *ltmp = prstab[trg];3271 * 3266 3267 .page 3268 3269 | case SM_KPRS: 3270 | ltmp = prstab[trg]; 3271 3272 3272 F05L143: move TRG(A6),A0 3273 3273 add.l A0,A0 … … 3276 3276 ext.l D0 3277 3277 move.l D0,LTMP(A6) 3278 * 3279 *break;3280 * 3278 3279 | break; 3280 3281 3281 bra F05L137 3282 * 3283 .page 3284 * 3285 *default:3286 *ltmp = valents[group | pt->ipvsrc].val;3287 * 3282 3283 .page 3284 3285 | default: 3286 | ltmp = valents[group | pt->ipvsrc].val; 3287 3288 3288 F05L144: move.l PT(A6),A0 3289 3289 clr.l D0 … … 3299 3299 move 8(A0,A1.l),D0 3300 3300 move.l D0,LTMP(A6) 3301 * 3302 *}3303 * 3304 * 3305 .page 3306 * 3307 * ltmp = (ltmp *pt->ipvmlt) >> 15;3308 * 3301 3302 | } 3303 3304 3305 .page 3306 3307 | ltmp = (ltmp | pt->ipvmlt) >> 15; 3308 3309 3309 F05L137: move.l PT(A6),A0 3310 3310 move.w 4(A0),D0 … … 3314 3314 asr.l D1,D0 3315 3315 move.l D0,LTMP(A6) 3316 * 3317 *ltmp += (long)pt->ipval;3318 * 3316 3317 | ltmp += (long)pt->ipval; 3318 3319 3319 move.l PT(A6),A0 3320 3320 move 2(A0),D0 3321 3321 ext.l D0 3322 3322 add.l D0,LTMP(A6) 3323 * 3324 *if (ltmp GT (long)VALMAX)3325 *ltmp = (long)VALMAX;3326 * 3323 3324 | if (ltmp GT (long)VALMAX) 3325 | ltmp = (long)VALMAX; 3326 3327 3327 cmp.l #VALMAX,LTMP(A6) 3328 3328 ble F05L146 3329 * 3329 3330 3330 move.l #VALMAX,LTMP(A6) 3331 3331 bra F05L147 3332 * 3333 *else if (ltmp LT (long)VALMIN)3334 *ltmp = (long)VALMIN;3335 * 3332 3333 | else if (ltmp LT (long)VALMIN) 3334 | ltmp = (long)VALMIN; 3335 3336 3336 F05L146: cmp.l #VALMIN,LTMP(A6) 3337 3337 bge F05L147 3338 * 3338 3339 3339 move.l #VALMIN,LTMP(A6) 3340 * 3341 *tfpval = (short)ltmp;3342 * 3340 3341 | tfpval = (short)ltmp; 3342 3343 3343 F05L147: move.w LTMP+2(A6),TFPVAL(A6) 3344 3344 bra F05L149 3345 * 3346 *} else {3347 * 3348 *tfpval = pt->ipval;3349 * 3345 3346 | } else { 3347 3348 | tfpval = pt->ipval; 3349 3350 3350 F05L136: move.l PT(A6),A0 3351 3351 move 2(A0),TFPVAL(A6) 3352 * 3353 *}3354 * 3355 .page 3356 * 3357 *fpmant = (((long)pt->iptom & 0x0000FFF0L)3358 * *((long)timemlt & 0x0000FFFFL)) >> 15;3359 * 3352 3353 | } 3354 3355 .page 3356 3357 | fpmant = (((long)pt->iptom & 0x0000FFF0L) 3358 | | ((long)timemlt & 0x0000FFFFL)) >> 15; 3359 3360 3360 F05L149: move.l PT(A6),A0 3361 3361 move.w (A0),D0 3362 3362 move.w D0,D2 3363 andi.w # $FFF0,D03363 andi.w #0xFFF0,D0 3364 3364 move.w _timemlt,D1 3365 3365 muls D1,D0 … … 3367 3367 asr.l D1,D0 3368 3368 move D0,R_FPMANT 3369 * 3370 *fpexp = expbit[pt->iptim & 0x000F];3371 * 3372 and # $000F,D23369 3370 | fpexp = expbit[pt->iptim & 0x000F]; 3371 3372 and #0x000F,D2 3373 3373 move D2,A0 3374 3374 add.l A0,A0 3375 3375 add.l #_expbit,A0 3376 3376 move (A0),R_FPEXP 3377 * 3378 .page 3379 * 3380 *fp->idfpch = pch;3381 * 3377 3378 .page 3379 3380 | fp->idfpch = pch; 3381 3382 3382 F05L163: move PCH(A6),(A_FP) 3383 * 3384 *if (tfpval > VALMAX)3385 *tfpval = VALMAX;3386 *else if (tfpval < 0)3387 *tfpval = 0;3388 * 3383 3384 | if (tfpval > VALMAX) 3385 | tfpval = VALMAX; 3386 | else if (tfpval < 0) 3387 | tfpval = 0; 3388 3389 3389 move.w TFPVAL(A6),D0 3390 cmp.w # $7D00,D03390 cmp.w #0x7D00,D0 3391 3391 ble F05L163B 3392 * 3393 move.w # $7D00,D03392 3393 move.w #0x7D00,D0 3394 3394 bra F05L163A 3395 3395 3396 3396 F05L163B: tst.w D0 3397 3397 bpl F05L163A 3398 * 3398 3399 3399 clr.w D0 3400 * 3401 *#if LOC_EOR3402 *fpval = (tfpval << 1) ^ 0x8000;3403 *#endif3404 * 3400 3401 |#if LOC_EOR 3402 | fpval = (tfpval << 1) ^ 0x8000; 3403 |#endif 3404 3405 3405 .ifne LOC_EOR 3406 3406 F05L163A: add.w D0,D0 3407 eor.w # $8000,D03407 eor.w #0x8000,D0 3408 3408 .endc 3409 * 3410 *#if LOC_SUB3411 *fpval = ((tfpval >> 5) - 500) << 6;3412 *#endif3413 * 3409 3410 |#if LOC_SUB 3411 | fpval = ((tfpval >> 5) - 500) << 6; 3412 |#endif 3413 3414 3414 .ifne LOC_SUB 3415 3415 F05L163A: asr.w #5,D0 … … 3417 3417 asl.w #6,D0 3418 3418 .endc 3419 * 3419 3420 3420 move.w D0,R_FPVAL 3421 * 3422 .page 3423 * 3421 3422 .page 3423 3424 3424 move.b 5(A_FP),D0 3425 3425 ext.w D0 3426 3426 sub.w #1,D0 3427 3427 movea.l PT(A6),A0 3428 * 3429 *oldi = setipl(FPU_DI);3430 * 3428 3429 | oldi = setipl(FPU_DI); 3430 3431 3431 move sr,OLDI(A6) 3432 3432 move #FPU_DI,sr 3433 * 3433 3434 3434 F05L168: clr.b 10(A0) 3435 3435 add.l #12,a0 3436 3436 dbra D0,F05L168 3437 * 3438 .page 3439 * 3440 *fp->idftmd ^= I_NVBITS;3441 * 3437 3438 .page 3439 3440 | fp->idftmd ^= I_NVBITS; 3441 3442 3442 F05L165: eor.b #24,7(A_FP) 3443 * 3444 *fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;3445 * 3443 3444 | fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003; 3445 3446 3446 move.b 7(A_FP),R_FPCTL 3447 3447 and #28,R_FPCTL 3448 3448 or #3,R_FPCTL 3449 * 3450 *fp->idfcpt = fp->idfpt1;3451 * 3449 3450 | fp->idfcpt = fp->idfpt1; 3451 3452 3452 move.b 6(A_FP),8(A_FP) 3453 * 3454 *fp->idftmd |= I_ACTIVE;3455 * 3453 3454 | fp->idftmd |= I_ACTIVE; 3455 3456 3456 or.b #2,7(A_FP) 3457 * 3458 *fp->idftrf = trg;3459 * 3457 3458 | fp->idftrf = trg; 3459 3460 3460 move TRG(A6),10(A_FP) 3461 * 3462 * *(fpu + (long)FPU_TCV1) = srcval;3463 * 3464 move SRCVAL(A6), $8(A_FPU)3465 * 3466 *++octype;3467 * 3461 3462 | |(fpu + (long)FPU_TCV1) = srcval; 3463 3464 move SRCVAL(A6),0x8(A_FPU) 3465 3466 | ++octype; 3467 3468 3468 add #1,OCTYPE(A6) 3469 * 3470 * *(fpu + (long)FPU_TSF1) = mltval;3471 * 3472 move MLTVAL(A6), $A(A_FPU)3473 * 3474 *++octype;3475 * 3469 3470 | |(fpu + (long)FPU_TSF1) = mltval; 3471 3472 move MLTVAL(A6),0xA(A_FPU) 3473 3474 | ++octype; 3475 3476 3476 add #1,OCTYPE(A6) 3477 * 3478 * *(fpu + (long)FPU_TMNT) = fpmant;3479 * 3480 move R_FPMANT, $14(A_FPU)3481 * 3482 *++octype;3483 * 3477 3478 | |(fpu + (long)FPU_TMNT) = fpmant; 3479 3480 move R_FPMANT,0x14(A_FPU) 3481 3482 | ++octype; 3483 3484 3484 add #1,OCTYPE(A6) 3485 * 3486 * *(fpu + (long)FPU_TEXP) = fpexp;3487 * 3488 move R_FPEXP, $16(A_FPU)3489 * 3490 *++octype;3491 * 3485 3486 | |(fpu + (long)FPU_TEXP) = fpexp; 3487 3488 move R_FPEXP,0x16(A_FPU) 3489 3490 | ++octype; 3491 3492 3492 add #1,OCTYPE(A6) 3493 * 3494 .page 3495 * 3496 *if (fp->idftmd & I_VNSUBN)3497 * 3493 3494 .page 3495 3496 | if (fp->idftmd & I_VNSUBN) 3497 3498 3498 btst #3,7(A_FP) 3499 3499 beq F05L169 3500 * 3501 * *(fpu + (long)FPU_TNV1) = fpval;3502 * 3503 move R_FPVAL, $1C(A_FPU)3500 3501 | |(fpu + (long)FPU_TNV1) = fpval; 3502 3503 move R_FPVAL,0x1C(A_FPU) 3504 3504 bra F05L170 3505 * 3506 *else3507 * *(fpu + (long)FPU_TNV0) = fpval;3508 * 3505 3506 | else 3507 | |(fpu + (long)FPU_TNV0) = fpval; 3508 3509 3509 F05L169: move R_FPVAL,2(A_FPU) 3510 * 3511 *++octype;3512 * 3510 3511 | ++octype; 3512 3513 3513 F05L170: add #1,OCTYPE(A6) 3514 * 3515 * *(fpu + (long)FPU_TCTL) = fpctl;3516 * 3514 3515 | |(fpu + (long)FPU_TCTL) = fpctl; 3516 3517 3517 move R_FPCTL,(A_FPU) 3518 * 3519 *setipl(oldi);3520 * 3518 3519 | setipl(oldi); 3520 3521 3521 move OLDI(A6),sr 3522 * 3523 .page 3524 *------------------------------------------------------------------------------3525 *Start function 6 -- Ind 13526 *------------------------------------------------------------------------------3527 * 3528 *if (ip->idhfnc[2].idftmd & I_TM_KEY) {3529 * 3522 3523 .page 3524 | ------------------------------------------------------------------------------ 3525 | Start function 6 -- Ind 1 3526 | ------------------------------------------------------------------------------ 3527 3528 | if (ip->idhfnc[2].idftmd & I_TM_KEY) { 3529 3530 3530 FN06: move.l IP(A6),A0 3531 3531 move.b 165(A0),D0 … … 3534 3534 btst #0,D0 3535 3535 bne FN06A 3536 * 3536 3537 3537 jmp FN07 3538 * 3539 *vp = (vce << 4) + 9;3540 * 3538 3539 | vp = (vce << 4) + 9; 3540 3541 3541 FN06A: move VCE(A6),D0 3542 3542 asl #4,D0 3543 3543 add.w #9,D0 3544 3544 move D0,VP(A6) 3545 * 3546 *fpu = io_fpu + FPU_OFNC + (vp << 4);3547 * 3545 3546 | fpu = io_fpu + FPU_OFNC + (vp << 4); 3547 3548 3548 asl #5,D0 3549 3549 ext.l D0 3550 3550 move.l D0,A_FPU 3551 add.l #_io_fpu+ $4000,A_FPU3552 * 3553 *fp = &ip->idhfnc[6];3554 * 3551 add.l #_io_fpu+0x4000,A_FPU 3552 3553 | fp = &ip->idhfnc[6]; 3554 3555 3555 move.l #72,A_FP 3556 3556 add.l IP(A6),A_FP 3557 3557 add.l #86,A_FP 3558 * 3559 *pt = &ip->idhpnt[fp->idfpt1];3560 * 3558 3559 | pt = &ip->idhpnt[fp->idfpt1]; 3560 3561 3561 clr.l D0 3562 3562 move.b 6(A_FP),D0 … … 3568 3568 add.l #242,D0 3569 3569 move.l D0,PT(A6) 3570 * 3571 .page 3572 * 3573 *srcnum = group | fp->idfsrc;3574 * 3570 3571 .page 3572 3573 | srcnum = group | fp->idfsrc; 3574 3575 3575 move.w GROUP(A6),D0 3576 3576 ext.l D0 … … 3579 3579 or D1,D0 3580 3580 move D0,SRCNUM(A6) 3581 * 3582 *vep = &valents[srcnum];3583 * 3581 3582 | vep = &valents[srcnum]; 3583 3584 3584 add.l D0,D0 3585 3585 move.l D0,D1 … … 3588 3588 add.l #_valents,D0 3589 3589 move.l D0,VEP(A6) 3590 * 3591 *smp = vpsms[vp];3592 * 3590 3591 | smp = vpsms[vp]; 3592 3593 3593 move VP(A6),A0 3594 3594 add.l A0,A0 … … 3596 3596 add.l #_vpsms,A0 3597 3597 move.l (A0),A_SMP 3598 * 3599 *if (srcnum NE smp->sm) {3600 * 3598 3599 | if (srcnum NE smp->sm) { 3600 3601 3601 clr D0 3602 3602 move 10(A_SMP),D0 3603 3603 cmp SRCNUM(A6),D0 3604 3604 beq F06L113 3605 * 3606 *(smp->prv)->nxt = smp->nxt;3607 * 3605 3606 | (smp->prv)->nxt = smp->nxt; 3607 3608 3608 move.l 4(A_SMP),A0 3609 3609 move.l (A_SMP),(A0) 3610 * 3611 *(smp->nxt)->prv = smp->prv;3612 * 3610 3611 | (smp->nxt)->prv = smp->prv; 3612 3613 3613 move.l (A_SMP),A0 3614 3614 move.l 4(A_SMP),4(A0) 3615 * 3616 * smp->prv = (struct sment *)vep;3617 * 3615 3616 | smp->prv = (struct sment |)vep; 3617 3618 3618 move.l VEP(A6),4(A_SMP) 3619 * 3620 *smp->nxt = vep->nxt;3621 * 3619 3620 | smp->nxt = vep->nxt; 3621 3622 3622 move.l VEP(A6),A0 3623 3623 move.l (A0),(A_SMP) 3624 * 3625 *(vep->nxt)->prv = smp;3626 * 3624 3625 | (vep->nxt)->prv = smp; 3626 3627 3627 move.l VEP(A6),A0 3628 3628 move.l (A0),A0 3629 3629 move.l A_SMP,4(A0) 3630 * 3631 *vep->nxt = smp;3632 * 3630 3631 | vep->nxt = smp; 3632 3633 3633 move.l VEP(A6),A0 3634 3634 move.l A_SMP,(A0) 3635 * 3636 *smp->sm = srcnum;3637 * 3635 3636 | smp->sm = srcnum; 3637 3638 3638 move SRCNUM(A6),10(A_SMP) 3639 * 3640 *}3641 * 3642 *mltval = fp->idfmlt;3643 * 3639 3640 | } 3641 3642 | mltval = fp->idfmlt; 3643 3644 3644 F06L113: move 2(A_FP),MLTVAL(A6) 3645 * 3646 .page 3647 * 3648 *switch (fp->idfsrc) {3649 * 3645 3646 .page 3647 3648 | switch (fp->idfsrc) { 3649 3650 3650 move.b 4(A_FP),D0 3651 3651 ext.w d0 3652 3652 cmp #10,D0 3653 3653 bhi F06L122 3654 * 3654 3655 3655 asl #2,D0 3656 3656 lea F06L123,A0 3657 3657 movea.l 0(A0,D0.W),A0 3658 3658 jmp (A0) 3659 * 3660 *case SM_NONE:3661 *mltval = 0;3662 * 3659 3660 | case SM_NONE: 3661 | mltval = 0; 3662 3663 3663 F06L116: clr MLTVAL(A6) 3664 * 3665 *tsrcval = 0;3666 * 3664 3665 | tsrcval = 0; 3666 3667 3667 clr TSRCVAL(A6) 3668 * 3669 *break;3670 * 3668 3669 | break; 3670 3671 3671 bra F06L114 3672 * 3673 *case SM_RAND:3674 *tsrcval = xgetran(mltval);3675 * 3672 3673 | case SM_RAND: 3674 | tsrcval = xgetran(mltval); 3675 3676 3676 F06L117: move MLTVAL(A6),(sp) 3677 3677 jsr _xgetran 3678 3678 move D0,TSRCVAL(A6) 3679 * 3680 *break;3681 * 3679 3680 | break; 3681 3682 3682 bra F06L114 3683 * 3684 *case SM_PTCH:3685 *tsrcval = pch;3686 * 3683 3684 | case SM_PTCH: 3685 | tsrcval = pch; 3686 3687 3687 F06L118: move PCH(A6),TSRCVAL(A6) 3688 * 3689 *break;3690 * 3688 3689 | break; 3690 3691 3691 bra F06L114 3692 * 3693 .page 3694 * 3695 *case SM_FREQ:3696 *tsrcval = ptoftab[(pch >> 7) & 0x00FF];3697 * 3692 3693 .page 3694 3695 | case SM_FREQ: 3696 | tsrcval = ptoftab[(pch >> 7) & 0x00FF]; 3697 3698 3698 F06L119: move PCH(A6),D0 3699 3699 asr #7,D0 … … 3703 3703 add.l #_ptoftab,A0 3704 3704 move (A0),TSRCVAL(A6) 3705 * 3706 *break;3707 * 3705 3706 | break; 3707 3708 3708 bra F06L114 3709 * 3710 *case SM_KVEL:3711 *tsrcval = veltab[trg];3712 * 3709 3710 | case SM_KVEL: 3711 | tsrcval = veltab[trg]; 3712 3713 3713 F06L120: move TRG(A6),A0 3714 3714 add.l A0,A0 3715 3715 add.l #_veltab,A0 3716 3716 move (A0),TSRCVAL(A6) 3717 * 3718 *break;3719 * 3717 3718 | break; 3719 3720 3720 bra F06L114 3721 * 3722 *case SM_KPRS:3723 *tsrcval = prstab[trg];3724 * 3721 3722 | case SM_KPRS: 3723 | tsrcval = prstab[trg]; 3724 3725 3725 F06L121: move TRG(A6),A0 3726 3726 add.l A0,A0 3727 3727 add.l #_prstab,A0 3728 3728 move (A0),TSRCVAL(A6) 3729 * 3730 *break;3731 * 3729 3730 | break; 3731 3732 3732 bra F06L114 3733 * 3734 *default:3735 *tsrcval = vep->val;3736 * 3733 3734 | default: 3735 | tsrcval = vep->val; 3736 3737 3737 F06L122: move.l VEP(A6),A0 3738 3738 move 8(A0),TSRCVAL(A6) 3739 * 3740 *}3741 * 3742 .page 3743 * 3744 *srcval = tsrcval;3745 * 3739 3740 | } 3741 3742 .page 3743 3744 | srcval = tsrcval; 3745 3746 3746 F06L114: move TSRCVAL(A6),SRCVAL(A6) 3747 * 3748 .page 3749 * 3750 *if (pt->ipvsrc) {3751 * 3747 3748 .page 3749 3750 | if (pt->ipvsrc) { 3751 3752 3752 F06L124: move.l PT(A6),A0 3753 3753 tst.b 6(A0) 3754 3754 beq F06L136 3755 * 3756 *switch (pt->ipvsrc) {3757 * 3755 3756 | switch (pt->ipvsrc) { 3757 3758 3758 move.l PT(A6),A0 3759 3759 move.b 6(A0),D0 … … 3762 3762 cmp #9,D0 3763 3763 bhi F06L144 3764 * 3764 3765 3765 asl #2,D0 3766 3766 lea F06L145,A0 3767 3767 move.l 0(A0,D0.W),A0 3768 3768 jmp (A0) 3769 * 3770 *case SM_RAND:3771 *ltmp = xgetran(pt_>ipvmlt);3772 * 3769 3770 | case SM_RAND: 3771 | ltmp = xgetran(pt_>ipvmlt); 3772 3773 3773 F06L139: move.l PT(A6),A0 3774 3774 move 4(A0),(sp) … … 3776 3776 ext.l D0 3777 3777 move.l D0,LTMP(A6) 3778 * 3779 *break;3780 * 3778 3779 | break; 3780 3781 3781 bra F06L137 3782 * 3783 *case SM_PTCH:3784 *ltmp = pch;3785 * 3782 3783 | case SM_PTCH: 3784 | ltmp = pch; 3785 3786 3786 F06L140: move PCH(A6),A0 3787 3787 move.l A0,LTMP(A6) 3788 * 3789 *break;3790 * 3788 3789 | break; 3790 3791 3791 bra F06L137 3792 * 3793 .page 3794 * 3795 *case SM_FREQ:3796 *ltmp = ptoftab[(pch >> 7) & 0x00FF];3797 * 3792 3793 .page 3794 3795 | case SM_FREQ: 3796 | ltmp = ptoftab[(pch >> 7) & 0x00FF]; 3797 3798 3798 F06L141: move PCH(A6),D0 3799 3799 asr #7,D0 … … 3805 3805 ext.l D0 3806 3806 move.l D0,LTMP(A6) 3807 * 3808 *break;3809 * 3807 3808 | break; 3809 3810 3810 bra F06L137 3811 * 3812 *case SM_KVEL:3813 *ltmp = veltab[trg];3814 * 3811 3812 | case SM_KVEL: 3813 | ltmp = veltab[trg]; 3814 3815 3815 F06L142: move TRG(A6),A0 3816 3816 add.l A0,A0 … … 3819 3819 ext.l D0 3820 3820 move.l D0,LTMP(A6) 3821 * 3822 *break;3823 * 3821 3822 | break; 3823 3824 3824 bra F06L137 3825 * 3826 .page 3827 * 3828 *case SM_KPRS:3829 *ltmp = prstab[trg];3830 * 3825 3826 .page 3827 3828 | case SM_KPRS: 3829 | ltmp = prstab[trg]; 3830 3831 3831 F06L143: move TRG(A6),A0 3832 3832 add.l A0,A0 … … 3835 3835 ext.l D0 3836 3836 move.l D0,LTMP(A6) 3837 * 3838 *break;3839 * 3837 3838 | break; 3839 3840 3840 bra F06L137 3841 * 3842 .page 3843 * 3844 *default:3845 *ltmp = valents[group | pt->ipvsrc].val;3846 * 3841 3842 .page 3843 3844 | default: 3845 | ltmp = valents[group | pt->ipvsrc].val; 3846 3847 3847 F06L144: move.l PT(A6),A0 3848 3848 clr.l D0 … … 3858 3858 move 8(A0,A1.l),D0 3859 3859 move.l D0,LTMP(A6) 3860 * 3861 *}3862 * 3863 * 3864 .page 3865 * 3866 * ltmp = (ltmp *pt->ipvmlt) >> 15;3867 * 3860 3861 | } 3862 3863 3864 .page 3865 3866 | ltmp = (ltmp | pt->ipvmlt) >> 15; 3867 3868 3868 F06L137: move.l PT(A6),A0 3869 3869 move.w 4(A0),D0 … … 3873 3873 asr.l D1,D0 3874 3874 move.l D0,LTMP(A6) 3875 * 3876 *ltmp += (long)pt->ipval;3877 * 3875 3876 | ltmp += (long)pt->ipval; 3877 3878 3878 move.l PT(A6),A0 3879 3879 move 2(A0),D0 3880 3880 ext.l D0 3881 3881 add.l D0,LTMP(A6) 3882 * 3883 *if (ltmp GT (long)VALMAX)3884 *ltmp = (long)VALMAX;3885 * 3882 3883 | if (ltmp GT (long)VALMAX) 3884 | ltmp = (long)VALMAX; 3885 3886 3886 cmp.l #VALMAX,LTMP(A6) 3887 3887 ble F06L146 3888 * 3888 3889 3889 move.l #VALMAX,LTMP(A6) 3890 3890 bra F06L147 3891 * 3892 *else if (ltmp LT (long)VALMIN)3893 *ltmp = (long)VALMIN;3894 * 3891 3892 | else if (ltmp LT (long)VALMIN) 3893 | ltmp = (long)VALMIN; 3894 3895 3895 F06L146: cmp.l #VALMIN,LTMP(A6) 3896 3896 bge F06L147 3897 * 3897 3898 3898 move.l #VALMIN,LTMP(A6) 3899 * 3900 *tfpval = (short)ltmp;3901 * 3899 3900 | tfpval = (short)ltmp; 3901 3902 3902 F06L147: move.w LTMP+2(A6),TFPVAL(A6) 3903 3903 bra F06L149 3904 * 3905 *} else {3906 * 3907 *tfpval = pt->ipval;3908 * 3904 3905 | } else { 3906 3907 | tfpval = pt->ipval; 3908 3909 3909 F06L136: move.l PT(A6),A0 3910 3910 move 2(A0),TFPVAL(A6) 3911 * 3912 *}3913 * 3914 .page 3915 * 3916 *fpmant = (((long)pt->iptom & 0x0000FFF0L)3917 * *((long)timemlt & 0x0000FFFFL)) >> 15;3918 * 3911 3912 | } 3913 3914 .page 3915 3916 | fpmant = (((long)pt->iptom & 0x0000FFF0L) 3917 | | ((long)timemlt & 0x0000FFFFL)) >> 15; 3918 3919 3919 F06L149: move.l PT(A6),A0 3920 3920 move.w (A0),D0 3921 3921 move.w D0,D2 3922 andi.w # $FFF0,D03922 andi.w #0xFFF0,D0 3923 3923 move.w _timemlt,D1 3924 3924 muls D1,D0 … … 3926 3926 asr.l D1,D0 3927 3927 move D0,R_FPMANT 3928 * 3929 *fpexp = expbit[pt->iptim & 0x000F];3930 * 3931 and # $000F,D23928 3929 | fpexp = expbit[pt->iptim & 0x000F]; 3930 3931 and #0x000F,D2 3932 3932 move D2,A0 3933 3933 add.l A0,A0 3934 3934 add.l #_expbit,A0 3935 3935 move (A0),R_FPEXP 3936 * 3937 .page 3938 * 3939 *fp->idfpch = pch;3940 * 3936 3937 .page 3938 3939 | fp->idfpch = pch; 3940 3941 3941 F06L163: move PCH(A6),(A_FP) 3942 * 3943 *fpval = tfpval;3944 * 3942 3943 | fpval = tfpval; 3944 3945 3945 move TFPVAL(A6),R_FPVAL 3946 * 3947 .page 3948 * 3946 3947 .page 3948 3949 3949 move.b 5(A_FP),D0 3950 3950 ext.w D0 3951 3951 sub.w #1,D0 3952 3952 movea.l PT(A6),A0 3953 * 3954 *oldi = setipl(FPU_DI);3955 * 3953 3954 | oldi = setipl(FPU_DI); 3955 3956 3956 move sr,OLDI(A6) 3957 3957 move #FPU_DI,sr 3958 * 3958 3959 3959 F06L168: clr.b 10(A0) 3960 3960 add.l #12,a0 3961 3961 dbra D0,F06L168 3962 * 3963 .page 3964 * 3965 *fp->idftmd ^= I_NVBITS;3966 * 3962 3963 .page 3964 3965 | fp->idftmd ^= I_NVBITS; 3966 3967 3967 F06L165: eor.b #24,7(A_FP) 3968 * 3969 *fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;3970 * 3968 3969 | fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003; 3970 3971 3971 move.b 7(A_FP),R_FPCTL 3972 3972 and #28,R_FPCTL 3973 3973 or #3,R_FPCTL 3974 * 3975 *fp->idfcpt = fp->idfpt1;3976 * 3974 3975 | fp->idfcpt = fp->idfpt1; 3976 3977 3977 move.b 6(A_FP),8(A_FP) 3978 * 3979 *fp->idftmd |= I_ACTIVE;3980 * 3978 3979 | fp->idftmd |= I_ACTIVE; 3980 3981 3981 or.b #2,7(A_FP) 3982 * 3983 *fp->idftrf = trg;3984 * 3982 3983 | fp->idftrf = trg; 3984 3985 3985 move TRG(A6),10(A_FP) 3986 * 3987 * *(fpu + (long)FPU_TCV1) = srcval;3988 * 3989 move SRCVAL(A6), $8(A_FPU)3990 * 3991 *++octype;3992 * 3986 3987 | |(fpu + (long)FPU_TCV1) = srcval; 3988 3989 move SRCVAL(A6),0x8(A_FPU) 3990 3991 | ++octype; 3992 3993 3993 add #1,OCTYPE(A6) 3994 * 3995 * *(fpu + (long)FPU_TSF1) = mltval;3996 * 3997 move MLTVAL(A6), $A(A_FPU)3998 * 3999 *++octype;4000 * 3994 3995 | |(fpu + (long)FPU_TSF1) = mltval; 3996 3997 move MLTVAL(A6),0xA(A_FPU) 3998 3999 | ++octype; 4000 4001 4001 add #1,OCTYPE(A6) 4002 * 4003 * *(fpu + (long)FPU_TMNT) = fpmant;4004 * 4005 move R_FPMANT, $14(A_FPU)4006 * 4007 *++octype;4008 * 4002 4003 | |(fpu + (long)FPU_TMNT) = fpmant; 4004 4005 move R_FPMANT,0x14(A_FPU) 4006 4007 | ++octype; 4008 4009 4009 add #1,OCTYPE(A6) 4010 * 4011 * *(fpu + (long)FPU_TEXP) = fpexp;4012 * 4013 move R_FPEXP, $16(A_FPU)4014 * 4015 *++octype;4016 * 4010 4011 | |(fpu + (long)FPU_TEXP) = fpexp; 4012 4013 move R_FPEXP,0x16(A_FPU) 4014 4015 | ++octype; 4016 4017 4017 add #1,OCTYPE(A6) 4018 * 4019 .page 4020 * 4021 *if (fp->idftmd & I_VNSUBN)4022 * 4018 4019 .page 4020 4021 | if (fp->idftmd & I_VNSUBN) 4022 4023 4023 btst #3,7(A_FP) 4024 4024 beq F06L169 4025 * 4026 * *(fpu + (long)FPU_TNV1) = fpval;4027 * 4028 move R_FPVAL, $1C(A_FPU)4025 4026 | |(fpu + (long)FPU_TNV1) = fpval; 4027 4028 move R_FPVAL,0x1C(A_FPU) 4029 4029 bra F06L170 4030 * 4031 *else4032 * *(fpu + (long)FPU_TNV0) = fpval;4033 * 4030 4031 | else 4032 | |(fpu + (long)FPU_TNV0) = fpval; 4033 4034 4034 F06L169: move R_FPVAL,2(A_FPU) 4035 * 4036 *++octype;4037 * 4035 4036 | ++octype; 4037 4038 4038 F06L170: add #1,OCTYPE(A6) 4039 * 4040 * *(fpu + (long)FPU_TCTL) = fpctl;4041 * 4039 4040 | |(fpu + (long)FPU_TCTL) = fpctl; 4041 4042 4042 move R_FPCTL,(A_FPU) 4043 * 4044 *setipl(oldi);4045 * 4043 4044 | setipl(oldi); 4045 4046 4046 move OLDI(A6),sr 4047 * 4048 .page 4049 *------------------------------------------------------------------------------4050 *Start function 7 -- Ind 24051 *------------------------------------------------------------------------------4052 * 4053 *if (ip->idhfnc[7].idftmd & I_TM_KEY) {4054 * 4047 4048 .page 4049 | ------------------------------------------------------------------------------ 4050 | Start function 7 -- Ind 2 4051 | ------------------------------------------------------------------------------ 4052 4053 | if (ip->idhfnc[7].idftmd & I_TM_KEY) { 4054 4055 4055 FN07: move.l IP(A6),A0 4056 4056 move.b 177(A0),D0 … … 4059 4059 btst #0,D0 4060 4060 bne FN07A 4061 * 4061 4062 4062 jmp FN08 4063 * 4064 *vp = (vce << 4) + 11;4065 * 4063 4064 | vp = (vce << 4) + 11; 4065 4066 4066 FN07A: move VCE(A6),D0 4067 4067 asl #4,D0 4068 4068 add.w #11,D0 4069 4069 move D0,VP(A6) 4070 * 4071 *fpu = io_fpu + FPU_OFNC + (vp << 4);4072 * 4070 4071 | fpu = io_fpu + FPU_OFNC + (vp << 4); 4072 4073 4073 asl #5,D0 4074 4074 ext.l D0 4075 4075 move.l D0,A_FPU 4076 add.l #_io_fpu+ $4000,A_FPU4077 * 4078 *fp = &ip->idhfnc[7];4079 * 4076 add.l #_io_fpu+0x4000,A_FPU 4077 4078 | fp = &ip->idhfnc[7]; 4079 4080 4080 move.l #84,A_FP 4081 4081 add.l IP(A6),A_FP 4082 4082 add.l #86,A_FP 4083 * 4084 *pt = &ip->idhpnt[fp->idfpt1];4085 * 4083 4084 | pt = &ip->idhpnt[fp->idfpt1]; 4085 4086 4086 clr.l D0 4087 4087 move.b 6(A_FP),D0 … … 4093 4093 add.l #242,D0 4094 4094 move.l D0,PT(A6) 4095 * 4096 .page 4097 * 4098 *srcnum = group | fp->idfsrc;4099 * 4095 4096 .page 4097 4098 | srcnum = group | fp->idfsrc; 4099 4100 4100 move.w GROUP(A6),D0 4101 4101 ext.l D0 … … 4104 4104 or D1,D0 4105 4105 move D0,SRCNUM(A6) 4106 * 4107 *vep = &valents[srcnum];4108 * 4106 4107 | vep = &valents[srcnum]; 4108 4109 4109 add.l D0,D0 4110 4110 move.l D0,D1 … … 4113 4113 add.l #_valents,D0 4114 4114 move.l D0,VEP(A6) 4115 * 4116 *smp = vpsms[vp];4117 * 4115 4116 | smp = vpsms[vp]; 4117 4118 4118 move VP(A6),A0 4119 4119 add.l A0,A0 … … 4121 4121 add.l #_vpsms,A0 4122 4122 move.l (A0),A_SMP 4123 * 4124 *if (srcnum NE smp->sm) {4125 * 4123 4124 | if (srcnum NE smp->sm) { 4125 4126 4126 clr D0 4127 4127 move 10(A_SMP),D0 4128 4128 cmp SRCNUM(A6),D0 4129 4129 beq F07L113 4130 * 4131 *(smp->prv)->nxt = smp->nxt;4132 * 4130 4131 | (smp->prv)->nxt = smp->nxt; 4132 4133 4133 move.l 4(A_SMP),A0 4134 4134 move.l (A_SMP),(A0) 4135 * 4136 *(smp->nxt)->prv = smp->prv;4137 * 4135 4136 | (smp->nxt)->prv = smp->prv; 4137 4138 4138 move.l (A_SMP),A0 4139 4139 move.l 4(A_SMP),4(A0) 4140 * 4141 * smp->prv = (struct sment *)vep;4142 * 4140 4141 | smp->prv = (struct sment |)vep; 4142 4143 4143 move.l VEP(A6),4(A_SMP) 4144 * 4145 *smp->nxt = vep->nxt;4146 * 4144 4145 | smp->nxt = vep->nxt; 4146 4147 4147 move.l VEP(A6),A0 4148 4148 move.l (A0),(A_SMP) 4149 * 4150 *(vep->nxt)->prv = smp;4151 * 4149 4150 | (vep->nxt)->prv = smp; 4151 4152 4152 move.l VEP(A6),A0 4153 4153 move.l (A0),A0 4154 4154 move.l A_SMP,4(A0) 4155 * 4156 *vep->nxt = smp;4157 * 4155 4156 | vep->nxt = smp; 4157 4158 4158 move.l VEP(A6),A0 4159 4159 move.l A_SMP,(A0) 4160 * 4161 *smp->sm = srcnum;4162 * 4160 4161 | smp->sm = srcnum; 4162 4163 4163 move SRCNUM(A6),10(A_SMP) 4164 * 4165 *}4166 * 4167 *mltval = fp->idfmlt;4168 * 4164 4165 | } 4166 4167 | mltval = fp->idfmlt; 4168 4169 4169 F07L113: move 2(A_FP),MLTVAL(A6) 4170 * 4171 .page 4172 * 4173 *switch (fp->idfsrc) {4174 * 4170 4171 .page 4172 4173 | switch (fp->idfsrc) { 4174 4175 4175 move.b 4(A_FP),D0 4176 4176 ext.w d0 4177 4177 cmp #10,D0 4178 4178 bhi F07L122 4179 * 4179 4180 4180 asl #2,D0 4181 4181 lea F07L123,A0 4182 4182 movea.l 0(A0,D0.W),A0 4183 4183 jmp (A0) 4184 * 4185 *case SM_NONE:4186 *mltval = 0;4187 * 4184 4185 | case SM_NONE: 4186 | mltval = 0; 4187 4188 4188 F07L116: clr MLTVAL(A6) 4189 * 4190 *tsrcval = 0;4191 * 4189 4190 | tsrcval = 0; 4191 4192 4192 clr TSRCVAL(A6) 4193 * 4194 *break;4195 * 4193 4194 | break; 4195 4196 4196 bra F07L114 4197 * 4198 *case SM_RAND:4199 *tsrcval = xgetran(mltval);4200 * 4197 4198 | case SM_RAND: 4199 | tsrcval = xgetran(mltval); 4200 4201 4201 F07L117: move MLTVAL(A6),(sp) 4202 4202 jsr _xgetran 4203 4203 move D0,TSRCVAL(A6) 4204 * 4205 *break;4206 * 4204 4205 | break; 4206 4207 4207 bra F07L114 4208 * 4209 *case SM_PTCH:4210 *tsrcval = pch;4211 * 4208 4209 | case SM_PTCH: 4210 | tsrcval = pch; 4211 4212 4212 F07L118: move PCH(A6),TSRCVAL(A6) 4213 * 4214 *break;4215 * 4213 4214 | break; 4215 4216 4216 bra F07L114 4217 * 4218 .page 4219 * 4220 *case SM_FREQ:4221 *tsrcval = ptoftab[(pch >> 7) & 0x00FF];4222 * 4217 4218 .page 4219 4220 | case SM_FREQ: 4221 | tsrcval = ptoftab[(pch >> 7) & 0x00FF]; 4222 4223 4223 F07L119: move PCH(A6),D0 4224 4224 asr #7,D0 … … 4228 4228 add.l #_ptoftab,A0 4229 4229 move (A0),TSRCVAL(A6) 4230 * 4231 *break;4232 * 4230 4231 | break; 4232 4233 4233 bra F07L114 4234 * 4235 *case SM_KVEL:4236 *tsrcval = veltab[trg];4237 * 4234 4235 | case SM_KVEL: 4236 | tsrcval = veltab[trg]; 4237 4238 4238 F07L120: move TRG(A6),A0 4239 4239 add.l A0,A0 4240 4240 add.l #_veltab,A0 4241 4241 move (A0),TSRCVAL(A6) 4242 * 4243 *break;4244 * 4242 4243 | break; 4244 4245 4245 bra F07L114 4246 * 4247 *case SM_KPRS:4248 *tsrcval = prstab[trg];4249 * 4246 4247 | case SM_KPRS: 4248 | tsrcval = prstab[trg]; 4249 4250 4250 F07L121: move TRG(A6),A0 4251 4251 add.l A0,A0 4252 4252 add.l #_prstab,A0 4253 4253 move (A0),TSRCVAL(A6) 4254 * 4255 *break;4256 * 4254 4255 | break; 4256 4257 4257 bra F07L114 4258 * 4259 *default:4260 *tsrcval = vep->val;4261 * 4258 4259 | default: 4260 | tsrcval = vep->val; 4261 4262 4262 F07L122: move.l VEP(A6),A0 4263 4263 move 8(A0),TSRCVAL(A6) 4264 * 4265 *}4266 * 4267 .page 4268 * 4269 *srcval = tsrcval;4270 * 4264 4265 | } 4266 4267 .page 4268 4269 | srcval = tsrcval; 4270 4271 4271 F07L114: move TSRCVAL(A6),SRCVAL(A6) 4272 * 4273 .page 4274 * 4275 *if (pt->ipvsrc) {4276 * 4272 4273 .page 4274 4275 | if (pt->ipvsrc) { 4276 4277 4277 F07L124: move.l PT(A6),A0 4278 4278 tst.b 6(A0) 4279 4279 beq F07L136 4280 * 4281 *switch (pt->ipvsrc) {4282 * 4280 4281 | switch (pt->ipvsrc) { 4282 4283 4283 move.l PT(A6),A0 4284 4284 move.b 6(A0),D0 … … 4287 4287 cmp #9,D0 4288 4288 bhi F07L144 4289 * 4289 4290 4290 asl #2,D0 4291 4291 lea F07L145,A0 4292 4292 move.l 0(A0,D0.W),A0 4293 4293 jmp (A0) 4294 * 4295 *case SM_RAND:4296 *ltmp = xgetran(pt_>ipvmlt);4297 * 4294 4295 | case SM_RAND: 4296 | ltmp = xgetran(pt_>ipvmlt); 4297 4298 4298 F07L139: move.l PT(A6),A0 4299 4299 move 4(A0),(sp) … … 4301 4301 ext.l D0 4302 4302 move.l D0,LTMP(A6) 4303 * 4304 *break;4305 * 4303 4304 | break; 4305 4306 4306 bra F07L137 4307 * 4308 *case SM_PTCH:4309 *ltmp = pch;4310 * 4307 4308 | case SM_PTCH: 4309 | ltmp = pch; 4310 4311 4311 F07L140: move PCH(A6),A0 4312 4312 move.l A0,LTMP(A6) 4313 * 4314 *break;4315 * 4313 4314 | break; 4315 4316 4316 bra F07L137 4317 * 4318 .page 4319 * 4320 *case SM_FREQ:4321 *ltmp = ptoftab[(pch >> 7) & 0x00FF];4322 * 4317 4318 .page 4319 4320 | case SM_FREQ: 4321 | ltmp = ptoftab[(pch >> 7) & 0x00FF]; 4322 4323 4323 F07L141: move PCH(A6),D0 4324 4324 asr #7,D0 … … 4330 4330 ext.l D0 4331 4331 move.l D0,LTMP(A6) 4332 * 4333 *break;4334 * 4332 4333 | break; 4334 4335 4335 bra F07L137 4336 * 4337 *case SM_KVEL:4338 *ltmp = veltab[trg];4339 * 4336 4337 | case SM_KVEL: 4338 | ltmp = veltab[trg]; 4339 4340 4340 F07L142: move TRG(A6),A0 4341 4341 add.l A0,A0 … … 4344 4344 ext.l D0 4345 4345 move.l D0,LTMP(A6) 4346 * 4347 *break;4348 * 4346 4347 | break; 4348 4349 4349 bra F07L137 4350 * 4351 .page 4352 * 4353 *case SM_KPRS:4354 *ltmp = prstab[trg];4355 * 4350 4351 .page 4352 4353 | case SM_KPRS: 4354 | ltmp = prstab[trg]; 4355 4356 4356 F07L143: move TRG(A6),A0 4357 4357 add.l A0,A0 … … 4360 4360 ext.l D0 4361 4361 move.l D0,LTMP(A6) 4362 * 4363 *break;4364 * 4362 4363 | break; 4364 4365 4365 bra F07L137 4366 * 4367 .page 4368 * 4369 *default:4370 *ltmp = valents[group | pt->ipvsrc].val;4371 * 4366 4367 .page 4368 4369 | default: 4370 | ltmp = valents[group | pt->ipvsrc].val; 4371 4372 4372 F07L144: move.l PT(A6),A0 4373 4373 clr.l D0 … … 4383 4383 move 8(A0,A1.l),D0 4384 4384 move.l D0,LTMP(A6) 4385 * 4386 *}4387 * 4388 * 4389 .page 4390 * 4391 * ltmp = (ltmp *pt->ipvmlt) >> 15;4392 * 4385 4386 | } 4387 4388 4389 .page 4390 4391 | ltmp = (ltmp | pt->ipvmlt) >> 15; 4392 4393 4393 F07L137: move.l PT(A6),A0 4394 4394 move.w 4(A0),D0 … … 4398 4398 asr.l D1,D0 4399 4399 move.l D0,LTMP(A6) 4400 * 4401 *ltmp += (long)pt->ipval;4402 * 4400 4401 | ltmp += (long)pt->ipval; 4402 4403 4403 move.l PT(A6),A0 4404 4404 move 2(A0),D0 4405 4405 ext.l D0 4406 4406 add.l D0,LTMP(A6) 4407 * 4408 *if (ltmp GT (long)VALMAX)4409 *ltmp = (long)VALMAX;4410 * 4407 4408 | if (ltmp GT (long)VALMAX) 4409 | ltmp = (long)VALMAX; 4410 4411 4411 cmp.l #VALMAX,LTMP(A6) 4412 4412 ble F07L146 4413 * 4413 4414 4414 move.l #VALMAX,LTMP(A6) 4415 4415 bra F07L147 4416 * 4417 *else if (ltmp LT (long)VALMIN)4418 *ltmp = (long)VALMIN;4419 * 4416 4417 | else if (ltmp LT (long)VALMIN) 4418 | ltmp = (long)VALMIN; 4419 4420 4420 F07L146: cmp.l #VALMIN,LTMP(A6) 4421 4421 bge F07L147 4422 * 4422 4423 4423 move.l #VALMIN,LTMP(A6) 4424 * 4425 *tfpval = (short)ltmp;4426 * 4424 4425 | tfpval = (short)ltmp; 4426 4427 4427 F07L147: move.w LTMP+2(A6),TFPVAL(A6) 4428 4428 bra F07L149 4429 * 4430 *} else {4431 * 4432 *tfpval = pt->ipval;4433 * 4429 4430 | } else { 4431 4432 | tfpval = pt->ipval; 4433 4434 4434 F07L136: move.l PT(A6),A0 4435 4435 move 2(A0),TFPVAL(A6) 4436 * 4437 *}4438 * 4439 .page 4440 * 4441 *fpmant = (((long)pt->iptom & 0x0000FFF0L)4442 * *((long)timemlt & 0x0000FFFFL)) >> 15;4443 * 4436 4437 | } 4438 4439 .page 4440 4441 | fpmant = (((long)pt->iptom & 0x0000FFF0L) 4442 | | ((long)timemlt & 0x0000FFFFL)) >> 15; 4443 4444 4444 F07L149: move.l PT(A6),A0 4445 4445 move.w (A0),D0 4446 4446 move.w D0,D2 4447 andi.w # $FFF0,D04447 andi.w #0xFFF0,D0 4448 4448 move.w _timemlt,D1 4449 4449 muls D1,D0 … … 4451 4451 asr.l D1,D0 4452 4452 move D0,R_FPMANT 4453 * 4454 *fpexp = expbit[pt->iptim & 0x000F];4455 * 4456 and # $000F,D24453 4454 | fpexp = expbit[pt->iptim & 0x000F]; 4455 4456 and #0x000F,D2 4457 4457 move D2,A0 4458 4458 add.l A0,A0 4459 4459 add.l #_expbit,A0 4460 4460 move (A0),R_FPEXP 4461 * 4462 .page 4463 * 4464 *fp->idfpch = pch;4465 * 4461 4462 .page 4463 4464 | fp->idfpch = pch; 4465 4466 4466 F07L163: move PCH(A6),(A_FP) 4467 * 4468 *fpval = tfpval;4469 * 4467 4468 | fpval = tfpval; 4469 4470 4470 move TFPVAL(A6),R_FPVAL 4471 * 4472 .page 4473 * 4471 4472 .page 4473 4474 4474 move.b 5(A_FP),D0 4475 4475 ext.w D0 4476 4476 sub.w #1,D0 4477 4477 movea.l PT(A6),A0 4478 * 4479 *oldi = setipl(FPU_DI);4480 * 4478 4479 | oldi = setipl(FPU_DI); 4480 4481 4481 move sr,OLDI(A6) 4482 4482 move #FPU_DI,sr 4483 * 4483 4484 4484 F07L168: clr.b 10(A0) 4485 4485 add.l #12,a0 4486 4486 dbra D0,F07L168 4487 * 4488 .page 4489 * 4490 *fp->idftmd ^= I_NVBITS;4491 * 4487 4488 .page 4489 4490 | fp->idftmd ^= I_NVBITS; 4491 4492 4492 F07L165: eor.b #24,7(A_FP) 4493 * 4494 *fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;4495 * 4493 4494 | fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003; 4495 4496 4496 move.b 7(A_FP),R_FPCTL 4497 4497 and #28,R_FPCTL 4498 4498 or #3,R_FPCTL 4499 * 4500 *fp->idfcpt = fp->idfpt1;4501 * 4499 4500 | fp->idfcpt = fp->idfpt1; 4501 4502 4502 move.b 6(A_FP),8(A_FP) 4503 * 4504 *fp->idftmd |= I_ACTIVE;4505 * 4503 4504 | fp->idftmd |= I_ACTIVE; 4505 4506 4506 or.b #2,7(A_FP) 4507 * 4508 *fp->idftrf = trg;4509 * 4507 4508 | fp->idftrf = trg; 4509 4510 4510 move TRG(A6),10(A_FP) 4511 * 4512 * *(fpu + (long)FPU_TCV1) = srcval;4513 * 4514 move SRCVAL(A6), $8(A_FPU)4515 * 4516 *++octype;4517 * 4511 4512 | |(fpu + (long)FPU_TCV1) = srcval; 4513 4514 move SRCVAL(A6),0x8(A_FPU) 4515 4516 | ++octype; 4517 4518 4518 add #1,OCTYPE(A6) 4519 * 4520 * *(fpu + (long)FPU_TSF1) = mltval;4521 * 4522 move MLTVAL(A6), $A(A_FPU)4523 * 4524 *++octype;4525 * 4519 4520 | |(fpu + (long)FPU_TSF1) = mltval; 4521 4522 move MLTVAL(A6),0xA(A_FPU) 4523 4524 | ++octype; 4525 4526 4526 add #1,OCTYPE(A6) 4527 * 4528 * *(fpu + (long)FPU_TMNT) = fpmant;4529 * 4530 move R_FPMANT, $14(A_FPU)4531 * 4532 *++octype;4533 * 4527 4528 | |(fpu + (long)FPU_TMNT) = fpmant; 4529 4530 move R_FPMANT,0x14(A_FPU) 4531 4532 | ++octype; 4533 4534 4534 add #1,OCTYPE(A6) 4535 * 4536 * *(fpu + (long)FPU_TEXP) = fpexp;4537 * 4538 move R_FPEXP, $16(A_FPU)4539 * 4540 *++octype;4541 * 4535 4536 | |(fpu + (long)FPU_TEXP) = fpexp; 4537 4538 move R_FPEXP,0x16(A_FPU) 4539 4540 | ++octype; 4541 4542 4542 add #1,OCTYPE(A6) 4543 * 4544 .page 4545 * 4546 *if (fp->idftmd & I_VNSUBN)4547 * 4543 4544 .page 4545 4546 | if (fp->idftmd & I_VNSUBN) 4547 4548 4548 btst #3,7(A_FP) 4549 4549 beq F07L169 4550 * 4551 * *(fpu + (long)FPU_TNV1) = fpval;4552 * 4553 move R_FPVAL, $1C(A_FPU)4550 4551 | |(fpu + (long)FPU_TNV1) = fpval; 4552 4553 move R_FPVAL,0x1C(A_FPU) 4554 4554 bra F07L170 4555 * 4556 *else4557 * *(fpu + (long)FPU_TNV0) = fpval;4558 * 4555 4556 | else 4557 | |(fpu + (long)FPU_TNV0) = fpval; 4558 4559 4559 F07L169: move R_FPVAL,2(A_FPU) 4560 * 4561 *++octype;4562 * 4560 4561 | ++octype; 4562 4563 4563 F07L170: add #1,OCTYPE(A6) 4564 * 4565 * *(fpu + (long)FPU_TCTL) = fpctl;4566 * 4564 4565 | |(fpu + (long)FPU_TCTL) = fpctl; 4566 4567 4567 move R_FPCTL,(A_FPU) 4568 * 4569 *setipl(oldi);4570 * 4568 4569 | setipl(oldi); 4570 4571 4571 move OLDI(A6),sr 4572 * 4573 .page 4574 *------------------------------------------------------------------------------4575 *Start function 8 -- Ind 34576 *------------------------------------------------------------------------------4577 * 4578 *if (ip->idhfnc[8].idftmd & I_TM_KEY) {4579 * 4572 4573 .page 4574 | ------------------------------------------------------------------------------ 4575 | Start function 8 -- Ind 3 4576 | ------------------------------------------------------------------------------ 4577 4578 | if (ip->idhfnc[8].idftmd & I_TM_KEY) { 4579 4580 4580 FN08: move.l IP(A6),A0 4581 4581 move.b 189(A0),D0 … … 4584 4584 btst #0,D0 4585 4585 bne FN08A 4586 * 4586 4587 4587 jmp FN09 4588 * 4589 *vp = (vce << 4) + 12;4590 * 4588 4589 | vp = (vce << 4) + 12; 4590 4591 4591 FN08A: move VCE(A6),D0 4592 4592 asl #4,D0 4593 4593 add.w #12,D0 4594 4594 move D0,VP(A6) 4595 * 4596 *fpu = io_fpu + FPU_OFNC + (vp << 4);4597 * 4595 4596 | fpu = io_fpu + FPU_OFNC + (vp << 4); 4597 4598 4598 asl #5,D0 4599 4599 ext.l D0 4600 4600 move.l D0,A_FPU 4601 add.l #_io_fpu+ $4000,A_FPU4602 * 4603 *fp = &ip->idhfnc[8];4604 * 4601 add.l #_io_fpu+0x4000,A_FPU 4602 4603 | fp = &ip->idhfnc[8]; 4604 4605 4605 move.l #96,A_FP 4606 4606 add.l IP(A6),A_FP 4607 4607 add.l #86,A_FP 4608 * 4609 *pt = &ip->idhpnt[fp->idfpt1];4610 * 4608 4609 | pt = &ip->idhpnt[fp->idfpt1]; 4610 4611 4611 clr.l D0 4612 4612 move.b 6(A_FP),D0 … … 4618 4618 add.l #242,D0 4619 4619 move.l D0,PT(A6) 4620 * 4621 .page 4622 * 4623 *srcnum = group | fp->idfsrc;4624 * 4620 4621 .page 4622 4623 | srcnum = group | fp->idfsrc; 4624 4625 4625 move.w GROUP(A6),D0 4626 4626 ext.l D0 … … 4629 4629 or D1,D0 4630 4630 move D0,SRCNUM(A6) 4631 * 4632 *vep = &valents[srcnum];4633 * 4631 4632 | vep = &valents[srcnum]; 4633 4634 4634 add.l D0,D0 4635 4635 move.l D0,D1 … … 4638 4638 add.l #_valents,D0 4639 4639 move.l D0,VEP(A6) 4640 * 4641 *smp = vpsms[vp];4642 * 4640 4641 | smp = vpsms[vp]; 4642 4643 4643 move VP(A6),A0 4644 4644 add.l A0,A0 … … 4646 4646 add.l #_vpsms,A0 4647 4647 move.l (A0),A_SMP 4648 * 4649 *if (srcnum NE smp->sm) {4650 * 4648 4649 | if (srcnum NE smp->sm) { 4650 4651 4651 clr D0 4652 4652 move 10(A_SMP),D0 4653 4653 cmp SRCNUM(A6),D0 4654 4654 beq F08L113 4655 * 4656 *(smp->prv)->nxt = smp->nxt;4657 * 4655 4656 | (smp->prv)->nxt = smp->nxt; 4657 4658 4658 move.l 4(A_SMP),A0 4659 4659 move.l (A_SMP),(A0) 4660 * 4661 *(smp->nxt)->prv = smp->prv;4662 * 4660 4661 | (smp->nxt)->prv = smp->prv; 4662 4663 4663 move.l (A_SMP),A0 4664 4664 move.l 4(A_SMP),4(A0) 4665 * 4666 * smp->prv = (struct sment *)vep;4667 * 4665 4666 | smp->prv = (struct sment |)vep; 4667 4668 4668 move.l VEP(A6),4(A_SMP) 4669 * 4670 *smp->nxt = vep->nxt;4671 * 4669 4670 | smp->nxt = vep->nxt; 4671 4672 4672 move.l VEP(A6),A0 4673 4673 move.l (A0),(A_SMP) 4674 * 4675 *(vep->nxt)->prv = smp;4676 * 4674 4675 | (vep->nxt)->prv = smp; 4676 4677 4677 move.l VEP(A6),A0 4678 4678 move.l (A0),A0 4679 4679 move.l A_SMP,4(A0) 4680 * 4681 *vep->nxt = smp;4682 * 4680 4681 | vep->nxt = smp; 4682 4683 4683 move.l VEP(A6),A0 4684 4684 move.l A_SMP,(A0) 4685 * 4686 *smp->sm = srcnum;4687 * 4685 4686 | smp->sm = srcnum; 4687 4688 4688 move SRCNUM(A6),10(A_SMP) 4689 * 4690 *}4691 * 4692 *mltval = fp->idfmlt;4693 * 4689 4690 | } 4691 4692 | mltval = fp->idfmlt; 4693 4694 4694 F08L113: move 2(A_FP),MLTVAL(A6) 4695 * 4696 .page 4697 * 4698 *switch (fp->idfsrc) {4699 * 4695 4696 .page 4697 4698 | switch (fp->idfsrc) { 4699 4700 4700 move.b 4(A_FP),D0 4701 4701 ext.w d0 4702 4702 cmp #10,D0 4703 4703 bhi F08L122 4704 * 4704 4705 4705 asl #2,D0 4706 4706 lea F08L123,A0 4707 4707 movea.l 0(A0,D0.W),A0 4708 4708 jmp (A0) 4709 * 4710 *case SM_NONE:4711 *mltval = 0;4712 * 4709 4710 | case SM_NONE: 4711 | mltval = 0; 4712 4713 4713 F08L116: clr MLTVAL(A6) 4714 * 4715 *tsrcval = 0;4716 * 4714 4715 | tsrcval = 0; 4716 4717 4717 clr TSRCVAL(A6) 4718 * 4719 *break;4720 * 4718 4719 | break; 4720 4721 4721 bra F08L114 4722 * 4723 *case SM_RAND:4724 *tsrcval = xgetran(mltval);4725 * 4722 4723 | case SM_RAND: 4724 | tsrcval = xgetran(mltval); 4725 4726 4726 F08L117: move MLTVAL(A6),(sp) 4727 4727 jsr _xgetran 4728 4728 move D0,TSRCVAL(A6) 4729 * 4730 *break;4731 * 4729 4730 | break; 4731 4732 4732 bra F08L114 4733 * 4734 *case SM_PTCH:4735 *tsrcval = pch;4736 * 4733 4734 | case SM_PTCH: 4735 | tsrcval = pch; 4736 4737 4737 F08L118: move PCH(A6),TSRCVAL(A6) 4738 * 4739 *break;4740 * 4738 4739 | break; 4740 4741 4741 bra F08L114 4742 * 4743 .page 4744 * 4745 *case SM_FREQ:4746 *tsrcval = ptoftab[(pch >> 7) & 0x00FF];4747 * 4742 4743 .page 4744 4745 | case SM_FREQ: 4746 | tsrcval = ptoftab[(pch >> 7) & 0x00FF]; 4747 4748 4748 F08L119: move PCH(A6),D0 4749 4749 asr #7,D0 … … 4753 4753 add.l #_ptoftab,A0 4754 4754 move (A0),TSRCVAL(A6) 4755 * 4756 *break;4757 * 4755 4756 | break; 4757 4758 4758 bra F08L114 4759 * 4760 *case SM_KVEL:4761 *tsrcval = veltab[trg];4762 * 4759 4760 | case SM_KVEL: 4761 | tsrcval = veltab[trg]; 4762 4763 4763 F08L120: move TRG(A6),A0 4764 4764 add.l A0,A0 4765 4765 add.l #_veltab,A0 4766 4766 move (A0),TSRCVAL(A6) 4767 * 4768 *break;4769 * 4767 4768 | break; 4769 4770 4770 bra F08L114 4771 * 4772 *case SM_KPRS:4773 *tsrcval = prstab[trg];4774 * 4771 4772 | case SM_KPRS: 4773 | tsrcval = prstab[trg]; 4774 4775 4775 F08L121: move TRG(A6),A0 4776 4776 add.l A0,A0 4777 4777 add.l #_prstab,A0 4778 4778 move (A0),TSRCVAL(A6) 4779 * 4780 *break;4781 * 4779 4780 | break; 4781 4782 4782 bra F08L114 4783 * 4784 *default:4785 *tsrcval = vep->val;4786 * 4783 4784 | default: 4785 | tsrcval = vep->val; 4786 4787 4787 F08L122: move.l VEP(A6),A0 4788 4788 move 8(A0),TSRCVAL(A6) 4789 * 4790 *}4791 * 4792 .page 4793 * 4794 *srcval = tsrcval;4795 * 4789 4790 | } 4791 4792 .page 4793 4794 | srcval = tsrcval; 4795 4796 4796 F08L114: move TSRCVAL(A6),SRCVAL(A6) 4797 * 4798 .page 4799 * 4800 *if (pt->ipvsrc) {4801 * 4797 4798 .page 4799 4800 | if (pt->ipvsrc) { 4801 4802 4802 F08L124: move.l PT(A6),A0 4803 4803 tst.b 6(A0) 4804 4804 beq F08L136 4805 * 4806 *switch (pt->ipvsrc) {4807 * 4805 4806 | switch (pt->ipvsrc) { 4807 4808 4808 move.l PT(A6),A0 4809 4809 move.b 6(A0),D0 … … 4812 4812 cmp #9,D0 4813 4813 bhi F08L144 4814 * 4814 4815 4815 asl #2,D0 4816 4816 lea F08L145,A0 4817 4817 move.l 0(A0,D0.W),A0 4818 4818 jmp (A0) 4819 * 4820 *case SM_RAND:4821 *ltmp = xgetran(pt_>ipvmlt);4822 * 4819 4820 | case SM_RAND: 4821 | ltmp = xgetran(pt_>ipvmlt); 4822 4823 4823 F08L139: move.l PT(A6),A0 4824 4824 move 4(A0),(sp) … … 4826 4826 ext.l D0 4827 4827 move.l D0,LTMP(A6) 4828 * 4829 *break;4830 * 4828 4829 | break; 4830 4831 4831 bra F08L137 4832 * 4833 *case SM_PTCH:4834 *ltmp = pch;4835 * 4832 4833 | case SM_PTCH: 4834 | ltmp = pch; 4835 4836 4836 F08L140: move PCH(A6),A0 4837 4837 move.l A0,LTMP(A6) 4838 * 4839 *break;4840 * 4838 4839 | break; 4840 4841 4841 bra F08L137 4842 * 4843 .page 4844 * 4845 *case SM_FREQ:4846 *ltmp = ptoftab[(pch >> 7) & 0x00FF];4847 * 4842 4843 .page 4844 4845 | case SM_FREQ: 4846 | ltmp = ptoftab[(pch >> 7) & 0x00FF]; 4847 4848 4848 F08L141: move PCH(A6),D0 4849 4849 asr #7,D0 … … 4855 4855 ext.l D0 4856 4856 move.l D0,LTMP(A6) 4857 * 4858 *break;4859 * 4857 4858 | break; 4859 4860 4860 bra F08L137 4861 * 4862 *case SM_KVEL:4863 *ltmp = veltab[trg];4864 * 4861 4862 | case SM_KVEL: 4863 | ltmp = veltab[trg]; 4864 4865 4865 F08L142: move TRG(A6),A0 4866 4866 add.l A0,A0 … … 4869 4869 ext.l D0 4870 4870 move.l D0,LTMP(A6) 4871 * 4872 *break;4873 * 4871 4872 | break; 4873 4874 4874 bra F08L137 4875 * 4876 .page 4877 * 4878 *case SM_KPRS:4879 *ltmp = prstab[trg];4880 * 4875 4876 .page 4877 4878 | case SM_KPRS: 4879 | ltmp = prstab[trg]; 4880 4881 4881 F08L143: move TRG(A6),A0 4882 4882 add.l A0,A0 … … 4885 4885 ext.l D0 4886 4886 move.l D0,LTMP(A6) 4887 * 4888 *break;4889 * 4887 4888 | break; 4889 4890 4890 bra F08L137 4891 * 4892 .page 4893 * 4894 *default:4895 *ltmp = valents[group | pt->ipvsrc].val;4896 * 4891 4892 .page 4893 4894 | default: 4895 | ltmp = valents[group | pt->ipvsrc].val; 4896 4897 4897 F08L144: move.l PT(A6),A0 4898 4898 clr.l D0 … … 4908 4908 move 8(A0,A1.l),D0 4909 4909 move.l D0,LTMP(A6) 4910 * 4911 *}4912 * 4913 * 4914 .page 4915 * 4916 * ltmp = (ltmp *pt->ipvmlt) >> 15;4917 * 4910 4911 | } 4912 4913 4914 .page 4915 4916 | ltmp = (ltmp | pt->ipvmlt) >> 15; 4917 4918 4918 F08L137: move.l PT(A6),A0 4919 4919 move.w 4(A0),D0 … … 4923 4923 asr.l D1,D0 4924 4924 move.l D0,LTMP(A6) 4925 * 4926 *ltmp += (long)pt->ipval;4927 * 4925 4926 | ltmp += (long)pt->ipval; 4927 4928 4928 move.l PT(A6),A0 4929 4929 move 2(A0),D0 4930 4930 ext.l D0 4931 4931 add.l D0,LTMP(A6) 4932 * 4933 *if (ltmp GT (long)VALMAX)4934 *ltmp = (long)VALMAX;4935 * 4932 4933 | if (ltmp GT (long)VALMAX) 4934 | ltmp = (long)VALMAX; 4935 4936 4936 cmp.l #VALMAX,LTMP(A6) 4937 4937 ble F08L146 4938 * 4938 4939 4939 move.l #VALMAX,LTMP(A6) 4940 4940 bra F08L147 4941 * 4942 *else if (ltmp LT (long)VALMIN)4943 *ltmp = (long)VALMIN;4944 * 4941 4942 | else if (ltmp LT (long)VALMIN) 4943 | ltmp = (long)VALMIN; 4944 4945 4945 F08L146: cmp.l #VALMIN,LTMP(A6) 4946 4946 bge F08L147 4947 * 4947 4948 4948 move.l #VALMIN,LTMP(A6) 4949 * 4950 *tfpval = (short)ltmp;4951 * 4949 4950 | tfpval = (short)ltmp; 4951 4952 4952 F08L147: move.w LTMP+2(A6),TFPVAL(A6) 4953 4953 bra F08L149 4954 * 4955 *} else {4956 * 4957 *tfpval = pt->ipval;4958 * 4954 4955 | } else { 4956 4957 | tfpval = pt->ipval; 4958 4959 4959 F08L136: move.l PT(A6),A0 4960 4960 move 2(A0),TFPVAL(A6) 4961 * 4962 *}4963 * 4964 .page 4965 * 4966 *fpmant = (((long)pt->iptom & 0x0000FFF0L)4967 * *((long)timemlt & 0x0000FFFFL)) >> 15;4968 * 4961 4962 | } 4963 4964 .page 4965 4966 | fpmant = (((long)pt->iptom & 0x0000FFF0L) 4967 | | ((long)timemlt & 0x0000FFFFL)) >> 15; 4968 4969 4969 F08L149: move.l PT(A6),A0 4970 4970 move.w (A0),D0 4971 4971 move.w D0,D2 4972 andi.w # $FFF0,D04972 andi.w #0xFFF0,D0 4973 4973 move.w _timemlt,D1 4974 4974 muls D1,D0 … … 4976 4976 asr.l D1,D0 4977 4977 move D0,R_FPMANT 4978 * 4979 *fpexp = expbit[pt->iptim & 0x000F];4980 * 4981 and # $000F,D24978 4979 | fpexp = expbit[pt->iptim & 0x000F]; 4980 4981 and #0x000F,D2 4982 4982 move D2,A0 4983 4983 add.l A0,A0 4984 4984 add.l #_expbit,A0 4985 4985 move (A0),R_FPEXP 4986 * 4987 .page 4988 * 4989 *fp->idfpch = pch;4990 * 4986 4987 .page 4988 4989 | fp->idfpch = pch; 4990 4991 4991 F08L163: move PCH(A6),(A_FP) 4992 * 4993 *fpval = tfpval;4994 * 4992 4993 | fpval = tfpval; 4994 4995 4995 move TFPVAL(A6),R_FPVAL 4996 * 4997 .page 4998 * 4996 4997 .page 4998 4999 4999 move.b 5(A_FP),D0 5000 5000 ext.w D0 5001 5001 sub.w #1,D0 5002 5002 movea.l PT(A6),A0 5003 * 5004 *oldi = setipl(FPU_DI);5005 * 5003 5004 | oldi = setipl(FPU_DI); 5005 5006 5006 move sr,OLDI(A6) 5007 5007 move #FPU_DI,sr 5008 * 5008 5009 5009 F08L168: clr.b 10(A0) 5010 5010 add.l #12,a0 5011 5011 dbra D0,F08L168 5012 * 5013 .page 5014 * 5015 *fp->idftmd ^= I_NVBITS;5016 * 5012 5013 .page 5014 5015 | fp->idftmd ^= I_NVBITS; 5016 5017 5017 F08L165: eor.b #24,7(A_FP) 5018 * 5019 *fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;5020 * 5018 5019 | fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003; 5020 5021 5021 move.b 7(A_FP),R_FPCTL 5022 5022 and #28,R_FPCTL 5023 5023 or #3,R_FPCTL 5024 * 5025 *fp->idfcpt = fp->idfpt1;5026 * 5024 5025 | fp->idfcpt = fp->idfpt1; 5026 5027 5027 move.b 6(A_FP),8(A_FP) 5028 * 5029 *fp->idftmd |= I_ACTIVE;5030 * 5028 5029 | fp->idftmd |= I_ACTIVE; 5030 5031 5031 or.b #2,7(A_FP) 5032 * 5033 *fp->idftrf = trg;5034 * 5032 5033 | fp->idftrf = trg; 5034 5035 5035 move TRG(A6),10(A_FP) 5036 * 5037 * *(fpu + (long)FPU_TCV1) = srcval;5038 * 5039 move SRCVAL(A6), $8(A_FPU)5040 * 5041 *++octype;5042 * 5036 5037 | |(fpu + (long)FPU_TCV1) = srcval; 5038 5039 move SRCVAL(A6),0x8(A_FPU) 5040 5041 | ++octype; 5042 5043 5043 add #1,OCTYPE(A6) 5044 * 5045 * *(fpu + (long)FPU_TSF1) = mltval;5046 * 5047 move MLTVAL(A6), $A(A_FPU)5048 * 5049 *++octype;5050 * 5044 5045 | |(fpu + (long)FPU_TSF1) = mltval; 5046 5047 move MLTVAL(A6),0xA(A_FPU) 5048 5049 | ++octype; 5050 5051 5051 add #1,OCTYPE(A6) 5052 * 5053 * *(fpu + (long)FPU_TMNT) = fpmant;5054 * 5055 move R_FPMANT, $14(A_FPU)5056 * 5057 *++octype;5058 * 5052 5053 | |(fpu + (long)FPU_TMNT) = fpmant; 5054 5055 move R_FPMANT,0x14(A_FPU) 5056 5057 | ++octype; 5058 5059 5059 add #1,OCTYPE(A6) 5060 * 5061 * *(fpu + (long)FPU_TEXP) = fpexp;5062 * 5063 move R_FPEXP, $16(A_FPU)5064 * 5065 *++octype;5066 * 5060 5061 | |(fpu + (long)FPU_TEXP) = fpexp; 5062 5063 move R_FPEXP,0x16(A_FPU) 5064 5065 | ++octype; 5066 5067 5067 add #1,OCTYPE(A6) 5068 * 5069 .page 5070 * 5071 *if (fp->idftmd & I_VNSUBN)5072 * 5068 5069 .page 5070 5071 | if (fp->idftmd & I_VNSUBN) 5072 5073 5073 btst #3,7(A_FP) 5074 5074 beq F08L169 5075 * 5076 * *(fpu + (long)FPU_TNV1) = fpval;5077 * 5078 move R_FPVAL, $1C(A_FPU)5075 5076 | |(fpu + (long)FPU_TNV1) = fpval; 5077 5078 move R_FPVAL,0x1C(A_FPU) 5079 5079 bra F08L170 5080 * 5081 *else5082 * *(fpu + (long)FPU_TNV0) = fpval;5083 * 5080 5081 | else 5082 | |(fpu + (long)FPU_TNV0) = fpval; 5083 5084 5084 F08L169: move R_FPVAL,2(A_FPU) 5085 * 5086 *++octype;5087 * 5085 5086 | ++octype; 5087 5088 5088 F08L170: add #1,OCTYPE(A6) 5089 * 5090 * *(fpu + (long)FPU_TCTL) = fpctl;5091 * 5089 5090 | |(fpu + (long)FPU_TCTL) = fpctl; 5091 5092 5092 move R_FPCTL,(A_FPU) 5093 * 5094 *setipl(oldi);5095 * 5093 5094 | setipl(oldi); 5095 5096 5096 move OLDI(A6),sr 5097 * 5098 .page 5099 *------------------------------------------------------------------------------5100 *Start function 9 -- Ind 45101 *------------------------------------------------------------------------------5102 * 5103 *if (ip->idhfnc[9].idftmd & I_TM_KEY) {5104 * 5097 5098 .page 5099 | ------------------------------------------------------------------------------ 5100 | Start function 9 -- Ind 4 5101 | ------------------------------------------------------------------------------ 5102 5103 | if (ip->idhfnc[9].idftmd & I_TM_KEY) { 5104 5105 5105 FN09: move.l IP(A6),A0 5106 5106 move.b 201(A0),D0 … … 5109 5109 btst #0,D0 5110 5110 bne FN09A 5111 * 5111 5112 5112 jmp FN10 5113 * 5114 *vp = (vce << 4) + 13;5115 * 5113 5114 | vp = (vce << 4) + 13; 5115 5116 5116 FN09A: move VCE(A6),D0 5117 5117 asl #4,D0 5118 5118 add.w #13,D0 5119 5119 move D0,VP(A6) 5120 * 5121 *fpu = io_fpu + FPU_OFNC + (vp << 4);5122 * 5120 5121 | fpu = io_fpu + FPU_OFNC + (vp << 4); 5122 5123 5123 asl #5,D0 5124 5124 ext.l D0 5125 5125 move.l D0,A_FPU 5126 add.l #_io_fpu+ $4000,A_FPU5127 * 5128 *fp = &ip->idhfnc[9];5129 * 5126 add.l #_io_fpu+0x4000,A_FPU 5127 5128 | fp = &ip->idhfnc[9]; 5129 5130 5130 move.l #108,A_FP 5131 5131 add.l IP(A6),A_FP 5132 5132 add.l #86,A_FP 5133 * 5134 *pt = &ip->idhpnt[fp->idfpt1];5135 * 5133 5134 | pt = &ip->idhpnt[fp->idfpt1]; 5135 5136 5136 clr.l D0 5137 5137 move.b 6(A_FP),D0 … … 5143 5143 add.l #242,D0 5144 5144 move.l D0,PT(A6) 5145 * 5146 .page 5147 * 5148 *srcnum = group | fp->idfsrc;5149 * 5145 5146 .page 5147 5148 | srcnum = group | fp->idfsrc; 5149 5150 5150 move.w GROUP(A6),D0 5151 5151 ext.l D0 … … 5154 5154 or D1,D0 5155 5155 move D0,SRCNUM(A6) 5156 * 5157 *vep = &valents[srcnum];5158 * 5156 5157 | vep = &valents[srcnum]; 5158 5159 5159 add.l D0,D0 5160 5160 move.l D0,D1 … … 5163 5163 add.l #_valents,D0 5164 5164 move.l D0,VEP(A6) 5165 * 5166 *smp = vpsms[vp];5167 * 5165 5166 | smp = vpsms[vp]; 5167 5168 5168 move VP(A6),A0 5169 5169 add.l A0,A0 … … 5171 5171 add.l #_vpsms,A0 5172 5172 move.l (A0),A_SMP 5173 * 5174 *if (srcnum NE smp->sm) {5175 * 5173 5174 | if (srcnum NE smp->sm) { 5175 5176 5176 clr D0 5177 5177 move 10(A_SMP),D0 5178 5178 cmp SRCNUM(A6),D0 5179 5179 beq F09L113 5180 * 5181 *(smp->prv)->nxt = smp->nxt;5182 * 5180 5181 | (smp->prv)->nxt = smp->nxt; 5182 5183 5183 move.l 4(A_SMP),A0 5184 5184 move.l (A_SMP),(A0) 5185 * 5186 *(smp->nxt)->prv = smp->prv;5187 * 5185 5186 | (smp->nxt)->prv = smp->prv; 5187 5188 5188 move.l (A_SMP),A0 5189 5189 move.l 4(A_SMP),4(A0) 5190 * 5191 * smp->prv = (struct sment *)vep;5192 * 5190 5191 | smp->prv = (struct sment |)vep; 5192 5193 5193 move.l VEP(A6),4(A_SMP) 5194 * 5195 *smp->nxt = vep->nxt;5196 * 5194 5195 | smp->nxt = vep->nxt; 5196 5197 5197 move.l VEP(A6),A0 5198 5198 move.l (A0),(A_SMP) 5199 * 5200 *(vep->nxt)->prv = smp;5201 * 5199 5200 | (vep->nxt)->prv = smp; 5201 5202 5202 move.l VEP(A6),A0 5203 5203 move.l (A0),A0 5204 5204 move.l A_SMP,4(A0) 5205 * 5206 *vep->nxt = smp;5207 * 5205 5206 | vep->nxt = smp; 5207 5208 5208 move.l VEP(A6),A0 5209 5209 move.l A_SMP,(A0) 5210 * 5211 *smp->sm = srcnum;5212 * 5210 5211 | smp->sm = srcnum; 5212 5213 5213 move SRCNUM(A6),10(A_SMP) 5214 * 5215 *}5216 * 5217 *mltval = fp->idfmlt;5218 * 5214 5215 | } 5216 5217 | mltval = fp->idfmlt; 5218 5219 5219 F09L113: move 2(A_FP),MLTVAL(A6) 5220 * 5221 .page 5222 * 5223 *switch (fp->idfsrc) {5224 * 5220 5221 .page 5222 5223 | switch (fp->idfsrc) { 5224 5225 5225 move.b 4(A_FP),D0 5226 5226 ext.w d0 5227 5227 cmp #10,D0 5228 5228 bhi F09L122 5229 * 5229 5230 5230 asl #2,D0 5231 5231 lea F09L123,A0 5232 5232 movea.l 0(A0,D0.W),A0 5233 5233 jmp (A0) 5234 * 5235 *case SM_NONE:5236 *mltval = 0;5237 * 5234 5235 | case SM_NONE: 5236 | mltval = 0; 5237 5238 5238 F09L116: clr MLTVAL(A6) 5239 * 5240 *tsrcval = 0;5241 * 5239 5240 | tsrcval = 0; 5241 5242 5242 clr TSRCVAL(A6) 5243 * 5244 *break;5245 * 5243 5244 | break; 5245 5246 5246 bra F09L114 5247 * 5248 *case SM_RAND:5249 *tsrcval = xgetran(mltval);5250 * 5247 5248 | case SM_RAND: 5249 | tsrcval = xgetran(mltval); 5250 5251 5251 F09L117: move MLTVAL(A6),(sp) 5252 5252 jsr _xgetran 5253 5253 move D0,TSRCVAL(A6) 5254 * 5255 *break;5256 * 5254 5255 | break; 5256 5257 5257 bra F09L114 5258 * 5259 *case SM_PTCH:5260 *tsrcval = pch;5261 * 5258 5259 | case SM_PTCH: 5260 | tsrcval = pch; 5261 5262 5262 F09L118: move PCH(A6),TSRCVAL(A6) 5263 * 5264 *break;5265 * 5263 5264 | break; 5265 5266 5266 bra F09L114 5267 * 5268 .page 5269 * 5270 *case SM_FREQ:5271 *tsrcval = ptoftab[(pch >> 7) & 0x00FF];5272 * 5267 5268 .page 5269 5270 | case SM_FREQ: 5271 | tsrcval = ptoftab[(pch >> 7) & 0x00FF]; 5272 5273 5273 F09L119: move PCH(A6),D0 5274 5274 asr #7,D0 … … 5278 5278 add.l #_ptoftab,A0 5279 5279 move (A0),TSRCVAL(A6) 5280 * 5281 *break;5282 * 5280 5281 | break; 5282 5283 5283 bra F09L114 5284 * 5285 *case SM_KVEL:5286 *tsrcval = veltab[trg];5287 * 5284 5285 | case SM_KVEL: 5286 | tsrcval = veltab[trg]; 5287 5288 5288 F09L120: move TRG(A6),A0 5289 5289 add.l A0,A0 5290 5290 add.l #_veltab,A0 5291 5291 move (A0),TSRCVAL(A6) 5292 * 5293 *break;5294 * 5292 5293 | break; 5294 5295 5295 bra F09L114 5296 * 5297 *case SM_KPRS:5298 *tsrcval = prstab[trg];5299 * 5296 5297 | case SM_KPRS: 5298 | tsrcval = prstab[trg]; 5299 5300 5300 F09L121: move TRG(A6),A0 5301 5301 add.l A0,A0 5302 5302 add.l #_prstab,A0 5303 5303 move (A0),TSRCVAL(A6) 5304 * 5305 *break;5306 * 5304 5305 | break; 5306 5307 5307 bra F09L114 5308 * 5309 *default:5310 *tsrcval = vep->val;5311 * 5308 5309 | default: 5310 | tsrcval = vep->val; 5311 5312 5312 F09L122: move.l VEP(A6),A0 5313 5313 move 8(A0),TSRCVAL(A6) 5314 * 5315 *}5316 * 5317 .page 5318 * 5319 *srcval = tsrcval;5320 * 5314 5315 | } 5316 5317 .page 5318 5319 | srcval = tsrcval; 5320 5321 5321 F09L114: move TSRCVAL(A6),SRCVAL(A6) 5322 * 5323 .page 5324 * 5325 *if (pt->ipvsrc) {5326 * 5322 5323 .page 5324 5325 | if (pt->ipvsrc) { 5326 5327 5327 F09L124: move.l PT(A6),A0 5328 5328 tst.b 6(A0) 5329 5329 beq F09L136 5330 * 5331 *switch (pt->ipvsrc) {5332 * 5330 5331 | switch (pt->ipvsrc) { 5332 5333 5333 move.l PT(A6),A0 5334 5334 move.b 6(A0),D0 … … 5337 5337 cmp #9,D0 5338 5338 bhi F09L144 5339 * 5339 5340 5340 asl #2,D0 5341 5341 lea F09L145,A0 5342 5342 move.l 0(A0,D0.W),A0 5343 5343 jmp (A0) 5344 * 5345 *case SM_RAND:5346 *ltmp = xgetran(pt_>ipvmlt);5347 * 5344 5345 | case SM_RAND: 5346 | ltmp = xgetran(pt_>ipvmlt); 5347 5348 5348 F09L139: move.l PT(A6),A0 5349 5349 move 4(A0),(sp) … … 5351 5351 ext.l D0 5352 5352 move.l D0,LTMP(A6) 5353 * 5354 *break;5355 * 5353 5354 | break; 5355 5356 5356 bra F09L137 5357 * 5358 *case SM_PTCH:5359 *ltmp = pch;5360 * 5357 5358 | case SM_PTCH: 5359 | ltmp = pch; 5360 5361 5361 F09L140: move PCH(A6),A0 5362 5362 move.l A0,LTMP(A6) 5363 * 5364 *break;5365 * 5363 5364 | break; 5365 5366 5366 bra F09L137 5367 * 5368 .page 5369 * 5370 *case SM_FREQ:5371 *ltmp = ptoftab[(pch >> 7) & 0x00FF];5372 * 5367 5368 .page 5369 5370 | case SM_FREQ: 5371 | ltmp = ptoftab[(pch >> 7) & 0x00FF]; 5372 5373 5373 F09L141: move PCH(A6),D0 5374 5374 asr #7,D0 … … 5380 5380 ext.l D0 5381 5381 move.l D0,LTMP(A6) 5382 * 5383 *break;5384 * 5382 5383 | break; 5384 5385 5385 bra F09L137 5386 * 5387 *case SM_KVEL:5388 *ltmp = veltab[trg];5389 * 5386 5387 | case SM_KVEL: 5388 | ltmp = veltab[trg]; 5389 5390 5390 F09L142: move TRG(A6),A0 5391 5391 add.l A0,A0 … … 5394 5394 ext.l D0 5395 5395 move.l D0,LTMP(A6) 5396 * 5397 *break;5398 * 5396 5397 | break; 5398 5399 5399 bra F09L137 5400 * 5401 .page 5402 * 5403 *case SM_KPRS:5404 *ltmp = prstab[trg];5405 * 5400 5401 .page 5402 5403 | case SM_KPRS: 5404 | ltmp = prstab[trg]; 5405 5406 5406 F09L143: move TRG(A6),A0 5407 5407 add.l A0,A0 … … 5410 5410 ext.l D0 5411 5411 move.l D0,LTMP(A6) 5412 * 5413 *break;5414 * 5412 5413 | break; 5414 5415 5415 bra F09L137 5416 * 5417 .page 5418 * 5419 *default:5420 *ltmp = valents[group | pt->ipvsrc].val;5421 * 5416 5417 .page 5418 5419 | default: 5420 | ltmp = valents[group | pt->ipvsrc].val; 5421 5422 5422 F09L144: move.l PT(A6),A0 5423 5423 clr.l D0 … … 5433 5433 move 8(A0,A1.l),D0 5434 5434 move.l D0,LTMP(A6) 5435 * 5436 *}5437 * 5438 * 5439 .page 5440 * 5441 * ltmp = (ltmp *pt->ipvmlt) >> 15;5442 * 5435 5436 | } 5437 5438 5439 .page 5440 5441 | ltmp = (ltmp | pt->ipvmlt) >> 15; 5442 5443 5443 F09L137: move.l PT(A6),A0 5444 5444 move.w 4(A0),D0 … … 5448 5448 asr.l D1,D0 5449 5449 move.l D0,LTMP(A6) 5450 * 5451 *ltmp += (long)pt->ipval;5452 * 5450 5451 | ltmp += (long)pt->ipval; 5452 5453 5453 move.l PT(A6),A0 5454 5454 move 2(A0),D0 5455 5455 ext.l D0 5456 5456 add.l D0,LTMP(A6) 5457 * 5458 *if (ltmp GT (long)VALMAX)5459 *ltmp = (long)VALMAX;5460 * 5457 5458 | if (ltmp GT (long)VALMAX) 5459 | ltmp = (long)VALMAX; 5460 5461 5461 cmp.l #VALMAX,LTMP(A6) 5462 5462 ble F09L146 5463 * 5463 5464 5464 move.l #VALMAX,LTMP(A6) 5465 5465 bra F09L147 5466 * 5467 *else if (ltmp LT (long)VALMIN)5468 *ltmp = (long)VALMIN;5469 * 5466 5467 | else if (ltmp LT (long)VALMIN) 5468 | ltmp = (long)VALMIN; 5469 5470 5470 F09L146: cmp.l #VALMIN,LTMP(A6) 5471 5471 bge F09L147 5472 * 5472 5473 5473 move.l #VALMIN,LTMP(A6) 5474 * 5475 *tfpval = (short)ltmp;5476 * 5474 5475 | tfpval = (short)ltmp; 5476 5477 5477 F09L147: move.w LTMP+2(A6),TFPVAL(A6) 5478 5478 bra F09L149 5479 * 5480 *} else {5481 * 5482 *tfpval = pt->ipval;5483 * 5479 5480 | } else { 5481 5482 | tfpval = pt->ipval; 5483 5484 5484 F09L136: move.l PT(A6),A0 5485 5485 move 2(A0),TFPVAL(A6) 5486 * 5487 *}5488 * 5489 .page 5490 * 5491 *fpmant = (((long)pt->iptom & 0x0000FFF0L)5492 * *((long)timemlt & 0x0000FFFFL)) >> 15;5493 * 5486 5487 | } 5488 5489 .page 5490 5491 | fpmant = (((long)pt->iptom & 0x0000FFF0L) 5492 | | ((long)timemlt & 0x0000FFFFL)) >> 15; 5493 5494 5494 F09L149: move.l PT(A6),A0 5495 5495 move.w (A0),D0 5496 5496 move.w D0,D2 5497 andi.w # $FFF0,D05497 andi.w #0xFFF0,D0 5498 5498 move.w _timemlt,D1 5499 5499 muls D1,D0 … … 5501 5501 asr.l D1,D0 5502 5502 move D0,R_FPMANT 5503 * 5504 *fpexp = expbit[pt->iptim & 0x000F];5505 * 5506 and # $000F,D25503 5504 | fpexp = expbit[pt->iptim & 0x000F]; 5505 5506 and #0x000F,D2 5507 5507 move D2,A0 5508 5508 add.l A0,A0 5509 5509 add.l #_expbit,A0 5510 5510 move (A0),R_FPEXP 5511 * 5512 .page 5513 * 5514 *fp->idfpch = pch;5515 * 5511 5512 .page 5513 5514 | fp->idfpch = pch; 5515 5516 5516 F09L163: move PCH(A6),(A_FP) 5517 * 5518 *fpval = tfpval;5519 * 5517 5518 | fpval = tfpval; 5519 5520 5520 move TFPVAL(A6),R_FPVAL 5521 * 5522 .page 5523 * 5521 5522 .page 5523 5524 5524 move.b 5(A_FP),D0 5525 5525 ext.w D0 5526 5526 sub.w #1,D0 5527 5527 movea.l PT(A6),A0 5528 * 5529 *oldi = setipl(FPU_DI);5530 * 5528 5529 | oldi = setipl(FPU_DI); 5530 5531 5531 move sr,OLDI(A6) 5532 5532 move #FPU_DI,sr 5533 * 5533 5534 5534 F09L168: clr.b 10(A0) 5535 5535 add.l #12,a0 5536 5536 dbra D0,F09L168 5537 * 5538 .page 5539 * 5540 *fp->idftmd ^= I_NVBITS;5541 * 5537 5538 .page 5539 5540 | fp->idftmd ^= I_NVBITS; 5541 5542 5542 F09L165: eor.b #24,7(A_FP) 5543 * 5544 *fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;5545 * 5543 5544 | fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003; 5545 5546 5546 move.b 7(A_FP),R_FPCTL 5547 5547 and #28,R_FPCTL 5548 5548 or #3,R_FPCTL 5549 * 5550 *fp->idfcpt = fp->idfpt1;5551 * 5549 5550 | fp->idfcpt = fp->idfpt1; 5551 5552 5552 move.b 6(A_FP),8(A_FP) 5553 * 5554 *fp->idftmd |= I_ACTIVE;5555 * 5553 5554 | fp->idftmd |= I_ACTIVE; 5555 5556 5556 or.b #2,7(A_FP) 5557 * 5558 *fp->idftrf = trg;5559 * 5557 5558 | fp->idftrf = trg; 5559 5560 5560 move TRG(A6),10(A_FP) 5561 * 5562 * *(fpu + (long)FPU_TCV1) = srcval;5563 * 5564 move SRCVAL(A6), $8(A_FPU)5565 * 5566 *++octype;5567 * 5561 5562 | |(fpu + (long)FPU_TCV1) = srcval; 5563 5564 move SRCVAL(A6),0x8(A_FPU) 5565 5566 | ++octype; 5567 5568 5568 add #1,OCTYPE(A6) 5569 * 5570 * *(fpu + (long)FPU_TSF1) = mltval;5571 * 5572 move MLTVAL(A6), $A(A_FPU)5573 * 5574 *++octype;5575 * 5569 5570 | |(fpu + (long)FPU_TSF1) = mltval; 5571 5572 move MLTVAL(A6),0xA(A_FPU) 5573 5574 | ++octype; 5575 5576 5576 add #1,OCTYPE(A6) 5577 * 5578 * *(fpu + (long)FPU_TMNT) = fpmant;5579 * 5580 move R_FPMANT, $14(A_FPU)5581 * 5582 *++octype;5583 * 5577 5578 | |(fpu + (long)FPU_TMNT) = fpmant; 5579 5580 move R_FPMANT,0x14(A_FPU) 5581 5582 | ++octype; 5583 5584 5584 add #1,OCTYPE(A6) 5585 * 5586 * *(fpu + (long)FPU_TEXP) = fpexp;5587 * 5588 move R_FPEXP, $16(A_FPU)5589 * 5590 *++octype;5591 * 5585 5586 | |(fpu + (long)FPU_TEXP) = fpexp; 5587 5588 move R_FPEXP,0x16(A_FPU) 5589 5590 | ++octype; 5591 5592 5592 add #1,OCTYPE(A6) 5593 * 5594 .page 5595 * 5596 *if (fp->idftmd & I_VNSUBN)5597 * 5593 5594 .page 5595 5596 | if (fp->idftmd & I_VNSUBN) 5597 5598 5598 btst #3,7(A_FP) 5599 5599 beq F09L169 5600 * 5601 * *(fpu + (long)FPU_TNV1) = fpval;5602 * 5603 move R_FPVAL, $1C(A_FPU)5600 5601 | |(fpu + (long)FPU_TNV1) = fpval; 5602 5603 move R_FPVAL,0x1C(A_FPU) 5604 5604 bra F09L170 5605 * 5606 *else5607 * *(fpu + (long)FPU_TNV0) = fpval;5608 * 5605 5606 | else 5607 | |(fpu + (long)FPU_TNV0) = fpval; 5608 5609 5609 F09L169: move R_FPVAL,2(A_FPU) 5610 * 5611 *++octype;5612 * 5610 5611 | ++octype; 5612 5613 5613 F09L170: add #1,OCTYPE(A6) 5614 * 5615 * *(fpu + (long)FPU_TCTL) = fpctl;5616 * 5614 5615 | |(fpu + (long)FPU_TCTL) = fpctl; 5616 5617 5617 move R_FPCTL,(A_FPU) 5618 * 5619 *setipl(oldi);5620 * 5618 5619 | setipl(oldi); 5620 5621 5621 move OLDI(A6),sr 5622 * 5623 .page 5624 *------------------------------------------------------------------------------5625 *Start function 10 -- Ind 55626 *------------------------------------------------------------------------------5627 * 5628 *if (ip->idhfnc[10].idftmd & I_TM_KEY) {5629 * 5622 5623 .page 5624 | ------------------------------------------------------------------------------ 5625 | Start function 10 -- Ind 5 5626 | ------------------------------------------------------------------------------ 5627 5628 | if (ip->idhfnc[10].idftmd & I_TM_KEY) { 5629 5630 5630 FN10: move.l IP(A6),A0 5631 5631 move.b 213(A0),D0 … … 5634 5634 btst #0,D0 5635 5635 bne FN10A 5636 * 5636 5637 5637 jmp FN11 5638 * 5639 *vp = (vce << 4) + 14;5640 * 5638 5639 | vp = (vce << 4) + 14; 5640 5641 5641 FN10A: move VCE(A6),D0 5642 5642 asl #4,D0 5643 5643 add.w #14,D0 5644 5644 move D0,VP(A6) 5645 * 5646 *fpu = io_fpu + FPU_OFNC + (vp << 4);5647 * 5645 5646 | fpu = io_fpu + FPU_OFNC + (vp << 4); 5647 5648 5648 asl #5,D0 5649 5649 ext.l D0 5650 5650 move.l D0,A_FPU 5651 add.l #_io_fpu+ $4000,A_FPU5652 * 5653 *fp = &ip->idhfnc[10];5654 * 5651 add.l #_io_fpu+0x4000,A_FPU 5652 5653 | fp = &ip->idhfnc[10]; 5654 5655 5655 move.l #120,A_FP 5656 5656 add.l IP(A6),A_FP 5657 5657 add.l #86,A_FP 5658 * 5659 *pt = &ip->idhpnt[fp->idfpt1];5660 * 5658 5659 | pt = &ip->idhpnt[fp->idfpt1]; 5660 5661 5661 clr.l D0 5662 5662 move.b 6(A_FP),D0 … … 5668 5668 add.l #242,D0 5669 5669 move.l D0,PT(A6) 5670 * 5671 .page 5672 * 5673 *srcnum = group | fp->idfsrc;5674 * 5670 5671 .page 5672 5673 | srcnum = group | fp->idfsrc; 5674 5675 5675 move.w GROUP(A6),D0 5676 5676 ext.l D0 … … 5679 5679 or D1,D0 5680 5680 move D0,SRCNUM(A6) 5681 * 5682 *vep = &valents[srcnum];5683 * 5681 5682 | vep = &valents[srcnum]; 5683 5684 5684 add.l D0,D0 5685 5685 move.l D0,D1 … … 5688 5688 add.l #_valents,D0 5689 5689 move.l D0,VEP(A6) 5690 * 5691 *smp = vpsms[vp];5692 * 5690 5691 | smp = vpsms[vp]; 5692 5693 5693 move VP(A6),A0 5694 5694 add.l A0,A0 … … 5696 5696 add.l #_vpsms,A0 5697 5697 move.l (A0),A_SMP 5698 * 5699 *if (srcnum NE smp->sm) {5700 * 5698 5699 | if (srcnum NE smp->sm) { 5700 5701 5701 clr D0 5702 5702 move 10(A_SMP),D0 5703 5703 cmp SRCNUM(A6),D0 5704 5704 beq F10L113 5705 * 5706 *(smp->prv)->nxt = smp->nxt;5707 * 5705 5706 | (smp->prv)->nxt = smp->nxt; 5707 5708 5708 move.l 4(A_SMP),A0 5709 5709 move.l (A_SMP),(A0) 5710 * 5711 *(smp->nxt)->prv = smp->prv;5712 * 5710 5711 | (smp->nxt)->prv = smp->prv; 5712 5713 5713 move.l (A_SMP),A0 5714 5714 move.l 4(A_SMP),4(A0) 5715 * 5716 * smp->prv = (struct sment *)vep;5717 * 5715 5716 | smp->prv = (struct sment |)vep; 5717 5718 5718 move.l VEP(A6),4(A_SMP) 5719 * 5720 *smp->nxt = vep->nxt;5721 * 5719 5720 | smp->nxt = vep->nxt; 5721 5722 5722 move.l VEP(A6),A0 5723 5723 move.l (A0),(A_SMP) 5724 * 5725 *(vep->nxt)->prv = smp;5726 * 5724 5725 | (vep->nxt)->prv = smp; 5726 5727 5727 move.l VEP(A6),A0 5728 5728 move.l (A0),A0 5729 5729 move.l A_SMP,4(A0) 5730 * 5731 *vep->nxt = smp;5732 * 5730 5731 | vep->nxt = smp; 5732 5733 5733 move.l VEP(A6),A0 5734 5734 move.l A_SMP,(A0) 5735 * 5736 *smp->sm = srcnum;5737 * 5735 5736 | smp->sm = srcnum; 5737 5738 5738 move SRCNUM(A6),10(A_SMP) 5739 * 5740 *}5741 * 5742 *mltval = fp->idfmlt;5743 * 5739 5740 | } 5741 5742 | mltval = fp->idfmlt; 5743 5744 5744 F10L113: move 2(A_FP),MLTVAL(A6) 5745 * 5746 .page 5747 * 5748 *switch (fp->idfsrc) {5749 * 5745 5746 .page 5747 5748 | switch (fp->idfsrc) { 5749 5750 5750 move.b 4(A_FP),D0 5751 5751 ext.w d0 5752 5752 cmp #10,D0 5753 5753 bhi F10L122 5754 * 5754 5755 5755 asl #2,D0 5756 5756 lea F10L123,A0 5757 5757 movea.l 0(A0,D0.W),A0 5758 5758 jmp (A0) 5759 * 5760 *case SM_NONE:5761 *mltval = 0;5762 * 5759 5760 | case SM_NONE: 5761 | mltval = 0; 5762 5763 5763 F10L116: clr MLTVAL(A6) 5764 * 5765 *tsrcval = 0;5766 * 5764 5765 | tsrcval = 0; 5766 5767 5767 clr TSRCVAL(A6) 5768 * 5769 *break;5770 * 5768 5769 | break; 5770 5771 5771 bra F10L114 5772 * 5773 *case SM_RAND:5774 *tsrcval = xgetran(mltval);5775 * 5772 5773 | case SM_RAND: 5774 | tsrcval = xgetran(mltval); 5775 5776 5776 F10L117: move MLTVAL(A6),(sp) 5777 5777 jsr _xgetran 5778 5778 move D0,TSRCVAL(A6) 5779 * 5780 *break;5781 * 5779 5780 | break; 5781 5782 5782 bra F10L114 5783 * 5784 *case SM_PTCH:5785 *tsrcval = pch;5786 * 5783 5784 | case SM_PTCH: 5785 | tsrcval = pch; 5786 5787 5787 F10L118: move PCH(A6),TSRCVAL(A6) 5788 * 5789 *break;5790 * 5788 5789 | break; 5790 5791 5791 bra F10L114 5792 * 5793 .page 5794 * 5795 *case SM_FREQ:5796 *tsrcval = ptoftab[(pch >> 7) & 0x00FF];5797 * 5792 5793 .page 5794 5795 | case SM_FREQ: 5796 | tsrcval = ptoftab[(pch >> 7) & 0x00FF]; 5797 5798 5798 F10L119: move PCH(A6),D0 5799 5799 asr #7,D0 … … 5803 5803 add.l #_ptoftab,A0 5804 5804 move (A0),TSRCVAL(A6) 5805 * 5806 *break;5807 * 5805 5806 | break; 5807 5808 5808 bra F10L114 5809 * 5810 *case SM_KVEL:5811 *tsrcval = veltab[trg];5812 * 5809 5810 | case SM_KVEL: 5811 | tsrcval = veltab[trg]; 5812 5813 5813 F10L120: move TRG(A6),A0 5814 5814 add.l A0,A0 5815 5815 add.l #_veltab,A0 5816 5816 move (A0),TSRCVAL(A6) 5817 * 5818 *break;5819 * 5817 5818 | break; 5819 5820 5820 bra F10L114 5821 * 5822 *case SM_KPRS:5823 *tsrcval = prstab[trg];5824 * 5821 5822 | case SM_KPRS: 5823 | tsrcval = prstab[trg]; 5824 5825 5825 F10L121: move TRG(A6),A0 5826 5826 add.l A0,A0 5827 5827 add.l #_prstab,A0 5828 5828 move (A0),TSRCVAL(A6) 5829 * 5830 *break;5831 * 5829 5830 | break; 5831 5832 5832 bra F10L114 5833 * 5834 *default:5835 *tsrcval = vep->val;5836 * 5833 5834 | default: 5835 | tsrcval = vep->val; 5836 5837 5837 F10L122: move.l VEP(A6),A0 5838 5838 move 8(A0),TSRCVAL(A6) 5839 * 5840 *}5841 * 5842 .page 5843 * 5844 *srcval = tsrcval;5845 * 5839 5840 | } 5841 5842 .page 5843 5844 | srcval = tsrcval; 5845 5846 5846 F10L114: move TSRCVAL(A6),SRCVAL(A6) 5847 * 5848 .page 5849 * 5850 *if (pt->ipvsrc) {5851 * 5847 5848 .page 5849 5850 | if (pt->ipvsrc) { 5851 5852 5852 F10L124: move.l PT(A6),A0 5853 5853 tst.b 6(A0) 5854 5854 beq F10L136 5855 * 5856 *switch (pt->ipvsrc) {5857 * 5855 5856 | switch (pt->ipvsrc) { 5857 5858 5858 move.l PT(A6),A0 5859 5859 move.b 6(A0),D0 … … 5862 5862 cmp #9,D0 5863 5863 bhi F10L144 5864 * 5864 5865 5865 asl #2,D0 5866 5866 lea F10L145,A0 5867 5867 move.l 0(A0,D0.W),A0 5868 5868 jmp (A0) 5869 * 5870 *case SM_RAND:5871 *ltmp = xgetran(pt_>ipvmlt);5872 * 5869 5870 | case SM_RAND: 5871 | ltmp = xgetran(pt_>ipvmlt); 5872 5873 5873 F10L139: move.l PT(A6),A0 5874 5874 move 4(A0),(sp) … … 5876 5876 ext.l D0 5877 5877 move.l D0,LTMP(A6) 5878 * 5879 *break;5880 * 5878 5879 | break; 5880 5881 5881 bra F10L137 5882 * 5883 *case SM_PTCH:5884 *ltmp = pch;5885 * 5882 5883 | case SM_PTCH: 5884 | ltmp = pch; 5885 5886 5886 F10L140: move PCH(A6),A0 5887 5887 move.l A0,LTMP(A6) 5888 * 5889 *break;5890 * 5888 5889 | break; 5890 5891 5891 bra F10L137 5892 * 5893 .page 5894 * 5895 *case SM_FREQ:5896 *ltmp = ptoftab[(pch >> 7) & 0x00FF];5897 * 5892 5893 .page 5894 5895 | case SM_FREQ: 5896 | ltmp = ptoftab[(pch >> 7) & 0x00FF]; 5897 5898 5898 F10L141: move PCH(A6),D0 5899 5899 asr #7,D0 … … 5905 5905 ext.l D0 5906 5906 move.l D0,LTMP(A6) 5907 * 5908 *break;5909 * 5907 5908 | break; 5909 5910 5910 bra F10L137 5911 * 5912 *case SM_KVEL:5913 *ltmp = veltab[trg];5914 * 5911 5912 | case SM_KVEL: 5913 | ltmp = veltab[trg]; 5914 5915 5915 F10L142: move TRG(A6),A0 5916 5916 add.l A0,A0 … … 5919 5919 ext.l D0 5920 5920 move.l D0,LTMP(A6) 5921 * 5922 *break;5923 * 5921 5922 | break; 5923 5924 5924 bra F10L137 5925 * 5926 .page 5927 * 5928 *case SM_KPRS:5929 *ltmp = prstab[trg];5930 * 5925 5926 .page 5927 5928 | case SM_KPRS: 5929 | ltmp = prstab[trg]; 5930 5931 5931 F10L143: move TRG(A6),A0 5932 5932 add.l A0,A0 … … 5935 5935 ext.l D0 5936 5936 move.l D0,LTMP(A6) 5937 * 5938 *break;5939 * 5937 5938 | break; 5939 5940 5940 bra F10L137 5941 * 5942 .page 5943 * 5944 *default:5945 *ltmp = valents[group | pt->ipvsrc].val;5946 * 5941 5942 .page 5943 5944 | default: 5945 | ltmp = valents[group | pt->ipvsrc].val; 5946 5947 5947 F10L144: move.l PT(A6),A0 5948 5948 clr.l D0 … … 5958 5958 move 8(A0,A1.l),D0 5959 5959 move.l D0,LTMP(A6) 5960 * 5961 *}5962 * 5963 * 5964 .page 5965 * 5966 * ltmp = (ltmp *pt->ipvmlt) >> 15;5967 * 5960 5961 | } 5962 5963 5964 .page 5965 5966 | ltmp = (ltmp | pt->ipvmlt) >> 15; 5967 5968 5968 F10L137: move.l PT(A6),A0 5969 5969 move.w 4(A0),D0 … … 5973 5973 asr.l D1,D0 5974 5974 move.l D0,LTMP(A6) 5975 * 5976 *ltmp += (long)pt->ipval;5977 * 5975 5976 | ltmp += (long)pt->ipval; 5977 5978 5978 move.l PT(A6),A0 5979 5979 move 2(A0),D0 5980 5980 ext.l D0 5981 5981 add.l D0,LTMP(A6) 5982 * 5983 *if (ltmp GT (long)VALMAX)5984 *ltmp = (long)VALMAX;5985 * 5982 5983 | if (ltmp GT (long)VALMAX) 5984 | ltmp = (long)VALMAX; 5985 5986 5986 cmp.l #VALMAX,LTMP(A6) 5987 5987 ble F10L146 5988 * 5988 5989 5989 move.l #VALMAX,LTMP(A6) 5990 5990 bra F10L147 5991 * 5992 *else if (ltmp LT (long)VALMIN)5993 *ltmp = (long)VALMIN;5994 * 5991 5992 | else if (ltmp LT (long)VALMIN) 5993 | ltmp = (long)VALMIN; 5994 5995 5995 F10L146: cmp.l #VALMIN,LTMP(A6) 5996 5996 bge F10L147 5997 * 5997 5998 5998 move.l #VALMIN,LTMP(A6) 5999 * 6000 *tfpval = (short)ltmp;6001 * 5999 6000 | tfpval = (short)ltmp; 6001 6002 6002 F10L147: move.w LTMP+2(A6),TFPVAL(A6) 6003 6003 bra F10L149 6004 * 6005 *} else {6006 * 6007 *tfpval = pt->ipval;6008 * 6004 6005 | } else { 6006 6007 | tfpval = pt->ipval; 6008 6009 6009 F10L136: move.l PT(A6),A0 6010 6010 move 2(A0),TFPVAL(A6) 6011 * 6012 *}6013 * 6014 .page 6015 * 6016 *fpmant = (((long)pt->iptom & 0x0000FFF0L)6017 * *((long)timemlt & 0x0000FFFFL)) >> 15;6018 * 6011 6012 | } 6013 6014 .page 6015 6016 | fpmant = (((long)pt->iptom & 0x0000FFF0L) 6017 | | ((long)timemlt & 0x0000FFFFL)) >> 15; 6018 6019 6019 F10L149: move.l PT(A6),A0 6020 6020 move.w (A0),D0 6021 6021 move.w D0,D2 6022 andi.w # $FFF0,D06022 andi.w #0xFFF0,D0 6023 6023 move.w _timemlt,D1 6024 6024 muls D1,D0 … … 6026 6026 asr.l D1,D0 6027 6027 move D0,R_FPMANT 6028 * 6029 *fpexp = expbit[pt->iptim & 0x000F];6030 * 6031 and # $000F,D26028 6029 | fpexp = expbit[pt->iptim & 0x000F]; 6030 6031 and #0x000F,D2 6032 6032 move D2,A0 6033 6033 add.l A0,A0 6034 6034 add.l #_expbit,A0 6035 6035 move (A0),R_FPEXP 6036 * 6037 .page 6038 * 6039 *fp->idfpch = pch;6040 * 6036 6037 .page 6038 6039 | fp->idfpch = pch; 6040 6041 6041 F10L163: move PCH(A6),(A_FP) 6042 * 6043 *fpval = tfpval;6044 * 6042 6043 | fpval = tfpval; 6044 6045 6045 move TFPVAL(A6),R_FPVAL 6046 * 6047 .page 6048 * 6046 6047 .page 6048 6049 6049 move.b 5(A_FP),D0 6050 6050 ext.w D0 6051 6051 sub.w #1,D0 6052 6052 movea.l PT(A6),A0 6053 * 6054 *oldi = setipl(FPU_DI);6055 * 6053 6054 | oldi = setipl(FPU_DI); 6055 6056 6056 move sr,OLDI(A6) 6057 6057 move #FPU_DI,sr 6058 * 6058 6059 6059 F10L168: clr.b 10(A0) 6060 6060 add.l #12,a0 6061 6061 dbra D0,F10L168 6062 * 6063 .page 6064 * 6065 *fp->idftmd ^= I_NVBITS;6066 * 6062 6063 .page 6064 6065 | fp->idftmd ^= I_NVBITS; 6066 6067 6067 F10L165: eor.b #24,7(A_FP) 6068 * 6069 *fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;6070 * 6068 6069 | fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003; 6070 6071 6071 move.b 7(A_FP),R_FPCTL 6072 6072 and #28,R_FPCTL 6073 6073 or #3,R_FPCTL 6074 * 6075 *fp->idfcpt = fp->idfpt1;6076 * 6074 6075 | fp->idfcpt = fp->idfpt1; 6076 6077 6077 move.b 6(A_FP),8(A_FP) 6078 * 6079 *fp->idftmd |= I_ACTIVE;6080 * 6078 6079 | fp->idftmd |= I_ACTIVE; 6080 6081 6081 or.b #2,7(A_FP) 6082 * 6083 *fp->idftrf = trg;6084 * 6082 6083 | fp->idftrf = trg; 6084 6085 6085 move TRG(A6),10(A_FP) 6086 * 6087 * *(fpu + (long)FPU_TCV1) = srcval;6088 * 6089 move SRCVAL(A6), $8(A_FPU)6090 * 6091 *++octype;6092 * 6086 6087 | |(fpu + (long)FPU_TCV1) = srcval; 6088 6089 move SRCVAL(A6),0x8(A_FPU) 6090 6091 | ++octype; 6092 6093 6093 add #1,OCTYPE(A6) 6094 * 6095 * *(fpu + (long)FPU_TSF1) = mltval;6096 * 6097 move MLTVAL(A6), $A(A_FPU)6098 * 6099 *++octype;6100 * 6094 6095 | |(fpu + (long)FPU_TSF1) = mltval; 6096 6097 move MLTVAL(A6),0xA(A_FPU) 6098 6099 | ++octype; 6100 6101 6101 add #1,OCTYPE(A6) 6102 * 6103 * *(fpu + (long)FPU_TMNT) = fpmant;6104 * 6105 move R_FPMANT, $14(A_FPU)6106 * 6107 *++octype;6108 * 6102 6103 | |(fpu + (long)FPU_TMNT) = fpmant; 6104 6105 move R_FPMANT,0x14(A_FPU) 6106 6107 | ++octype; 6108 6109 6109 add #1,OCTYPE(A6) 6110 * 6111 * *(fpu + (long)FPU_TEXP) = fpexp;6112 * 6113 move R_FPEXP, $16(A_FPU)6114 * 6115 *++octype;6116 * 6110 6111 | |(fpu + (long)FPU_TEXP) = fpexp; 6112 6113 move R_FPEXP,0x16(A_FPU) 6114 6115 | ++octype; 6116 6117 6117 add #1,OCTYPE(A6) 6118 * 6119 .page 6120 * 6121 *if (fp->idftmd & I_VNSUBN)6122 * 6118 6119 .page 6120 6121 | if (fp->idftmd & I_VNSUBN) 6122 6123 6123 btst #3,7(A_FP) 6124 6124 beq F10L169 6125 * 6126 * *(fpu + (long)FPU_TNV1) = fpval;6127 * 6128 move R_FPVAL, $1C(A_FPU)6125 6126 | |(fpu + (long)FPU_TNV1) = fpval; 6127 6128 move R_FPVAL,0x1C(A_FPU) 6129 6129 bra F10L170 6130 * 6131 *else6132 * *(fpu + (long)FPU_TNV0) = fpval;6133 * 6130 6131 | else 6132 | |(fpu + (long)FPU_TNV0) = fpval; 6133 6134 6134 F10L169: move R_FPVAL,2(A_FPU) 6135 * 6136 *++octype;6137 * 6135 6136 | ++octype; 6137 6138 6138 F10L170: add #1,OCTYPE(A6) 6139 * 6140 * *(fpu + (long)FPU_TCTL) = fpctl;6141 * 6139 6140 | |(fpu + (long)FPU_TCTL) = fpctl; 6141 6142 6142 move R_FPCTL,(A_FPU) 6143 * 6144 *setipl(oldi);6145 * 6143 6144 | setipl(oldi); 6145 6146 6146 move OLDI(A6),sr 6147 * 6148 .page 6149 *------------------------------------------------------------------------------6150 *Start function 11 -- Ind 66151 *------------------------------------------------------------------------------6152 * 6153 *if (ip->idhfnc[11].idftmd & I_TM_KEY) {6154 * 6147 6148 .page 6149 | ------------------------------------------------------------------------------ 6150 | Start function 11 -- Ind 6 6151 | ------------------------------------------------------------------------------ 6152 6153 | if (ip->idhfnc[11].idftmd & I_TM_KEY) { 6154 6155 6155 FN11: move.l IP(A6),A0 6156 6156 move.b 225(A0),D0 … … 6159 6159 btst #0,D0 6160 6160 bne FN11A 6161 * 6161 6162 6162 jmp FN12 6163 * 6164 *vp = (vce << 4) + 15;6165 * 6163 6164 | vp = (vce << 4) + 15; 6165 6166 6166 FN11A: move VCE(A6),D0 6167 6167 asl #4,D0 6168 6168 add.w #15,D0 6169 6169 move D0,VP(A6) 6170 * 6171 *fpu = io_fpu + FPU_OFNC + (vp << 4);6172 * 6170 6171 | fpu = io_fpu + FPU_OFNC + (vp << 4); 6172 6173 6173 asl #5,D0 6174 6174 ext.l D0 6175 6175 move.l D0,A_FPU 6176 add.l #_io_fpu+ $4000,A_FPU6177 * 6178 *fp = &ip->idhfnc[11];6179 * 6176 add.l #_io_fpu+0x4000,A_FPU 6177 6178 | fp = &ip->idhfnc[11]; 6179 6180 6180 move.l #132,A_FP 6181 6181 add.l IP(A6),A_FP 6182 6182 add.l #86,A_FP 6183 * 6184 *pt = &ip->idhpnt[fp->idfpt1];6185 * 6183 6184 | pt = &ip->idhpnt[fp->idfpt1]; 6185 6186 6186 clr.l D0 6187 6187 move.b 6(A_FP),D0 … … 6193 6193 add.l #242,D0 6194 6194 move.l D0,PT(A6) 6195 * 6196 .page 6197 * 6198 *srcnum = group | fp->idfsrc;6199 * 6195 6196 .page 6197 6198 | srcnum = group | fp->idfsrc; 6199 6200 6200 move.w GROUP(A6),D0 6201 6201 ext.l D0 … … 6204 6204 or D1,D0 6205 6205 move D0,SRCNUM(A6) 6206 * 6207 *vep = &valents[srcnum];6208 * 6206 6207 | vep = &valents[srcnum]; 6208 6209 6209 add.l D0,D0 6210 6210 move.l D0,D1 … … 6213 6213 add.l #_valents,D0 6214 6214 move.l D0,VEP(A6) 6215 * 6216 *smp = vpsms[vp];6217 * 6215 6216 | smp = vpsms[vp]; 6217 6218 6218 move VP(A6),A0 6219 6219 add.l A0,A0 … … 6221 6221 add.l #_vpsms,A0 6222 6222 move.l (A0),A_SMP 6223 * 6224 *if (srcnum NE smp->sm) {6225 * 6223 6224 | if (srcnum NE smp->sm) { 6225 6226 6226 clr D0 6227 6227 move 10(A_SMP),D0 6228 6228 cmp SRCNUM(A6),D0 6229 6229 beq F11L113 6230 * 6231 *(smp->prv)->nxt = smp->nxt;6232 * 6230 6231 | (smp->prv)->nxt = smp->nxt; 6232 6233 6233 move.l 4(A_SMP),A0 6234 6234 move.l (A_SMP),(A0) 6235 * 6236 *(smp->nxt)->prv = smp->prv;6237 * 6235 6236 | (smp->nxt)->prv = smp->prv; 6237 6238 6238 move.l (A_SMP),A0 6239 6239 move.l 4(A_SMP),4(A0) 6240 * 6241 * smp->prv = (struct sment *)vep;6242 * 6240 6241 | smp->prv = (struct sment |)vep; 6242 6243 6243 move.l VEP(A6),4(A_SMP) 6244 * 6245 *smp->nxt = vep->nxt;6246 * 6244 6245 | smp->nxt = vep->nxt; 6246 6247 6247 move.l VEP(A6),A0 6248 6248 move.l (A0),(A_SMP) 6249 * 6250 *(vep->nxt)->prv = smp;6251 * 6249 6250 | (vep->nxt)->prv = smp; 6251 6252 6252 move.l VEP(A6),A0 6253 6253 move.l (A0),A0 6254 6254 move.l A_SMP,4(A0) 6255 * 6256 *vep->nxt = smp;6257 * 6255 6256 | vep->nxt = smp; 6257 6258 6258 move.l VEP(A6),A0 6259 6259 move.l A_SMP,(A0) 6260 * 6261 *smp->sm = srcnum;6262 * 6260 6261 | smp->sm = srcnum; 6262 6263 6263 move SRCNUM(A6),10(A_SMP) 6264 * 6265 *}6266 * 6267 *mltval = fp->idfmlt;6268 * 6264 6265 | } 6266 6267 | mltval = fp->idfmlt; 6268 6269 6269 F11L113: move 2(A_FP),MLTVAL(A6) 6270 * 6271 .page 6272 * 6273 *switch (fp->idfsrc) {6274 * 6270 6271 .page 6272 6273 | switch (fp->idfsrc) { 6274 6275 6275 move.b 4(A_FP),D0 6276 6276 ext.w d0 6277 6277 cmp #10,D0 6278 6278 bhi F11L122 6279 * 6279 6280 6280 asl #2,D0 6281 6281 lea F11L123,A0 6282 6282 movea.l 0(A0,D0.W),A0 6283 6283 jmp (A0) 6284 * 6285 *case SM_NONE:6286 *mltval = 0;6287 * 6284 6285 | case SM_NONE: 6286 | mltval = 0; 6287 6288 6288 F11L116: clr MLTVAL(A6) 6289 * 6290 *tsrcval = 0;6291 * 6289 6290 | tsrcval = 0; 6291 6292 6292 clr TSRCVAL(A6) 6293 * 6294 *break;6295 * 6293 6294 | break; 6295 6296 6296 bra F11L114 6297 * 6298 *case SM_RAND:6299 *tsrcval = xgetran(mltval);6300 * 6297 6298 | case SM_RAND: 6299 | tsrcval = xgetran(mltval); 6300 6301 6301 F11L117: move MLTVAL(A6),(sp) 6302 6302 jsr _xgetran 6303 6303 move D0,TSRCVAL(A6) 6304 * 6305 *break;6306 * 6304 6305 | break; 6306 6307 6307 bra F11L114 6308 * 6309 *case SM_PTCH:6310 *tsrcval = pch;6311 * 6308 6309 | case SM_PTCH: 6310 | tsrcval = pch; 6311 6312 6312 F11L118: move PCH(A6),TSRCVAL(A6) 6313 * 6314 *break;6315 * 6313 6314 | break; 6315 6316 6316 bra F11L114 6317 * 6318 .page 6319 * 6320 *case SM_FREQ:6321 *tsrcval = ptoftab[(pch >> 7) & 0x00FF];6322 * 6317 6318 .page 6319 6320 | case SM_FREQ: 6321 | tsrcval = ptoftab[(pch >> 7) & 0x00FF]; 6322 6323 6323 F11L119: move PCH(A6),D0 6324 6324 asr #7,D0 … … 6328 6328 add.l #_ptoftab,A0 6329 6329 move (A0),TSRCVAL(A6) 6330 * 6331 *break;6332 * 6330 6331 | break; 6332 6333 6333 bra F11L114 6334 * 6335 *case SM_KVEL:6336 *tsrcval = veltab[trg];6337 * 6334 6335 | case SM_KVEL: 6336 | tsrcval = veltab[trg]; 6337 6338 6338 F11L120: move TRG(A6),A0 6339 6339 add.l A0,A0 6340 6340 add.l #_veltab,A0 6341 6341 move (A0),TSRCVAL(A6) 6342 * 6343 *break;6344 * 6342 6343 | break; 6344 6345 6345 bra F11L114 6346 * 6347 *case SM_KPRS:6348 *tsrcval = prstab[trg];6349 * 6346 6347 | case SM_KPRS: 6348 | tsrcval = prstab[trg]; 6349 6350 6350 F11L121: move TRG(A6),A0 6351 6351 add.l A0,A0 6352 6352 add.l #_prstab,A0 6353 6353 move (A0),TSRCVAL(A6) 6354 * 6355 *break;6356 * 6354 6355 | break; 6356 6357 6357 bra F11L114 6358 * 6359 *default:6360 *tsrcval = vep->val;6361 * 6358 6359 | default: 6360 | tsrcval = vep->val; 6361 6362 6362 F11L122: move.l VEP(A6),A0 6363 6363 move 8(A0),TSRCVAL(A6) 6364 * 6365 *}6366 * 6367 .page 6368 * 6369 *srcval = tsrcval;6370 * 6364 6365 | } 6366 6367 .page 6368 6369 | srcval = tsrcval; 6370 6371 6371 F11L114: move TSRCVAL(A6),SRCVAL(A6) 6372 * 6373 .page 6374 * 6375 *if (pt->ipvsrc) {6376 * 6372 6373 .page 6374 6375 | if (pt->ipvsrc) { 6376 6377 6377 F11L124: move.l PT(A6),A0 6378 6378 tst.b 6(A0) 6379 6379 beq F11L136 6380 * 6381 *switch (pt->ipvsrc) {6382 * 6380 6381 | switch (pt->ipvsrc) { 6382 6383 6383 move.l PT(A6),A0 6384 6384 move.b 6(A0),D0 … … 6387 6387 cmp #9,D0 6388 6388 bhi F11L144 6389 * 6389 6390 6390 asl #2,D0 6391 6391 lea F11L145,A0 6392 6392 move.l 0(A0,D0.W),A0 6393 6393 jmp (A0) 6394 * 6395 *case SM_RAND:6396 *ltmp = xgetran(pt_>ipvmlt);6397 * 6394 6395 | case SM_RAND: 6396 | ltmp = xgetran(pt_>ipvmlt); 6397 6398 6398 F11L139: move.l PT(A6),A0 6399 6399 move 4(A0),(sp) … … 6401 6401 ext.l D0 6402 6402 move.l D0,LTMP(A6) 6403 * 6404 *break;6405 * 6403 6404 | break; 6405 6406 6406 bra F11L137 6407 * 6408 *case SM_PTCH:6409 *ltmp = pch;6410 * 6407 6408 | case SM_PTCH: 6409 | ltmp = pch; 6410 6411 6411 F11L140: move PCH(A6),A0 6412 6412 move.l A0,LTMP(A6) 6413 * 6414 *break;6415 * 6413 6414 | break; 6415 6416 6416 bra F11L137 6417 * 6418 .page 6419 * 6420 *case SM_FREQ:6421 *ltmp = ptoftab[(pch >> 7) & 0x00FF];6422 * 6417 6418 .page 6419 6420 | case SM_FREQ: 6421 | ltmp = ptoftab[(pch >> 7) & 0x00FF]; 6422 6423 6423 F11L141: move PCH(A6),D0 6424 6424 asr #7,D0 … … 6430 6430 ext.l D0 6431 6431 move.l D0,LTMP(A6) 6432 * 6433 *break;6434 * 6432 6433 | break; 6434 6435 6435 bra F11L137 6436 * 6437 *case SM_KVEL:6438 *ltmp = veltab[trg];6439 * 6436 6437 | case SM_KVEL: 6438 | ltmp = veltab[trg]; 6439 6440 6440 F11L142: move TRG(A6),A0 6441 6441 add.l A0,A0 … … 6444 6444 ext.l D0 6445 6445 move.l D0,LTMP(A6) 6446 * 6447 *break;6448 * 6446 6447 | break; 6448 6449 6449 bra F11L137 6450 * 6451 .page 6452 * 6453 *case SM_KPRS:6454 *ltmp = prstab[trg];6455 * 6450 6451 .page 6452 6453 | case SM_KPRS: 6454 | ltmp = prstab[trg]; 6455 6456 6456 F11L143: move TRG(A6),A0 6457 6457 add.l A0,A0 … … 6460 6460 ext.l D0 6461 6461 move.l D0,LTMP(A6) 6462 * 6463 *break;6464 * 6462 6463 | break; 6464 6465 6465 bra F11L137 6466 * 6467 .page 6468 * 6469 *default:6470 *ltmp = valents[group | pt->ipvsrc].val;6471 * 6466 6467 .page 6468 6469 | default: 6470 | ltmp = valents[group | pt->ipvsrc].val; 6471 6472 6472 F11L144: move.l PT(A6),A0 6473 6473 clr.l D0 … … 6483 6483 move 8(A0,A1.l),D0 6484 6484 move.l D0,LTMP(A6) 6485 * 6486 *}6487 * 6488 * 6489 .page 6490 * 6491 * ltmp = (ltmp *pt->ipvmlt) >> 15;6492 * 6485 6486 | } 6487 6488 6489 .page 6490 6491 | ltmp = (ltmp | pt->ipvmlt) >> 15; 6492 6493 6493 F11L137: move.l PT(A6),A0 6494 6494 move.w 4(A0),D0 … … 6498 6498 asr.l D1,D0 6499 6499 move.l D0,LTMP(A6) 6500 * 6501 *ltmp += (long)pt->ipval;6502 * 6500 6501 | ltmp += (long)pt->ipval; 6502 6503 6503 move.l PT(A6),A0 6504 6504 move 2(A0),D0 6505 6505 ext.l D0 6506 6506 add.l D0,LTMP(A6) 6507 * 6508 *if (ltmp GT (long)VALMAX)6509 *ltmp = (long)VALMAX;6510 * 6507 6508 | if (ltmp GT (long)VALMAX) 6509 | ltmp = (long)VALMAX; 6510 6511 6511 cmp.l #VALMAX,LTMP(A6) 6512 6512 ble F11L146 6513 * 6513 6514 6514 move.l #VALMAX,LTMP(A6) 6515 6515 bra F11L147 6516 * 6517 *else if (ltmp LT (long)VALMIN)6518 *ltmp = (long)VALMIN;6519 * 6516 6517 | else if (ltmp LT (long)VALMIN) 6518 | ltmp = (long)VALMIN; 6519 6520 6520 F11L146: cmp.l #VALMIN,LTMP(A6) 6521 6521 bge F11L147 6522 * 6522 6523 6523 move.l #VALMIN,LTMP(A6) 6524 * 6525 *tfpval = (short)ltmp;6526 * 6524 6525 | tfpval = (short)ltmp; 6526 6527 6527 F11L147: move.w LTMP+2(A6),TFPVAL(A6) 6528 6528 bra F11L149 6529 * 6530 *} else {6531 * 6532 *tfpval = pt->ipval;6533 * 6529 6530 | } else { 6531 6532 | tfpval = pt->ipval; 6533 6534 6534 F11L136: move.l PT(A6),A0 6535 6535 move 2(A0),TFPVAL(A6) 6536 * 6537 *}6538 * 6539 .page 6540 * 6541 *fpmant = (((long)pt->iptom & 0x0000FFF0L)6542 * *((long)timemlt & 0x0000FFFFL)) >> 15;6543 * 6536 6537 | } 6538 6539 .page 6540 6541 | fpmant = (((long)pt->iptom & 0x0000FFF0L) 6542 | | ((long)timemlt & 0x0000FFFFL)) >> 15; 6543 6544 6544 F11L149: move.l PT(A6),A0 6545 6545 move.w (A0),D0 6546 6546 move.w D0,D2 6547 andi.w # $FFF0,D06547 andi.w #0xFFF0,D0 6548 6548 move.w _timemlt,D1 6549 6549 muls D1,D0 … … 6551 6551 asr.l D1,D0 6552 6552 move D0,R_FPMANT 6553 * 6554 *fpexp = expbit[pt->iptim & 0x000F];6555 * 6556 and # $000F,D26553 6554 | fpexp = expbit[pt->iptim & 0x000F]; 6555 6556 and #0x000F,D2 6557 6557 move D2,A0 6558 6558 add.l A0,A0 6559 6559 add.l #_expbit,A0 6560 6560 move (A0),R_FPEXP 6561 * 6562 .page 6563 * 6564 *fp->idfpch = pch;6565 * 6561 6562 .page 6563 6564 | fp->idfpch = pch; 6565 6566 6566 F11L163: move PCH(A6),(A_FP) 6567 * 6568 *fpval = tfpval;6569 * 6567 6568 | fpval = tfpval; 6569 6570 6570 move TFPVAL(A6),R_FPVAL 6571 * 6572 .page 6573 * 6571 6572 .page 6573 6574 6574 move.b 5(A_FP),D0 6575 6575 ext.w D0 6576 6576 sub.w #1,D0 6577 6577 movea.l PT(A6),A0 6578 * 6579 *oldi = setipl(FPU_DI);6580 * 6578 6579 | oldi = setipl(FPU_DI); 6580 6581 6581 move sr,OLDI(A6) 6582 6582 move #FPU_DI,sr 6583 * 6583 6584 6584 F11L168: clr.b 10(A0) 6585 6585 add.l #12,a0 6586 6586 dbra D0,F11L168 6587 * 6588 .page 6589 * 6590 *fp->idftmd ^= I_NVBITS;6591 * 6587 6588 .page 6589 6590 | fp->idftmd ^= I_NVBITS; 6591 6592 6592 F11L165: eor.b #24,7(A_FP) 6593 * 6594 *fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;6595 * 6593 6594 | fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003; 6595 6596 6596 move.b 7(A_FP),R_FPCTL 6597 6597 and #28,R_FPCTL 6598 6598 or #3,R_FPCTL 6599 * 6600 *fp->idfcpt = fp->idfpt1;6601 * 6599 6600 | fp->idfcpt = fp->idfpt1; 6601 6602 6602 move.b 6(A_FP),8(A_FP) 6603 * 6604 *fp->idftmd |= I_ACTIVE;6605 * 6603 6604 | fp->idftmd |= I_ACTIVE; 6605 6606 6606 or.b #2,7(A_FP) 6607 * 6608 *fp->idftrf = trg;6609 * 6607 6608 | fp->idftrf = trg; 6609 6610 6610 move TRG(A6),10(A_FP) 6611 * 6612 * *(fpu + (long)FPU_TCV1) = srcval;6613 * 6614 move SRCVAL(A6), $8(A_FPU)6615 * 6616 *++octype;6617 * 6611 6612 | |(fpu + (long)FPU_TCV1) = srcval; 6613 6614 move SRCVAL(A6),0x8(A_FPU) 6615 6616 | ++octype; 6617 6618 6618 add #1,OCTYPE(A6) 6619 * 6620 * *(fpu + (long)FPU_TSF1) = mltval;6621 * 6622 move MLTVAL(A6), $A(A_FPU)6623 * 6624 *++octype;6625 * 6619 6620 | |(fpu + (long)FPU_TSF1) = mltval; 6621 6622 move MLTVAL(A6),0xA(A_FPU) 6623 6624 | ++octype; 6625 6626 6626 add #1,OCTYPE(A6) 6627 * 6628 * *(fpu + (long)FPU_TMNT) = fpmant;6629 * 6630 move R_FPMANT, $14(A_FPU)6631 * 6632 *++octype;6633 * 6627 6628 | |(fpu + (long)FPU_TMNT) = fpmant; 6629 6630 move R_FPMANT,0x14(A_FPU) 6631 6632 | ++octype; 6633 6634 6634 add #1,OCTYPE(A6) 6635 * 6636 * *(fpu + (long)FPU_TEXP) = fpexp;6637 * 6638 move R_FPEXP, $16(A_FPU)6639 * 6640 *++octype;6641 * 6635 6636 | |(fpu + (long)FPU_TEXP) = fpexp; 6637 6638 move R_FPEXP,0x16(A_FPU) 6639 6640 | ++octype; 6641 6642 6642 add #1,OCTYPE(A6) 6643 * 6644 .page 6645 * 6646 *if (fp->idftmd & I_VNSUBN)6647 * 6643 6644 .page 6645 6646 | if (fp->idftmd & I_VNSUBN) 6647 6648 6648 btst #3,7(A_FP) 6649 6649 beq F11L169 6650 * 6651 * *(fpu + (long)FPU_TNV1) = fpval;6652 * 6653 move R_FPVAL, $1C(A_FPU)6650 6651 | |(fpu + (long)FPU_TNV1) = fpval; 6652 6653 move R_FPVAL,0x1C(A_FPU) 6654 6654 bra F11L170 6655 * 6656 *else6657 * *(fpu + (long)FPU_TNV0) = fpval;6658 * 6655 6656 | else 6657 | |(fpu + (long)FPU_TNV0) = fpval; 6658 6659 6659 F11L169: move R_FPVAL,2(A_FPU) 6660 * 6661 *++octype;6662 * 6660 6661 | ++octype; 6662 6663 6663 F11L170: add #1,OCTYPE(A6) 6664 * 6665 * *(fpu + (long)FPU_TCTL) = fpctl;6666 * 6664 6665 | |(fpu + (long)FPU_TCTL) = fpctl; 6666 6667 6667 move R_FPCTL,(A_FPU) 6668 * 6669 *setipl(oldi);6670 * 6668 6669 | setipl(oldi); 6670 6671 6671 move OLDI(A6),sr 6672 * 6673 .page 6674 *------------------------------------------------------------------------------6675 *Start function 12 -- Level6676 *------------------------------------------------------------------------------6677 * 6678 *if (ip->idhfnc[12].idftmd & I_TM_KEY) {6679 * 6672 6673 .page 6674 | ------------------------------------------------------------------------------ 6675 | Start function 12 -- Level 6676 | ------------------------------------------------------------------------------ 6677 6678 | if (ip->idhfnc[12].idftmd & I_TM_KEY) { 6679 6680 6680 FN12: move.l IP(A6),A0 6681 6681 move.b 237(A0),D0 … … 6684 6684 btst #0,D0 6685 6685 bne FN12A 6686 * 6686 6687 6687 jmp FNEXIT 6688 * 6689 *vp = (vce << 4) + 2;6690 * 6688 6689 | vp = (vce << 4) + 2; 6690 6691 6691 FN12A: move VCE(A6),D0 6692 6692 asl #4,D0 6693 6693 add.w #2,D0 6694 6694 move D0,VP(A6) 6695 * 6696 *fpu = io_fpu + FPU_OFNC + (vp << 4);6697 * 6695 6696 | fpu = io_fpu + FPU_OFNC + (vp << 4); 6697 6698 6698 asl #5,D0 6699 6699 ext.l D0 6700 6700 move.l D0,A_FPU 6701 add.l #_io_fpu+ $4000,A_FPU6702 * 6703 *fp = &ip->idhfnc[12];6704 * 6701 add.l #_io_fpu+0x4000,A_FPU 6702 6703 | fp = &ip->idhfnc[12]; 6704 6705 6705 move.l #144,A_FP 6706 6706 add.l IP(A6),A_FP 6707 6707 add.l #86,A_FP 6708 * 6709 *pt = &ip->idhpnt[fp->idfpt1];6710 * 6708 6709 | pt = &ip->idhpnt[fp->idfpt1]; 6710 6711 6711 clr.l D0 6712 6712 move.b 6(A_FP),D0 … … 6718 6718 add.l #242,D0 6719 6719 move.l D0,PT(A6) 6720 * 6721 .page 6722 * 6723 *srcnum = group | fp->idfsrc;6724 * 6720 6721 .page 6722 6723 | srcnum = group | fp->idfsrc; 6724 6725 6725 move.w GROUP(A6),D0 6726 6726 ext.l D0 … … 6729 6729 or D1,D0 6730 6730 move D0,SRCNUM(A6) 6731 * 6732 *vep = &valents[srcnum];6733 * 6731 6732 | vep = &valents[srcnum]; 6733 6734 6734 add.l D0,D0 6735 6735 move.l D0,D1 … … 6738 6738 add.l #_valents,D0 6739 6739 move.l D0,VEP(A6) 6740 * 6741 *smp = vpsms[vp];6742 * 6740 6741 | smp = vpsms[vp]; 6742 6743 6743 move VP(A6),A0 6744 6744 add.l A0,A0 … … 6746 6746 add.l #_vpsms,A0 6747 6747 move.l (A0),A_SMP 6748 * 6749 *if (srcnum NE smp->sm) {6750 * 6748 6749 | if (srcnum NE smp->sm) { 6750 6751 6751 clr D0 6752 6752 move 10(A_SMP),D0 6753 6753 cmp SRCNUM(A6),D0 6754 6754 beq F12L113 6755 * 6756 *(smp->prv)->nxt = smp->nxt;6757 * 6755 6756 | (smp->prv)->nxt = smp->nxt; 6757 6758 6758 move.l 4(A_SMP),A0 6759 6759 move.l (A_SMP),(A0) 6760 * 6761 *(smp->nxt)->prv = smp->prv;6762 * 6760 6761 | (smp->nxt)->prv = smp->prv; 6762 6763 6763 move.l (A_SMP),A0 6764 6764 move.l 4(A_SMP),4(A0) 6765 * 6766 * smp->prv = (struct sment *)vep;6767 * 6765 6766 | smp->prv = (struct sment |)vep; 6767 6768 6768 move.l VEP(A6),4(A_SMP) 6769 * 6770 *smp->nxt = vep->nxt;6771 * 6769 6770 | smp->nxt = vep->nxt; 6771 6772 6772 move.l VEP(A6),A0 6773 6773 move.l (A0),(A_SMP) 6774 * 6775 *(vep->nxt)->prv = smp;6776 * 6774 6775 | (vep->nxt)->prv = smp; 6776 6777 6777 move.l VEP(A6),A0 6778 6778 move.l (A0),A0 6779 6779 move.l A_SMP,4(A0) 6780 * 6781 *vep->nxt = smp;6782 * 6780 6781 | vep->nxt = smp; 6782 6783 6783 move.l VEP(A6),A0 6784 6784 move.l A_SMP,(A0) 6785 * 6786 *smp->sm = srcnum;6787 * 6785 6786 | smp->sm = srcnum; 6787 6788 6788 move SRCNUM(A6),10(A_SMP) 6789 * 6790 *}6791 * 6792 *mltval = fp->idfmlt;6793 * 6789 6790 | } 6791 6792 | mltval = fp->idfmlt; 6793 6794 6794 F12L113: move 2(A_FP),MLTVAL(A6) 6795 * 6796 .page 6797 * 6798 *switch (fp->idfsrc) {6799 * 6795 6796 .page 6797 6798 | switch (fp->idfsrc) { 6799 6800 6800 move.b 4(A_FP),D0 6801 6801 ext.w d0 6802 6802 cmp #10,D0 6803 6803 bhi F12L122 6804 * 6804 6805 6805 asl #2,D0 6806 6806 lea F12L123,A0 6807 6807 movea.l 0(A0,D0.W),A0 6808 6808 jmp (A0) 6809 * 6810 *case SM_NONE:6811 *mltval = 0;6812 * 6809 6810 | case SM_NONE: 6811 | mltval = 0; 6812 6813 6813 F12L116: clr MLTVAL(A6) 6814 * 6815 *tsrcval = 0;6816 * 6814 6815 | tsrcval = 0; 6816 6817 6817 clr TSRCVAL(A6) 6818 * 6819 *break;6820 * 6818 6819 | break; 6820 6821 6821 bra F12L114 6822 * 6823 *case SM_RAND:6824 *tsrcval = xgetran(mltval);6825 * 6822 6823 | case SM_RAND: 6824 | tsrcval = xgetran(mltval); 6825 6826 6826 F12L117: move MLTVAL(A6),(sp) 6827 6827 jsr _xgetran 6828 6828 move D0,TSRCVAL(A6) 6829 * 6830 *break;6831 * 6829 6830 | break; 6831 6832 6832 bra F12L114 6833 * 6834 *case SM_PTCH:6835 *tsrcval = pch;6836 * 6833 6834 | case SM_PTCH: 6835 | tsrcval = pch; 6836 6837 6837 F12L118: move PCH(A6),TSRCVAL(A6) 6838 * 6839 *break;6840 * 6838 6839 | break; 6840 6841 6841 bra F12L114 6842 * 6843 .page 6844 * 6845 *case SM_FREQ:6846 *tsrcval = ptoftab[(pch >> 7) & 0x00FF];6847 * 6842 6843 .page 6844 6845 | case SM_FREQ: 6846 | tsrcval = ptoftab[(pch >> 7) & 0x00FF]; 6847 6848 6848 F12L119: move PCH(A6),D0 6849 6849 asr #7,D0 … … 6853 6853 add.l #_ptoftab,A0 6854 6854 move (A0),TSRCVAL(A6) 6855 * 6856 *break;6857 * 6855 6856 | break; 6857 6858 6858 bra F12L114 6859 * 6860 *case SM_KVEL:6861 *tsrcval = veltab[trg];6862 * 6859 6860 | case SM_KVEL: 6861 | tsrcval = veltab[trg]; 6862 6863 6863 F12L120: move TRG(A6),A0 6864 6864 add.l A0,A0 6865 6865 add.l #_veltab,A0 6866 6866 move (A0),TSRCVAL(A6) 6867 * 6868 *break;6869 * 6867 6868 | break; 6869 6870 6870 bra F12L114 6871 * 6872 *case SM_KPRS:6873 *tsrcval = prstab[trg];6874 * 6871 6872 | case SM_KPRS: 6873 | tsrcval = prstab[trg]; 6874 6875 6875 F12L121: move TRG(A6),A0 6876 6876 add.l A0,A0 6877 6877 add.l #_prstab,A0 6878 6878 move (A0),TSRCVAL(A6) 6879 * 6880 *break;6881 * 6879 6880 | break; 6881 6882 6882 bra F12L114 6883 * 6884 *default:6885 *tsrcval = vep->val;6886 * 6883 6884 | default: 6885 | tsrcval = vep->val; 6886 6887 6887 F12L122: move.l VEP(A6),A0 6888 6888 move 8(A0),TSRCVAL(A6) 6889 * 6890 *}6891 * 6892 .page 6893 * 6894 *srcval = tsrcval;6895 * 6889 6890 | } 6891 6892 .page 6893 6894 | srcval = tsrcval; 6895 6896 6896 F12L114: move TSRCVAL(A6),SRCVAL(A6) 6897 * 6898 .page 6899 * 6900 *if (pt->ipvsrc) {6901 * 6897 6898 .page 6899 6900 | if (pt->ipvsrc) { 6901 6902 6902 F12L124: move.l PT(A6),A0 6903 6903 tst.b 6(A0) 6904 6904 beq F12L136 6905 * 6906 *switch (pt->ipvsrc) {6907 * 6905 6906 | switch (pt->ipvsrc) { 6907 6908 6908 move.l PT(A6),A0 6909 6909 move.b 6(A0),D0 … … 6912 6912 cmp #9,D0 6913 6913 bhi F12L144 6914 * 6914 6915 6915 asl #2,D0 6916 6916 lea F12L145,A0 6917 6917 move.l 0(A0,D0.W),A0 6918 6918 jmp (A0) 6919 * 6920 *case SM_RAND:6921 *ltmp = xgetran(pt_>ipvmlt);6922 * 6919 6920 | case SM_RAND: 6921 | ltmp = xgetran(pt_>ipvmlt); 6922 6923 6923 F12L139: move.l PT(A6),A0 6924 6924 move 4(A0),(sp) … … 6926 6926 ext.l D0 6927 6927 move.l D0,LTMP(A6) 6928 * 6929 *break;6930 * 6928 6929 | break; 6930 6931 6931 bra F12L137 6932 * 6933 *case SM_PTCH:6934 *ltmp = pch;6935 * 6932 6933 | case SM_PTCH: 6934 | ltmp = pch; 6935 6936 6936 F12L140: move PCH(A6),A0 6937 6937 move.l A0,LTMP(A6) 6938 * 6939 *break;6940 * 6938 6939 | break; 6940 6941 6941 bra F12L137 6942 * 6943 .page 6944 * 6945 *case SM_FREQ:6946 *ltmp = ptoftab[(pch >> 7) & 0x00FF];6947 * 6942 6943 .page 6944 6945 | case SM_FREQ: 6946 | ltmp = ptoftab[(pch >> 7) & 0x00FF]; 6947 6948 6948 F12L141: move PCH(A6),D0 6949 6949 asr #7,D0 … … 6955 6955 ext.l D0 6956 6956 move.l D0,LTMP(A6) 6957 * 6958 *break;6959 * 6957 6958 | break; 6959 6960 6960 bra F12L137 6961 * 6962 *case SM_KVEL:6963 *ltmp = veltab[trg];6964 * 6961 6962 | case SM_KVEL: 6963 | ltmp = veltab[trg]; 6964 6965 6965 F12L142: move TRG(A6),A0 6966 6966 add.l A0,A0 … … 6969 6969 ext.l D0 6970 6970 move.l D0,LTMP(A6) 6971 * 6972 *break;6973 * 6971 6972 | break; 6973 6974 6974 bra F12L137 6975 * 6976 .page 6977 * 6978 *case SM_KPRS:6979 *ltmp = prstab[trg];6980 * 6975 6976 .page 6977 6978 | case SM_KPRS: 6979 | ltmp = prstab[trg]; 6980 6981 6981 F12L143: move TRG(A6),A0 6982 6982 add.l A0,A0 … … 6985 6985 ext.l D0 6986 6986 move.l D0,LTMP(A6) 6987 * 6988 *break;6989 * 6987 6988 | break; 6989 6990 6990 bra F12L137 6991 * 6992 .page 6993 * 6994 *default:6995 *ltmp = valents[group | pt->ipvsrc].val;6996 * 6991 6992 .page 6993 6994 | default: 6995 | ltmp = valents[group | pt->ipvsrc].val; 6996 6997 6997 F12L144: move.l PT(A6),A0 6998 6998 clr.l D0 … … 7008 7008 move 8(A0,A1.l),D0 7009 7009 move.l D0,LTMP(A6) 7010 * 7011 *}7012 * 7013 * 7014 .page 7015 * 7016 * ltmp = (ltmp *pt->ipvmlt) >> 15;7017 * 7010 7011 | } 7012 7013 7014 .page 7015 7016 | ltmp = (ltmp | pt->ipvmlt) >> 15; 7017 7018 7018 F12L137: move.l PT(A6),A0 7019 7019 move.w 4(A0),D0 … … 7023 7023 asr.l D1,D0 7024 7024 move.l D0,LTMP(A6) 7025 * 7026 *ltmp += (long)pt->ipval;7027 * 7025 7026 | ltmp += (long)pt->ipval; 7027 7028 7028 move.l PT(A6),A0 7029 7029 move 2(A0),D0 7030 7030 ext.l D0 7031 7031 add.l D0,LTMP(A6) 7032 * 7033 *if (ltmp GT (long)VALMAX)7034 *ltmp = (long)VALMAX;7035 * 7032 7033 | if (ltmp GT (long)VALMAX) 7034 | ltmp = (long)VALMAX; 7035 7036 7036 cmp.l #VALMAX,LTMP(A6) 7037 7037 ble F12L146 7038 * 7038 7039 7039 move.l #VALMAX,LTMP(A6) 7040 7040 bra F12L147 7041 * 7042 *else if (ltmp LT (long)VALMIN)7043 *ltmp = (long)VALMIN;7044 * 7041 7042 | else if (ltmp LT (long)VALMIN) 7043 | ltmp = (long)VALMIN; 7044 7045 7045 F12L146: cmp.l #VALMIN,LTMP(A6) 7046 7046 bge F12L147 7047 * 7047 7048 7048 move.l #VALMIN,LTMP(A6) 7049 * 7050 *tfpval = (short)ltmp;7051 * 7049 7050 | tfpval = (short)ltmp; 7051 7052 7052 F12L147: move.w LTMP+2(A6),TFPVAL(A6) 7053 7053 bra F12L149 7054 * 7055 *} else {7056 * 7057 *tfpval = pt->ipval;7058 * 7054 7055 | } else { 7056 7057 | tfpval = pt->ipval; 7058 7059 7059 F12L136: move.l PT(A6),A0 7060 7060 move 2(A0),TFPVAL(A6) 7061 * 7062 *}7063 * 7064 .page 7065 * 7066 *fpmant = (((long)pt->iptom & 0x0000FFF0L)7067 * *((long)timemlt & 0x0000FFFFL)) >> 15;7068 * 7061 7062 | } 7063 7064 .page 7065 7066 | fpmant = (((long)pt->iptom & 0x0000FFF0L) 7067 | | ((long)timemlt & 0x0000FFFFL)) >> 15; 7068 7069 7069 F12L149: move.l PT(A6),A0 7070 7070 move.w (A0),D0 7071 7071 move.w D0,D2 7072 andi.w # $FFF0,D07072 andi.w #0xFFF0,D0 7073 7073 move.w _timemlt,D1 7074 7074 muls D1,D0 … … 7076 7076 asr.l D1,D0 7077 7077 move D0,R_FPMANT 7078 * 7079 *fpexp = expbit[pt->iptim & 0x000F];7080 * 7081 and # $000F,D27078 7079 | fpexp = expbit[pt->iptim & 0x000F]; 7080 7081 and #0x000F,D2 7082 7082 move D2,A0 7083 7083 add.l A0,A0 7084 7084 add.l #_expbit,A0 7085 7085 move (A0),R_FPEXP 7086 * 7087 .page 7088 * 7089 *fp->idfpch = pch;7090 * 7086 7087 .page 7088 7089 | fp->idfpch = pch; 7090 7091 7091 F12L162: move PCH(A6),(A_FP) 7092 * 7093 *fpval = ((tfpval >> 5) - 500) << 6;7094 * 7092 7093 | fpval = ((tfpval >> 5) - 500) << 6; 7094 7095 7095 move TFPVAL(A6),R_FPVAL 7096 7096 asr #5,R_FPVAL 7097 7097 add #-500,R_FPVAL 7098 7098 asl #6,R_FPVAL 7099 * 7100 .page 7101 * 7099 7100 .page 7101 7102 7102 move.b 5(A_FP),D0 7103 7103 ext.w D0 7104 7104 sub.w #1,D0 7105 7105 movea.l PT(A6),A0 7106 * 7107 *oldi = setipl(FPU_DI);7108 * 7106 7107 | oldi = setipl(FPU_DI); 7108 7109 7109 move sr,OLDI(A6) 7110 7110 move #FPU_DI,sr 7111 * 7111 7112 7112 F12L168: clr.b 10(A0) 7113 7113 add.l #12,a0 7114 7114 dbra D0,F12L168 7115 * 7116 .page 7117 * 7118 *fp->idftmd ^= I_NVBITS;7119 * 7115 7116 .page 7117 7118 | fp->idftmd ^= I_NVBITS; 7119 7120 7120 F12L165: eor.b #24,7(A_FP) 7121 * 7122 *fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;7123 * 7121 7122 | fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003; 7123 7124 7124 move.b 7(A_FP),R_FPCTL 7125 7125 and #28,R_FPCTL 7126 7126 or #3,R_FPCTL 7127 * 7128 *fp->idfcpt = fp->idfpt1;7129 * 7127 7128 | fp->idfcpt = fp->idfpt1; 7129 7130 7130 move.b 6(A_FP),8(A_FP) 7131 * 7132 *fp->idftmd |= I_ACTIVE;7133 * 7131 7132 | fp->idftmd |= I_ACTIVE; 7133 7134 7134 or.b #2,7(A_FP) 7135 * 7136 *fp->idftrf = trg;7137 * 7135 7136 | fp->idftrf = trg; 7137 7138 7138 move TRG(A6),10(A_FP) 7139 * 7140 * *(fpu + (long)FPU_TCV1) = srcval;7141 * 7142 move SRCVAL(A6), $8(A_FPU)7143 * 7144 *++octype;7145 * 7139 7140 | |(fpu + (long)FPU_TCV1) = srcval; 7141 7142 move SRCVAL(A6),0x8(A_FPU) 7143 7144 | ++octype; 7145 7146 7146 add #1,OCTYPE(A6) 7147 * 7148 * *(fpu + (long)FPU_TSF1) = mltval;7149 * 7150 move MLTVAL(A6), $A(A_FPU)7151 * 7152 *++octype;7153 * 7147 7148 | |(fpu + (long)FPU_TSF1) = mltval; 7149 7150 move MLTVAL(A6),0xA(A_FPU) 7151 7152 | ++octype; 7153 7154 7154 add #1,OCTYPE(A6) 7155 * 7156 * *(fpu + (long)FPU_TMNT) = fpmant;7157 * 7158 move R_FPMANT, $14(A_FPU)7159 * 7160 *++octype;7161 * 7155 7156 | |(fpu + (long)FPU_TMNT) = fpmant; 7157 7158 move R_FPMANT,0x14(A_FPU) 7159 7160 | ++octype; 7161 7162 7162 add #1,OCTYPE(A6) 7163 * 7164 * *(fpu + (long)FPU_TEXP) = fpexp;7165 * 7166 move R_FPEXP, $16(A_FPU)7167 * 7168 *++octype;7169 * 7163 7164 | |(fpu + (long)FPU_TEXP) = fpexp; 7165 7166 move R_FPEXP,0x16(A_FPU) 7167 7168 | ++octype; 7169 7170 7170 add #1,OCTYPE(A6) 7171 * 7172 .page 7173 * 7174 *if (fp->idftmd & I_VNSUBN)7175 * 7171 7172 .page 7173 7174 | if (fp->idftmd & I_VNSUBN) 7175 7176 7176 btst #3,7(A_FP) 7177 7177 beq F12L169 7178 * 7179 * *(fpu + (long)FPU_TNV1) = fpval;7180 * 7181 move R_FPVAL, $1C(A_FPU)7178 7179 | |(fpu + (long)FPU_TNV1) = fpval; 7180 7181 move R_FPVAL,0x1C(A_FPU) 7182 7182 bra F12L170 7183 * 7184 *else7185 * *(fpu + (long)FPU_TNV0) = fpval;7186 * 7183 7184 | else 7185 | |(fpu + (long)FPU_TNV0) = fpval; 7186 7187 7187 F12L169: move R_FPVAL,2(A_FPU) 7188 * 7189 *++octype;7190 * 7188 7189 | ++octype; 7190 7191 7191 F12L170: add #1,OCTYPE(A6) 7192 * 7193 * *(fpu + (long)FPU_TCTL) = fpctl;7194 * 7192 7193 | |(fpu + (long)FPU_TCTL) = fpctl; 7194 7195 7195 move R_FPCTL,(A_FPU) 7196 * 7197 *setipl(oldi);7198 * 7196 7197 | setipl(oldi); 7198 7199 7199 move OLDI(A6),sr 7200 * 7201 *}7202 * 7203 .page 7204 * 7200 7201 | } 7202 7203 .page 7204 7205 7205 FNEXIT: tst.l (sp)+ 7206 7206 movem.l (sp)+,R_FPVAL-R_FPMANT/A_SMP-A_FP 7207 7207 unlk A6 7208 7208 rts 7209 * 7210 *}7211 * 7212 .page 7213 * 7209 7210 | } 7211 7212 .page 7213 7214 7214 .data 7215 * 7216 *Jump tables for switch statements7217 *---------------------------------7218 * 7215 7216 | Jump tables for switch statements 7217 | --------------------------------- 7218 7219 7219 F00L123: .dc.l F00L116 7220 7220 .dc.l F00L117 … … 7228 7228 .dc.l F00L122 7229 7229 .dc.l F00L119 7230 * 7230 7231 7231 F00L145: .dc.l F00L139 7232 7232 .dc.l F00L144 … … 7239 7239 .dc.l F00L144 7240 7240 .dc.l F00L141 7241 * 7241 7242 7242 F01L123: .dc.l F01L116 7243 7243 .dc.l F01L117 … … 7251 7251 .dc.l F01L122 7252 7252 .dc.l F01L119 7253 * 7253 7254 7254 F01L145: .dc.l F01L139 7255 7255 .dc.l F01L144 … … 7262 7262 .dc.l F01L144 7263 7263 .dc.l F01L141 7264 * 7264 7265 7265 F02L123: .dc.l F02L116 7266 7266 .dc.l F02L117 … … 7274 7274 .dc.l F02L122 7275 7275 .dc.l F02L119 7276 * 7276 7277 7277 F02L145: .dc.l F02L139 7278 7278 .dc.l F02L144 … … 7285 7285 .dc.l F02L144 7286 7286 .dc.l F02L141 7287 * 7287 7288 7288 F03L123: .dc.l F03L116 7289 7289 .dc.l F03L117 … … 7297 7297 .dc.l F03L122 7298 7298 .dc.l F03L119 7299 * 7299 7300 7300 F03L145: .dc.l F03L139 7301 7301 .dc.l F03L144 … … 7308 7308 .dc.l F03L144 7309 7309 .dc.l F03L141 7310 * 7310 7311 7311 F04L123: .dc.l F04L116 7312 7312 .dc.l F04L117 … … 7320 7320 .dc.l F04L122 7321 7321 .dc.l F04L119 7322 * 7322 7323 7323 F04L145: .dc.l F04L139 7324 7324 .dc.l F04L144 … … 7331 7331 .dc.l F04L144 7332 7332 .dc.l F04L141 7333 * 7333 7334 7334 F05L123: .dc.l F05L116 7335 7335 .dc.l F05L117 … … 7343 7343 .dc.l F05L122 7344 7344 .dc.l F05L119 7345 * 7345 7346 7346 F05L145: .dc.l F05L139 7347 7347 .dc.l F05L144 … … 7354 7354 .dc.l F05L144 7355 7355 .dc.l F05L141 7356 * 7356 7357 7357 F06L123: .dc.l F06L116 7358 7358 .dc.l F06L117 … … 7366 7366 .dc.l F06L122 7367 7367 .dc.l F06L119 7368 * 7368 7369 7369 F06L145: .dc.l F06L139 7370 7370 .dc.l F06L144 … … 7377 7377 .dc.l F06L144 7378 7378 .dc.l F06L141 7379 * 7379 7380 7380 F07L123: .dc.l F07L116 7381 7381 .dc.l F07L117 … … 7389 7389 .dc.l F07L122 7390 7390 .dc.l F07L119 7391 * 7391 7392 7392 F07L145: .dc.l F07L139 7393 7393 .dc.l F07L144 … … 7400 7400 .dc.l F07L144 7401 7401 .dc.l F07L141 7402 * 7402 7403 7403 F08L123: .dc.l F08L116 7404 7404 .dc.l F08L117 … … 7412 7412 .dc.l F08L122 7413 7413 .dc.l F08L119 7414 * 7414 7415 7415 F08L145: .dc.l F08L139 7416 7416 .dc.l F08L144 … … 7423 7423 .dc.l F08L144 7424 7424 .dc.l F08L141 7425 * 7425 7426 7426 F09L123: .dc.l F09L116 7427 7427 .dc.l F09L117 … … 7435 7435 .dc.l F09L122 7436 7436 .dc.l F09L119 7437 * 7437 7438 7438 F09L145: .dc.l F09L139 7439 7439 .dc.l F09L144 … … 7446 7446 .dc.l F09L144 7447 7447 .dc.l F09L141 7448 * 7448 7449 7449 F10L123: .dc.l F10L116 7450 7450 .dc.l F10L117 … … 7458 7458 .dc.l F10L122 7459 7459 .dc.l F10L119 7460 * 7460 7461 7461 F10L145: .dc.l F10L139 7462 7462 .dc.l F10L144 … … 7469 7469 .dc.l F10L144 7470 7470 .dc.l F10L141 7471 * 7471 7472 7472 F11L123: .dc.l F11L116 7473 7473 .dc.l F11L117 … … 7481 7481 .dc.l F11L122 7482 7482 .dc.l F11L119 7483 * 7483 7484 7484 F11L145: .dc.l F11L139 7485 7485 .dc.l F11L144 … … 7492 7492 .dc.l F11L144 7493 7493 .dc.l F11L141 7494 * 7494 7495 7495 F12L123: .dc.l F12L116 7496 7496 .dc.l F12L117 … … 7504 7504 .dc.l F12L122 7505 7505 .dc.l F12L119 7506 * 7506 7507 7507 F12L145: .dc.l F12L139 7508 7508 .dc.l F12L144 … … 7515 7515 .dc.l F12L144 7516 7516 .dc.l F12L141 7517 * 7518 *vbtab -- vbuf pointer table -- indexed by voice number7519 *----- ---------------------------------------------7517 7518 | vbtab -- vbuf pointer table -- indexed by voice number 7519 | ----- --------------------------------------------- 7520 7520 vbtab: .dc.l _vbufs 7521 7521 .dc.l _vbufs+VBLEN … … 7530 7530 .dc.l _vbufs+(10*VBLEN) 7531 7531 .dc.l _vbufs+(11*VBLEN) 7532 * 7532 7533 7533 .end -
ram/fpuint.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *fpuint.s -- process FPU interrupts / clear FPU3 *Version 63 -- 1988-08-31 -- D.N. Lynx Crowe4 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | fpuint.s -- process FPU interrupts / clear FPU 3 | Version 63 -- 1988-08-31 -- D.N. Lynx Crowe 4 | ------------------------------------------------------------------------------ 5 5 .text 6 * 7 .xdef _fpuint *process an FPU interrupt8 .xdef _fpuclr *reset the FPU9 .xdef _clrvce *quiet a voice10 * 11 .xdef _fputrap *a very good debug trap point12 * 13 .xdef _fp_resv *'spare' function reset value table14 .xdef _fpuifnc *FPU interrupt code (voice / function)15 * 16 .xref _irand *ranged random number function17 .xref _scope *diagnostic scope function18 .xref _xgetran *random number function19 * 6 7 .xdef _fpuint | process an FPU interrupt 8 .xdef _fpuclr | reset the FPU 9 .xdef _clrvce | quiet a voice 10 11 .xdef _fputrap | a very good debug trap point 12 13 .xdef _fp_resv | 'spare' function reset value table 14 .xdef _fpuifnc | FPU interrupt code (voice / function) 15 16 .xref _irand | ranged random number function 17 .xref _scope | diagnostic scope function 18 .xref _xgetran | random number function 19 20 20 .xref _expbit 21 21 .xref _funcndx … … 33 33 .xref _vce2trg 34 34 .xref _veltab 35 * 36 .page 37 *------------------------------------------------------------------------------38 *Register usage39 *--------------40 *d0 scratch41 *d1 FPU function index42 *d2 point index from FH_CPT (idfcpt)43 *d3 scratch44 *d4 jump point number from PT_PAR1 (ippar1)45 *d5 scratch46 * 47 *a0 scratch48 *a1 function header base49 *a2 point table base50 *a3 FPU base51 * 52 *------------------------------------------------------------------------------53 *FPU definitions54 *---------------55 * 56 UPD_BIT .equ $0001 *update bit (1 = update)57 INT_BIT .equ $0002 *int. bit (0 = disable)58 RAT_BIT .equ $0004 *ratio bit (0 = ratio)59 * 60 VSUBNBIT .equ 3 *new value select bit number61 VAL_BITS .equ $0018 *new value select bit mask62 * 63 MSK_RNVB .equ $000C *new value / ratio bits64 MSK_ONVB .equ $0010 *old new value bit65 * 66 FKILL .equ $0014 *kill value for function67 FSEND .equ $0015 *send new value to function68 * 69 CLREXP .equ $8000 *clear value for time exponent70 CLRMNT .equ $8000 *clear value for time mantissa71 * 72 *------------------------------------------------------------------------------73 *Miscellaneous definitions74 *-------------------------75 * 76 PCHMAX .equ 21920 *maximum pitch value77 VALMAX .equ 32000 *maximum value to send to FPU78 VALMIN .equ -32000 *minimum value to send to FPU79 * 80 LSPCH .equ 2 *left shift for sources to freq81 * 82 VALLEN .equ 10 *length of the 'valent' struct83 VT_VAL .equ 8 *value offset in 'valent'84 * 85 .page 86 *------------------------------------------------------------------------------87 *FPU addresses88 *-------------89 * 90 FPUBASE .equ $180000 *FPU base address91 * 92 FPUWST .equ FPUBASE *FPU waveshape base93 FPUFUNC .equ FPUBASE+$4000 *FPU function base94 FPUINT1 .equ FPUBASE+$4000 *FPU int. input address (R/O)95 FPUINT2 .equ FPUBASE+$6000 *FPU int. reset address (W/O)96 FPUCFG .equ FPUBASE+$5FE0 *FPU config. data address (W/O)97 * 98 F_CTL .equ $00 *control word99 F_VAL10 .equ $02 *new value "10"100 F_CV1 .equ $08 *control voltage 1101 F_SF1 .equ $0A *scale factor 1102 F_CV2 .equ $0C *control voltage 2103 F_SF2 .equ $0E *scale factor 2104 F_CV3 .equ $10 *control voltage 3105 F_SF3 .equ $12 *scale factor 3106 F_MNT .equ $14 *time mantissa107 F_EXP .equ $16 *time exponent108 F_VAL01 .equ $1C *new value "01"109 * 110 P_FREQ1 .equ $0020 *frequency 1111 P_FREQ2 .equ $0060 *frequency 2112 P_FREQ3 .equ $00A0 *frequency 3113 P_FREQ4 .equ $00E0 *frequency 4114 P_FILTER .equ $0140 *filter115 P_FILTRQ .equ $00C0 *filter q116 * 117 P_INDEX1 .equ $0120 *index 1118 P_INDEX2 .equ $0160 *index 2119 P_INDEX3 .equ $0180 *index 3120 P_INDEX4 .equ $01A0 *index 4121 P_INDEX5 .equ $01C0 *index 5122 P_INDEX6 .equ $01E0 *index 6123 * 124 P_LEVEL .equ $0040 *level125 * 126 P_LOCN .equ $0080 *location127 P_DYNAM .equ $0100 *dynamics128 * 129 .page 130 *------------------------------------------------------------------------------131 *Structure definitions132 *------------------------------------------------------------------------------133 *The following MUST match the idfnhdr structure definition in instdsp.h:134 * 135 FH_LEN .equ 12 *length of the idfnhdr structure136 * 137 FH_PCH .equ 0 *WORD - pitch offset (freq1 only)138 FH_MLT .equ 2 *WORD - overall value multiplier139 FH_SRC .equ 4 *BYTE - overall value source140 FH_PIF .equ 5 *BYTE - # of points in the function141 FH_PT1 .equ 6 *BYTE - index of first point142 FH_TMD .equ 7 *BYTE - trigger mode / control bits143 FH_CPT .equ 8 *BYTE - current point144 FH_PRM .equ 9 *BYTE - misc. function parameter145 FH_TRG .equ 10 *WORD - trigger146 * 147 I_ACTIVE .equ 1 *'Active' bit number (in FH_TMD)148 * 149 MSK_CTL .equ $001C *mask for FPU hardware bits (in FH_TMD)150 * 151 *------------------------------------------------------------------------------152 *The following MUST match the instpnt structure definition in instdsp.h:153 * 154 PT_LEN .equ 12 *length of the instpnt structure155 * 156 PT_TIM .equ 0 *WORD - time (packed)157 PT_VAL .equ 2 *WORD - value158 PT_VMLT .equ 4 *WORD - value multiplier159 PT_VSRC .equ 6 *BYTE - value source160 PT_ACT .equ 7 *BYTE - action161 PT_PAR1 .equ 8 *BYTE - parameter 1162 PT_PAR2 .equ 9 *BYTE - parameter 2163 PT_PAR3 .equ 10 *BYTE - parameter 3164 PT_PAD .equ 11 *BYTE - padding for even boundary165 * 166 MSK_MNT .equ $FFF0 *mask for mantissa (in PT_TIM)167 MSK_EXP .equ $000F *mask for exponent (in PT_TIM)168 * 169 MAX_ACT .equ 7 *maximum action code value170 * 171 .page 172 * 173 *------------------------------------------------------------------------------174 *pflist definitions -- must match those in instdsp.h175 * 176 PF_NEXT .equ0177 PF_TRIG .equ4178 PF_FUNC .equ6179 PF_D1 .equ8180 PF_D2 .equ12181 PF_D4 .equ16182 PF_A1 .equ20183 PF_A2 .equ24184 PF_A3 .equ28185 *------------------------------------------------------------------------------186 *Source definitions -- must match those in 'smdefs.h'187 * 188 SM_RAND .equ 1 *random189 SM_PTCH .equ 5 *pitch190 SM_KPRS .equ 6 *key pressure191 SM_KVEL .equ 7 *key velocity192 SM_FREQ .equ 10 *frequency193 * 194 .page 195 *------------------------------------------------------------------------------196 *_fpuint() -- process FPU interrupts197 * 198 *void199 *fpuint();200 * 201 *Processes FPU interrupts. Must be the target of vector 26,202 *which is Autovector Interrupt level 2.203 * 204 *------------------------------------------------------------------------------205 * 206 _fpuint: movem.l d0-d5/a0-a3,-(a7) *preserve registers we use207 move.w FPUINT1,d0 *read FPU interrupt status208 andi.w # $00FF,d0 *mask out garbage in MS bits209 move.w d0,_fpuifnc *save for later use210 move.w _ndisp,d1 *get display number211 cmpi.w #11,d1 *see if we display212 bne nodisp *jump if not213 * 214 tst.w _scopef *...215 beq nodisp *...216 * 217 move.w d0,-(a7) *display value218 jsr _scope *...219 tst.w (a7)+ *...220 * 221 move.w _fpuifnc,d0 *get FPU status222 * 223 nodisp: move.w d0,d1 *save in d1 (becomes function offset)224 * 225 lsl.w #5,d1 *develop FPU function offset226 lea FPUFUNC,a3 *setup FPU function base address227 * 228 lsl.w #3,d0 *develop funcndx[] index229 lea _funcndx,a0 *setup funcndx[] base address230 * 231 tst.l 0(a0,d0.W) *see if function is defined232 bne fnok *jump if so233 * 234 move.w d1,d0 *get function offset in d0235 andi.w # $1E00,d0 *mask for voice number236 cmpi.w # $1800,d0 *see if it's a real voice (0..11)237 bge fpexit *don't send a kill if not a real voice238 * 239 move.w #FKILL,F_CTL(a3,d1.W) *kill the undefined function240 * 241 fpexit: clr.w FPUINT2 *reset the FPU interrupt latch242 movem.l (a7)+,d0-d5/a0-a3 *restore the registers243 rte *return to interrupted code244 * 245 .page 246 *------------------------------------------------------------------------------247 *set up to process active functions, stop ones that should be inactive248 *------------------------------------------------------------------------------249 fnok: movea.l 0(a0,d0.W),a1 *get pointer to function header250 movea.l 4(a0,d0.W),a2 *get pointer to point table251 btst #I_ACTIVE,FH_TMD(a1) *see if function is active252 bne doact *go process action if so253 * 254 *------------------------------------------------------------------------------255 *stop a function256 *------------------------------------------------------------------------------257 stopfn: move.b FH_TMD(a1),d0 *get function control bits258 andi.w #MSK_RNVB,d0 *mask for ratio / new new-value bit259 move.w d0,d3 *isolate new new-value bit260 add.w d3,d3 *... from function header261 andi.w #MSK_ONVB,d3 *... shift to old new-value bit262 or.w d3,d0 * ... and put new bit in old bit263 move.w d0,F_CTL(a3,d1.W) *stop the function264 bclr #I_ACTIVE,FH_TMD(a1) *reset the active bit265 bra fpexit *go restore registers and exit266 * 267 .page 268 *------------------------------------------------------------------------------269 *setup for and dispatch to the proper action handler270 *------------------------------------------------------------------------------271 doact: clr.w d2 *get current point index in d2272 move.b FH_CPT(a1),d2 *...273 lsl.w #2,d2 *multiply it by the length of a point274 move.w d2,d0 *... (fast multiply by PT_LEN = 12275 add.w d2,d2 *... via shift and add)276 add.w d0,d2 *...277 clr.w d4 *get jump point # into d4278 move.b PT_PAR1(a2,d2.W),d4 *...279 clr.w d3 *get action code in d3280 move.b PT_ACT(a2,d2.W),d3 *...281 cmpi.b #MAX_ACT,d3 *check against the limit282 bgt stopfn *stop things if it's a bad action code283 * 284 lsl.w #2,d3 *develop index to action dispatch table285 lea actab,a0 *get the address of the action handler286 movea.l 0(a0,d3.W),a0 *...287 * 288 *------------------------------------------------------------------------------289 *At this point we're ready to do the action associated with the point,290 *and the registers are set up, and will remain, as follows:291 * 292 *d1 FPU function index a1 function header base293 *d2 point table index a2 point table base294 *a3 FPU function base295 *d4 jump point number296 * 297 *d0, d3, d5, and a0 are used as scratch throughout the code.298 * 299 *------------------------------------------------------------------------------300 * 301 _fputrap: jmp (a0) *dispatch to action handler302 * 303 .page 304 *------------------------------------------------------------------------------305 *act0 -- AC_NULL -- no action306 *---- --------------------307 act0: move.b FH_PT1(a1),d0 *get first point number308 add.b FH_PIF(a1),d0 *add number of points in function309 subq.b #1,d0 *make it last point number310 cmp.b FH_CPT(a1),d0 *see if we're at the last point311 beq stopfn *stop function if so312 * 313 addq.b #1,FH_CPT(a1) *update function header for next point314 addi.w #PT_LEN,d2 *advance the point index315 * 316 *------------------------------------------------------------------------------317 *outseg -- output a segment318 *------ ----------------319 outseg: move.w PT_TIM(a2,d2.w),d3 *get packed time320 move.w d3,d0 *extract mantissa321 andi.w #MSK_MNT,d0 *...322 mulu _timemlt,d0 *multiply by panel time pot value323 lsr.l #8,d0 *... and scale it324 lsr.l #7,d0 *...325 move.w d0,F_MNT(a3,d1.W) *send mantissa to FPU326 andi.w #MSK_EXP,d3 *extract exponent code327 add.w d3,d3 *look up decoded exponent328 lea _expbit,a0 *... in expbit329 move.w 0(a0,d3.W),F_EXP(a3,d1.W) *send exponent to FPU330 move.w PT_VAL(a2,d2.W),d3 *get the function value331 * 332 *------------------------------------------------------------------------------333 *get the point source, if any334 *------------------------------------------------------------------------------335 tst.w PT_VMLT(a2,d2.W) *see if we have a point mlt.336 beq nosrc *don't do anything for zero337 * 338 clr.w d0 *get the source number339 move.b PT_VSRC(a2,d2.W),d0 *...340 beq nosrc *don't do anything for zero341 * 342 *------------------------------------------------------------------------------343 *SM_RAND -- random344 *------------------------------------------------------------------------------345 cmpi.w #SM_RAND,d0 *is this the random source ?346 bne srctyp0 *jump if not347 * 348 movem.l d1-d2/a0-a2,-(a7) *preserve registers around call349 move.w PT_VMLT(a2,d2.W),-(a7) *pass multiplier to xgetran()350 jsr _xgetran *call for a random number351 tst.w (a7)+ *clean up stack352 movem.l (a7)+,d1-d2/a0-a2 *restore registers353 move.w d0,d5 *put random value in the value register354 bra applym *go apply the multiplier355 * 356 .page 357 *------------------------------------------------------------------------------358 *SM_FREQ -- frequency359 *------------------------------------------------------------------------------360 srctyp0: cmpi.w #SM_FREQ,d0 *is this the frequency source ?361 bne srctyp1 *jump if not362 * 363 move.w (a1),d0 *get the pitch364 lsr.w #6,d0 *shift to a word index365 andi.w # $01FE,d0 *mask out extraneous bits366 lea _ptoftab,a0 *get entry from ptoftab[]367 move.w 0(a0,d0.W),d5 *...368 bra applym *go apply the multiplier369 * 370 *------------------------------------------------------------------------------371 *SM_PTCH -- pitch372 *------------------------------------------------------------------------------373 srctyp1: cmpi.w #SM_PTCH,d0 *is this the pitch source ?374 bne srctyp2 *jump if not375 * 376 move.w (a1),d5 *get the pitch as the value377 bra applym *go apply the multiplier378 * 379 *------------------------------------------------------------------------------380 *SM_KVEL -- velocity381 *------------------------------------------------------------------------------382 srctyp2: cmpi.w #SM_KVEL,d0 *is this the key velocity source ?383 bne srctyp3 *jump if not384 * 385 move.w FH_TRG(a1),d0 *get the trigger number386 add.w d0,d0 *... as a word index387 lea _veltab,a0 *... into veltab[]388 move.w 0(a0,d0.W),d5 *get the velocity from veltab[trg]389 bra applym *go apply the multiplier390 * 391 *------------------------------------------------------------------------------392 *SM_KPRS -- pressure393 *------------------------------------------------------------------------------394 srctyp3: cmpi.w #SM_KPRS,d0 *is this the key pressure source ?395 bne srctyp4 *jump if not (must be an analog input)396 * 397 move.w FH_TRG(a1),d0 *get the trigger number398 add.w d0,d0 *... as a word index399 lea _prstab,a0 *... into prstab[]400 move.w 0(a0,d0.W),d5 *get the pressure from prstab[trg]401 bra applym *go apply the multiplier402 * 403 .page 404 *------------------------------------------------------------------------------405 *all other sources come out of the valents[] array406 *------------------------------------------------------------------------------407 srctyp4: lea _vce2grp,a0 *point at vce2grp[]408 move.w _fpuifnc,d5 *get voice number in d5409 lsr.w #3,d5 *...410 andi.w # $001E,d5 *... as a word index411 move.w 0(a0,d5.W),d5 *get the group number412 subq.w #1,d5 *...413 lsl.w #4,d5 *shift it left a nybble414 or.w d5,d0 *OR it into the source number415 add.w d0,d0 *make source number a valents[] index416 move.w d0,d5 *... (fast multiply by VALLEN = 10417 lsl.w #2,d0 *... via shift and add)418 add.w d5,d0 *...419 lea _valents,a0 *get base of valents[]420 move.w VT_VAL(a0,d0.W),d5 *get value421 * 422 *------------------------------------------------------------------------------423 *apply the multiplier to the source, and add it to the function value424 *------------------------------------------------------------------------------425 applym: muls PT_VMLT(a2,d2.W),d5 *apply the multiplier426 asr.l #7,d5 *scale the result427 asr.l #8,d5 *...428 ext.l d3 *add the function value429 add.l d3,d5 *...430 cmpi.l #VALMAX,d5 *check for overflow431 ble srcmlt1 *jump if no overflow432 * 433 move.l #VALMAX,d5 *limit at VALMAX434 bra srcmlt2 *...435 * 436 srcmlt1: cmpi.l #VALMIN,d5 *check for underflow437 bge srcmlt2 *jump if no underflow438 * 439 move.l #VALMIN,d5 *limit at VALMIN440 * 441 srcmlt2: move.w d5,d3 *setup value for output to FPU442 * 443 .page 444 *------------------------------------------------------------------------------445 *adjust the value according to the function type446 *------------------------------------------------------------------------------447 nosrc: move.w d1,d0 *get function type448 andi.w # $01E0,d0 *...449 * 450 *------------------------------------------------------------------------------451 *level or location452 *------------------------------------------------------------------------------453 cmpi.w #P_LEVEL,d0 *see if it's the level454 beq outsegl *jump if so455 * 456 cmpi.w #P_LOCN,d0 *see if it's the location457 bne outsegf *jump if not458 * 459 tst.w d3 *check sign of value460 bpl outsegc *jump if positive461 * 462 clr.w d3 *force negative values to 0463 * 464 outsegc: asr.w #5,d3 *shift value to LS bits465 sub.w #500,d3 *subtract 5.00 from value466 asl.w #6,d3 *readjust to MS bits467 bra outseg3 *go output the value468 * 469 outsegl: tst.w d3 *check sign of value470 bpl outsegm *jump if positive471 * 472 clr.w d3 *limit negative values at 0473 * 474 outsegm: asr.w #5,d3 *shift value to LS bits475 sub.w #500,d3 *subtract 5.00 from value476 asl.w #6,d3 *readjust to MS bits477 bra outseg3 *go output the value478 * 479 .page 480 *------------------------------------------------------------------------------481 *filter482 *------------------------------------------------------------------------------483 outsegf: cmpi.w #P_FILTER,d0 *see if it's filter484 bne outsegp *jump if not485 * 486 ext.l d3 *make function value a long487 asr.l #1,d3 *multiply function value by .75488 move.l d3,d0 *... (fast multiply by .75489 asr.l #1,d0 *... via shift and add)490 add.l d0,d3 *...491 move.w (a1),d0 *add pitch492 ext.l d0 *...493 add.l d0,d3 *...494 cmpi.l #VALMAX,d3 *see if it's within limits495 ble outsega *...496 * 497 move.w #VALMAX,d3 *limit at VALMAX498 bra outseg3 *...499 * 500 outsega: cmpi.l #VALMIN,d3 *...501 bge outseg3 *...502 * 503 move.w #VALMIN,d3 *limit at VALMIN504 bra outseg3 *...505 * 506 .page 507 *------------------------------------------------------------------------------508 *freq 1..4509 *------------------------------------------------------------------------------510 outsegp: cmpi.w #P_FREQ1,d0 *see if it's freq1511 beq outseg0 *go process freq1512 * 513 outsegq: cmpi.w #P_FREQ2,d0 *see if it's freq2514 beq outseg0 *process it if so515 * 516 cmpi.w #P_FREQ3,d0 *see if it's freq3517 beq outseg0 *process it if so518 * 519 cmpi.w #P_FREQ4,d0 *see if it's freq4520 bne outseg3 *jump if not521 * 522 outseg0: ext.l d3 *scale the point value to cents offset523 asr.l #5,d3 *...524 sub.l #500,d3 *... value - 500525 asl.l #LSPCH,d3 *mult. by 2 and scale for 1/2 cent lsb526 move.w (a1),d0 *add pitch from function header527 ext.l d0 *...528 add.l d0,d3 *...529 cmp.l #PCHMAX,d3 *see if result is valid530 ble outseg3 *jump if within pitch limits531 * 532 move.l #PCHMAX,d3 *limit at maximum pitch533 * 534 *------------------------------------------------------------------------------535 *send the value to the FPU536 *------------------------------------------------------------------------------537 outseg3: move.b FH_TMD(a1),d0 *get hardware bits from function header538 eor.w #VAL_BITS,d0 *toggle new value select bits539 move.b d0,FH_TMD(a1) *store updated word540 btst.l #VSUBNBIT,d0 *check which value address to use35 36 .page 37 | ------------------------------------------------------------------------------ 38 | Register usage 39 | -------------- 40 | d0 scratch 41 | d1 FPU function index 42 | d2 point index from FH_CPT (idfcpt) 43 | d3 scratch 44 | d4 jump point number from PT_PAR1 (ippar1) 45 | d5 scratch 46 47 | a0 scratch 48 | a1 function header base 49 | a2 point table base 50 | a3 FPU base 51 52 | ------------------------------------------------------------------------------ 53 | FPU definitions 54 | --------------- 55 56 UPD_BIT = 0x0001 | update bit (1 = update) 57 INT_BIT = 0x0002 | int. bit (0 = disable) 58 RAT_BIT = 0x0004 | ratio bit (0 = ratio) 59 60 VSUBNBIT = 3 | new value select bit number 61 VAL_BITS = 0x0018 | new value select bit mask 62 63 MSK_RNVB = 0x000C | new value / ratio bits 64 MSK_ONVB = 0x0010 | old new value bit 65 66 FKILL = 0x0014 | kill value for function 67 FSEND = 0x0015 | send new value to function 68 69 CLREXP = 0x8000 | clear value for time exponent 70 CLRMNT = 0x8000 | clear value for time mantissa 71 72 | ------------------------------------------------------------------------------ 73 | Miscellaneous definitions 74 | ------------------------- 75 76 PCHMAX = 21920 | maximum pitch value 77 VALMAX = 32000 | maximum value to send to FPU 78 VALMIN = -32000 | minimum value to send to FPU 79 80 LSPCH = 2 | left shift for sources to freq 81 82 VALLEN = 10 | length of the 'valent' struct 83 VT_VAL = 8 | value offset in 'valent' 84 85 .page 86 | ------------------------------------------------------------------------------ 87 | FPU addresses 88 | ------------- 89 90 FPUBASE = 0x180000 | FPU base address 91 92 FPUWST = FPUBASE | FPU waveshape base 93 FPUFUNC = FPUBASE+0x4000 | FPU function base 94 FPUINT1 = FPUBASE+0x4000 | FPU int. input address (R/O) 95 FPUINT2 = FPUBASE+0x6000 | FPU int. reset address (W/O) 96 FPUCFG = FPUBASE+0x5FE0 | FPU config. data address (W/O) 97 98 F_CTL = 0x00 | control word 99 F_VAL10 = 0x02 | new value "10" 100 F_CV1 = 0x08 | control voltage 1 101 F_SF1 = 0x0A | scale factor 1 102 F_CV2 = 0x0C | control voltage 2 103 F_SF2 = 0x0E | scale factor 2 104 F_CV3 = 0x10 | control voltage 3 105 F_SF3 = 0x12 | scale factor 3 106 F_MNT = 0x14 | time mantissa 107 F_EXP = 0x16 | time exponent 108 F_VAL01 = 0x1C | new value "01" 109 110 P_FREQ1 = 0x0020 | frequency 1 111 P_FREQ2 = 0x0060 | frequency 2 112 P_FREQ3 = 0x00A0 | frequency 3 113 P_FREQ4 = 0x00E0 | frequency 4 114 P_FILTER = 0x0140 | filter 115 P_FILTRQ = 0x00C0 | filter q 116 117 P_INDEX1 = 0x0120 | index 1 118 P_INDEX2 = 0x0160 | index 2 119 P_INDEX3 = 0x0180 | index 3 120 P_INDEX4 = 0x01A0 | index 4 121 P_INDEX5 = 0x01C0 | index 5 122 P_INDEX6 = 0x01E0 | index 6 123 124 P_LEVEL = 0x0040 | level 125 126 P_LOCN = 0x0080 | location 127 P_DYNAM = 0x0100 | dynamics 128 129 .page 130 | ------------------------------------------------------------------------------ 131 | Structure definitions 132 | ------------------------------------------------------------------------------ 133 | The following MUST match the idfnhdr structure definition in instdsp.h: 134 135 FH_LEN = 12 | length of the idfnhdr structure 136 137 FH_PCH = 0 | WORD - pitch offset (freq1 only) 138 FH_MLT = 2 | WORD - overall value multiplier 139 FH_SRC = 4 | BYTE - overall value source 140 FH_PIF = 5 | BYTE - # of points in the function 141 FH_PT1 = 6 | BYTE - index of first point 142 FH_TMD = 7 | BYTE - trigger mode / control bits 143 FH_CPT = 8 | BYTE - current point 144 FH_PRM = 9 | BYTE - misc. function parameter 145 FH_TRG = 10 | WORD - trigger 146 147 I_ACTIVE = 1 | 'Active' bit number (in FH_TMD) 148 149 MSK_CTL = 0x001C | mask for FPU hardware bits (in FH_TMD) 150 151 | ------------------------------------------------------------------------------ 152 | The following MUST match the instpnt structure definition in instdsp.h: 153 154 PT_LEN = 12 | length of the instpnt structure 155 156 PT_TIM = 0 | WORD - time (packed) 157 PT_VAL = 2 | WORD - value 158 PT_VMLT = 4 | WORD - value multiplier 159 PT_VSRC = 6 | BYTE - value source 160 PT_ACT = 7 | BYTE - action 161 PT_PAR1 = 8 | BYTE - parameter 1 162 PT_PAR2 = 9 | BYTE - parameter 2 163 PT_PAR3 = 10 | BYTE - parameter 3 164 PT_PAD = 11 | BYTE - padding for even boundary 165 166 MSK_MNT = 0xFFF0 | mask for mantissa (in PT_TIM) 167 MSK_EXP = 0x000F | mask for exponent (in PT_TIM) 168 169 MAX_ACT = 7 | maximum action code value 170 171 .page 172 173 | ------------------------------------------------------------------------------ 174 | pflist definitions -- must match those in instdsp.h 175 176 PF_NEXT = 0 177 PF_TRIG = 4 178 PF_FUNC = 6 179 PF_D1 = 8 180 PF_D2 = 12 181 PF_D4 = 16 182 PF_A1 = 20 183 PF_A2 = 24 184 PF_A3 = 28 185 | ------------------------------------------------------------------------------ 186 | Source definitions -- must match those in 'smdefs.h' 187 188 SM_RAND = 1 | random 189 SM_PTCH = 5 | pitch 190 SM_KPRS = 6 | key pressure 191 SM_KVEL = 7 | key velocity 192 SM_FREQ = 10 | frequency 193 194 .page 195 | ------------------------------------------------------------------------------ 196 | _fpuint() -- process FPU interrupts 197 198 | void 199 | fpuint(); 200 201 | Processes FPU interrupts. Must be the target of vector 26, 202 | which is Autovector Interrupt level 2. 203 204 | ------------------------------------------------------------------------------ 205 206 _fpuint: movem.l d0-d5/a0-a3,-(a7) | preserve registers we use 207 move.w FPUINT1,d0 | read FPU interrupt status 208 andi.w #0x00FF,d0 | mask out garbage in MS bits 209 move.w d0,_fpuifnc | save for later use 210 move.w _ndisp,d1 | get display number 211 cmpi.w #11,d1 | see if we display 212 bne nodisp | jump if not 213 214 tst.w _scopef | ... 215 beq nodisp | ... 216 217 move.w d0,-(a7) | display value 218 jsr _scope | ... 219 tst.w (a7)+ | ... 220 221 move.w _fpuifnc,d0 | get FPU status 222 223 nodisp: move.w d0,d1 | save in d1 (becomes function offset) 224 225 lsl.w #5,d1 | develop FPU function offset 226 lea FPUFUNC,a3 | setup FPU function base address 227 228 lsl.w #3,d0 | develop funcndx[] index 229 lea _funcndx,a0 | setup funcndx[] base address 230 231 tst.l 0(a0,d0.W) | see if function is defined 232 bne fnok | jump if so 233 234 move.w d1,d0 | get function offset in d0 235 andi.w #0x1E00,d0 | mask for voice number 236 cmpi.w #0x1800,d0 | see if it's a real voice (0..11) 237 bge fpexit | don't send a kill if not a real voice 238 239 move.w #FKILL,F_CTL(a3,d1.W) | kill the undefined function 240 241 fpexit: clr.w FPUINT2 | reset the FPU interrupt latch 242 movem.l (a7)+,d0-d5/a0-a3 | restore the registers 243 rte | return to interrupted code 244 245 .page 246 | ------------------------------------------------------------------------------ 247 | set up to process active functions, stop ones that should be inactive 248 | ------------------------------------------------------------------------------ 249 fnok: movea.l 0(a0,d0.W),a1 | get pointer to function header 250 movea.l 4(a0,d0.W),a2 | get pointer to point table 251 btst #I_ACTIVE,FH_TMD(a1) | see if function is active 252 bne doact | go process action if so 253 254 | ------------------------------------------------------------------------------ 255 | stop a function 256 | ------------------------------------------------------------------------------ 257 stopfn: move.b FH_TMD(a1),d0 | get function control bits 258 andi.w #MSK_RNVB,d0 | mask for ratio / new new-value bit 259 move.w d0,d3 | isolate new new-value bit 260 add.w d3,d3 | ... from function header 261 andi.w #MSK_ONVB,d3 | ... shift to old new-value bit 262 or.w d3,d0 | ... and put new bit in old bit 263 move.w d0,F_CTL(a3,d1.W) | stop the function 264 bclr #I_ACTIVE,FH_TMD(a1) | reset the active bit 265 bra fpexit | go restore registers and exit 266 267 .page 268 | ------------------------------------------------------------------------------ 269 | setup for and dispatch to the proper action handler 270 | ------------------------------------------------------------------------------ 271 doact: clr.w d2 | get current point index in d2 272 move.b FH_CPT(a1),d2 | ... 273 lsl.w #2,d2 | multiply it by the length of a point 274 move.w d2,d0 | ... (fast multiply by PT_LEN = 12 275 add.w d2,d2 | ... via shift and add) 276 add.w d0,d2 | ... 277 clr.w d4 | get jump point # into d4 278 move.b PT_PAR1(a2,d2.W),d4 | ... 279 clr.w d3 | get action code in d3 280 move.b PT_ACT(a2,d2.W),d3 | ... 281 cmpi.b #MAX_ACT,d3 | check against the limit 282 bgt stopfn | stop things if it's a bad action code 283 284 lsl.w #2,d3 | develop index to action dispatch table 285 lea actab,a0 | get the address of the action handler 286 movea.l 0(a0,d3.W),a0 | ... 287 288 | ------------------------------------------------------------------------------ 289 | At this point we're ready to do the action associated with the point, 290 | and the registers are set up, and will remain, as follows: 291 292 | d1 FPU function index a1 function header base 293 | d2 point table index a2 point table base 294 | a3 FPU function base 295 | d4 jump point number 296 297 | d0, d3, d5, and a0 are used as scratch throughout the code. 298 299 | ------------------------------------------------------------------------------ 300 301 _fputrap: jmp (a0) | dispatch to action handler 302 303 .page 304 | ------------------------------------------------------------------------------ 305 | act0 -- AC_NULL -- no action 306 | ---- -------------------- 307 act0: move.b FH_PT1(a1),d0 | get first point number 308 add.b FH_PIF(a1),d0 | add number of points in function 309 subq.b #1,d0 | make it last point number 310 cmp.b FH_CPT(a1),d0 | see if we're at the last point 311 beq stopfn | stop function if so 312 313 addq.b #1,FH_CPT(a1) | update function header for next point 314 addi.w #PT_LEN,d2 | advance the point index 315 316 | ------------------------------------------------------------------------------ 317 | outseg -- output a segment 318 | ------ ---------------- 319 outseg: move.w PT_TIM(a2,d2.w),d3 | get packed time 320 move.w d3,d0 | extract mantissa 321 andi.w #MSK_MNT,d0 | ... 322 mulu _timemlt,d0 | multiply by panel time pot value 323 lsr.l #8,d0 | ... and scale it 324 lsr.l #7,d0 | ... 325 move.w d0,F_MNT(a3,d1.W) | send mantissa to FPU 326 andi.w #MSK_EXP,d3 | extract exponent code 327 add.w d3,d3 | look up decoded exponent 328 lea _expbit,a0 | ... in expbit 329 move.w 0(a0,d3.W),F_EXP(a3,d1.W) | send exponent to FPU 330 move.w PT_VAL(a2,d2.W),d3 | get the function value 331 332 | ------------------------------------------------------------------------------ 333 | get the point source, if any 334 | ------------------------------------------------------------------------------ 335 tst.w PT_VMLT(a2,d2.W) | see if we have a point mlt. 336 beq nosrc | don't do anything for zero 337 338 clr.w d0 | get the source number 339 move.b PT_VSRC(a2,d2.W),d0 | ... 340 beq nosrc | don't do anything for zero 341 342 | ------------------------------------------------------------------------------ 343 | SM_RAND -- random 344 | ------------------------------------------------------------------------------ 345 cmpi.w #SM_RAND,d0 | is this the random source ? 346 bne srctyp0 | jump if not 347 348 movem.l d1-d2/a0-a2,-(a7) | preserve registers around call 349 move.w PT_VMLT(a2,d2.W),-(a7) | pass multiplier to xgetran() 350 jsr _xgetran | call for a random number 351 tst.w (a7)+ | clean up stack 352 movem.l (a7)+,d1-d2/a0-a2 | restore registers 353 move.w d0,d5 | put random value in the value register 354 bra applym | go apply the multiplier 355 356 .page 357 | ------------------------------------------------------------------------------ 358 | SM_FREQ -- frequency 359 | ------------------------------------------------------------------------------ 360 srctyp0: cmpi.w #SM_FREQ,d0 | is this the frequency source ? 361 bne srctyp1 | jump if not 362 363 move.w (a1),d0 | get the pitch 364 lsr.w #6,d0 | shift to a word index 365 andi.w #0x01FE,d0 | mask out extraneous bits 366 lea _ptoftab,a0 | get entry from ptoftab[] 367 move.w 0(a0,d0.W),d5 | ... 368 bra applym | go apply the multiplier 369 370 | ------------------------------------------------------------------------------ 371 | SM_PTCH -- pitch 372 | ------------------------------------------------------------------------------ 373 srctyp1: cmpi.w #SM_PTCH,d0 | is this the pitch source ? 374 bne srctyp2 | jump if not 375 376 move.w (a1),d5 | get the pitch as the value 377 bra applym | go apply the multiplier 378 379 | ------------------------------------------------------------------------------ 380 | SM_KVEL -- velocity 381 | ------------------------------------------------------------------------------ 382 srctyp2: cmpi.w #SM_KVEL,d0 | is this the key velocity source ? 383 bne srctyp3 | jump if not 384 385 move.w FH_TRG(a1),d0 | get the trigger number 386 add.w d0,d0 | ... as a word index 387 lea _veltab,a0 | ... into veltab[] 388 move.w 0(a0,d0.W),d5 | get the velocity from veltab[trg] 389 bra applym | go apply the multiplier 390 391 | ------------------------------------------------------------------------------ 392 | SM_KPRS -- pressure 393 | ------------------------------------------------------------------------------ 394 srctyp3: cmpi.w #SM_KPRS,d0 | is this the key pressure source ? 395 bne srctyp4 | jump if not (must be an analog input) 396 397 move.w FH_TRG(a1),d0 | get the trigger number 398 add.w d0,d0 | ... as a word index 399 lea _prstab,a0 | ... into prstab[] 400 move.w 0(a0,d0.W),d5 | get the pressure from prstab[trg] 401 bra applym | go apply the multiplier 402 403 .page 404 | ------------------------------------------------------------------------------ 405 | all other sources come out of the valents[] array 406 | ------------------------------------------------------------------------------ 407 srctyp4: lea _vce2grp,a0 | point at vce2grp[] 408 move.w _fpuifnc,d5 | get voice number in d5 409 lsr.w #3,d5 | ... 410 andi.w #0x001E,d5 | ... as a word index 411 move.w 0(a0,d5.W),d5 | get the group number 412 subq.w #1,d5 | ... 413 lsl.w #4,d5 | shift it left a nybble 414 or.w d5,d0 | OR it into the source number 415 add.w d0,d0 | make source number a valents[] index 416 move.w d0,d5 | ... (fast multiply by VALLEN = 10 417 lsl.w #2,d0 | ... via shift and add) 418 add.w d5,d0 | ... 419 lea _valents,a0 | get base of valents[] 420 move.w VT_VAL(a0,d0.W),d5 | get value 421 422 | ------------------------------------------------------------------------------ 423 | apply the multiplier to the source, and add it to the function value 424 | ------------------------------------------------------------------------------ 425 applym: muls PT_VMLT(a2,d2.W),d5 | apply the multiplier 426 asr.l #7,d5 | scale the result 427 asr.l #8,d5 | ... 428 ext.l d3 | add the function value 429 add.l d3,d5 | ... 430 cmpi.l #VALMAX,d5 | check for overflow 431 ble srcmlt1 | jump if no overflow 432 433 move.l #VALMAX,d5 | limit at VALMAX 434 bra srcmlt2 | ... 435 436 srcmlt1: cmpi.l #VALMIN,d5 | check for underflow 437 bge srcmlt2 | jump if no underflow 438 439 move.l #VALMIN,d5 | limit at VALMIN 440 441 srcmlt2: move.w d5,d3 | setup value for output to FPU 442 443 .page 444 | ------------------------------------------------------------------------------ 445 | adjust the value according to the function type 446 | ------------------------------------------------------------------------------ 447 nosrc: move.w d1,d0 | get function type 448 andi.w #0x01E0,d0 | ... 449 450 | ------------------------------------------------------------------------------ 451 | level or location 452 | ------------------------------------------------------------------------------ 453 cmpi.w #P_LEVEL,d0 | see if it's the level 454 beq outsegl | jump if so 455 456 cmpi.w #P_LOCN,d0 | see if it's the location 457 bne outsegf | jump if not 458 459 tst.w d3 | check sign of value 460 bpl outsegc | jump if positive 461 462 clr.w d3 | force negative values to 0 463 464 outsegc: asr.w #5,d3 | shift value to LS bits 465 sub.w #500,d3 | subtract 5.00 from value 466 asl.w #6,d3 | readjust to MS bits 467 bra outseg3 | go output the value 468 469 outsegl: tst.w d3 | check sign of value 470 bpl outsegm | jump if positive 471 472 clr.w d3 | limit negative values at 0 473 474 outsegm: asr.w #5,d3 | shift value to LS bits 475 sub.w #500,d3 | subtract 5.00 from value 476 asl.w #6,d3 | readjust to MS bits 477 bra outseg3 | go output the value 478 479 .page 480 | ------------------------------------------------------------------------------ 481 | filter 482 | ------------------------------------------------------------------------------ 483 outsegf: cmpi.w #P_FILTER,d0 | see if it's filter 484 bne outsegp | jump if not 485 486 ext.l d3 | make function value a long 487 asr.l #1,d3 | multiply function value by .75 488 move.l d3,d0 | ... (fast multiply by .75 489 asr.l #1,d0 | ... via shift and add) 490 add.l d0,d3 | ... 491 move.w (a1),d0 | add pitch 492 ext.l d0 | ... 493 add.l d0,d3 | ... 494 cmpi.l #VALMAX,d3 | see if it's within limits 495 ble outsega | ... 496 497 move.w #VALMAX,d3 | limit at VALMAX 498 bra outseg3 | ... 499 500 outsega: cmpi.l #VALMIN,d3 | ... 501 bge outseg3 | ... 502 503 move.w #VALMIN,d3 | limit at VALMIN 504 bra outseg3 | ... 505 506 .page 507 | ------------------------------------------------------------------------------ 508 | freq 1..4 509 | ------------------------------------------------------------------------------ 510 outsegp: cmpi.w #P_FREQ1,d0 | see if it's freq1 511 beq outseg0 | go process freq1 512 513 outsegq: cmpi.w #P_FREQ2,d0 | see if it's freq2 514 beq outseg0 | process it if so 515 516 cmpi.w #P_FREQ3,d0 | see if it's freq3 517 beq outseg0 | process it if so 518 519 cmpi.w #P_FREQ4,d0 | see if it's freq4 520 bne outseg3 | jump if not 521 522 outseg0: ext.l d3 | scale the point value to cents offset 523 asr.l #5,d3 | ... 524 sub.l #500,d3 | ... value - 500 525 asl.l #LSPCH,d3 | mult. by 2 and scale for 1/2 cent lsb 526 move.w (a1),d0 | add pitch from function header 527 ext.l d0 | ... 528 add.l d0,d3 | ... 529 cmp.l #PCHMAX,d3 | see if result is valid 530 ble outseg3 | jump if within pitch limits 531 532 move.l #PCHMAX,d3 | limit at maximum pitch 533 534 | ------------------------------------------------------------------------------ 535 | send the value to the FPU 536 | ------------------------------------------------------------------------------ 537 outseg3: move.b FH_TMD(a1),d0 | get hardware bits from function header 538 eor.w #VAL_BITS,d0 | toggle new value select bits 539 move.b d0,FH_TMD(a1) | store updated word 540 btst.l #VSUBNBIT,d0 | check which value address to use 541 541 beq outseg1 542 * 543 move.w d3,F_VAL01(a3,d1.W) *send value to FPU542 543 move.w d3,F_VAL01(a3,d1.W) | send value to FPU 544 544 bra outseg2 545 * 546 outseg1: move.w d3,F_VAL10(a3,d1.W) *send value to FPU547 * 548 outseg2: andi.w #MSK_CTL,d0 *mask off software bits549 ori.w #UPD_BIT+INT_BIT,d0 *set the update & !lastseg bits550 move.w d0,F_CTL(a3,d1.W) *send control word to FPU551 bra fpexit *done -- exit552 * 553 .page 554 * 555 *------------------------------------------------------------------------------556 *act1 -- AC_SUST -- pause if key is down (sustain)557 *---- ------------------------------------------558 act1: move.w _fpuifnc,d0 *get voice as a word index559 lsr.w #3,d0 *...560 andi.w # $001E,d0 *...561 lea _vce2trg,a0 *point at voice to trigger table562 move.w 0(a0,d0.W),d0 *get trigger table entry into d0563 cmpi.w #-1,d0 *see if voice is free564 beq act0 *continue function if so565 * 566 btst #15,d0 *see if voice is held by a pedal567 bne act1a *sustain if so568 * 569 btst #14,d0 *see if voice is sustained by a pedal570 bne act1a *sustain if so571 * 572 lea _trgtab,a0 *point at trigger table573 tst.b 0(a0,d0.W) *check trigger status574 beq act0 *continue function if not active575 * 576 act1a: move.l _pfqhdr,d3 *see if any pflist entries remain577 beq act0 *continue if not (shouldn't happen!)578 * 579 move.b FH_PT1(a1),d0 *get first point number580 add.b FH_PIF(a1),d0 *add base to first point581 subq.b #1,d0 *make d0 last point number582 cmp.b FH_CPT(a1),d0 *check current point number583 beq stopfn *done if this is the last point584 * 585 addq.b #1,FH_CPT(a1) *update current point number586 addi.w #PT_LEN,d2 *advance the point index587 movea.l d3,a0 *acquire a new pflist entry588 move.l (a0),_pfqhdr *...589 move.l _pflist,(a0) *chain it to pflist590 move.l a0,_pflist *...591 move.w FH_TRG(a1),PF_TRIG(a0) *set trigger number in entry592 move.w _fpuifnc,PF_FUNC(a0) *set v/p word in entry593 movem.l d1-d2/d4/a1-a3,PF_D1(a0) *set registers in entry594 move.b FH_TMD(a1),d0 *stop the function595 andi.w #MSK_RNVB,d0 *...596 move.w d0,d3 *...597 add.w d3,d3 *...598 andi.w #MSK_ONVB,d3 *...599 or.w d3,d0 *...600 move.w d0,F_CTL(a3,d1.W) *...601 bra fpexit *exit602 * 603 .page 604 * 605 *------------------------------------------------------------------------------606 *act2 -- AC_ENBL -- stop if key is up607 *---- ----------------------------608 act2: move.w _fpuifnc,d0 *get voice as a word index609 lsr.w #3,d0 *...610 andi.w # $001E,d0 *...611 lea _vce2trg,a0 *check to see if voice is free612 move.w 0(a0,d0.W),d0 *...613 cmpi.w #-1,d0 *...614 beq stopfn *if so, stop the function615 * 616 btst #15,d0 *see if voice is held617 bne act0 *continue if so618 * 619 btst #14,d0 *...620 bne act0 *...621 * 622 lea _trgtab,a0 *check trigger table entry623 tst.b 0(a0,d0.W) *...624 bne act0 *if trigger is active, continue625 * 626 bra stopfn *if not, stop the function627 * 628 *------------------------------------------------------------------------------629 *act3 -- AC_JUMP -- unconditional jump630 *---- -----------------------------631 act3: cmp.b FH_PIF(a1),d4 *check jump point against limit632 bcc stopfn *stop function if jump point invalid633 * 634 clr.w d2 *get index of first point635 move.b FH_PT1(a1),d2 *...636 add.b d4,d2 *add jump point637 move.b d2,FH_CPT(a1) *make it the current point638 lsl.w #2,d2 *develop new point index in d2639 move.w d2,d0 *... (fast multiply by PT_LEN = 12640 add.w d2,d2 *... via shift and add)641 add.w d0,d2 *...642 bra outseg *output the segment643 * 644 .page 645 * 646 *------------------------------------------------------------------------------647 *act4 -- AC_LOOP -- jump to point PT_PAR1 PT_PAR2 times648 *---- ----------------------------------------------649 act4: tst.b PT_PAR3(a2,d2.W) *check counter650 bne act4a *jump if it's running651 * 652 move.b PT_PAR2(a2,d2.W),d0 *get parameter653 subi.w #90,d0 *put parameter in random range654 bmi act4b *treat as normal if < 90655 * 656 movem.l d1-d2/a0-a2,-(a7) *get ranged random number657 move.w d0,-(a7) *...658 jsr _irand *...659 tst.w (a7)+ *...660 movem.l (a7)+,d1-d2/a0-a2 *...661 move.b d0,PT_PAR3(a2,d2.w) *set counter662 beq act0 *next segment if cntr set to 0663 * 664 bra act3 *else jump to the point665 * 666 act4b: move.b PT_PAR2(a2,d2.W),PT_PAR3(a2,d2.W) *set counter667 beq act0 *next segment if cntr set to 0668 * 669 bra act3 *else jump to the point670 * 671 act4a: subq.b #1,PT_PAR3(a2,d2.W) *decrement counter672 beq act0 *next segment if cntr ran out673 * 674 bra act3 *jump if it's still non-zero675 * 676 *------------------------------------------------------------------------------677 *act5 -- AC_KYUP -- jump if key is up678 *---- ----------------------------679 act5: move.w _fpuifnc,d0 *get voice as a word index680 lsr.w #3,d0 *...681 andi.w # $001E,d0 *...682 lea _vce2trg,a0 *check to see if voice is free683 move.w 0(a0,d0.W),d0 *...684 cmpi.w #-1,d0 *...685 beq act3 *if so (inactive), do the jump686 * 687 btst #15,d0 *see if voice is held688 bne act0 *continue if so689 * 690 btst #14,d0 *...691 bne act0 *...692 * 693 lea _trgtab,a0 *check trigger table entry694 tst.b 0(a0,d0.W) *see if the trigger is active695 beq act3 *if not, do the jump696 * 697 bra act0 *if so, do next segment698 * 699 .page 700 * 701 *------------------------------------------------------------------------------702 *act6 -- AC_KYDN -- jump if key is down703 *---- ------------------------------704 act6: move.w _fpuifnc,d0 *get voice as a word index705 lsr.w #3,d0 *...706 andi.w # $001E,d0 *...707 lea _vce2trg,a0 *check to see if voice is free708 move.w 0(a0,d0.W),d0 *...709 cmpi.w #-1,d0 *...710 beq act0 *if so (inactive), continue711 * 712 btst #15,d0 *see if voice is held713 bne act3 *do jump if so714 * 715 btst #14,d0 *...716 bne act3 *...717 * 718 lea _trgtab,a0 *check trigger table entry719 tst.b 0(a0,d0.W) *see if the trigger is active720 bne act3 *if so, do the jump721 * 722 bra act0 *if not, do next segment723 * 724 *------------------------------------------------------------------------------725 *Test stub726 *---------727 act7: bra act0 *AC_HERE: treat act7 as AC_NULL728 * 729 .page 730 *------------------------------------------------------------------------------731 * 732 *_fpuclr -- clear the FPU733 *------- -------------734 * 735 *void736 *fpuclr()737 * 738 *Resets the FPU functions to their nominal values.739 * 740 *------------------------------------------------------------------------------741 * 742 _fpuclr: link a6,#0 *link stack frames743 move.w sr,-(a7) *save the interrupt level744 ori.w # $0700,sr *turn off interrupts745 * 746 lea FPUFUNC,a0 *point at the first function747 lea _fp_resv,a2 *point at reset value table748 move.w #11,d1 *set the outer loop count749 * 750 .page 751 *------------------------------------------------------------------------------752 *reset the 'spare' function for the voice753 *------------------------------------------------------------------------------754 clr0: move.w #CLREXP,F_EXP(a0) *set time exponent755 tst.l actab *delay756 tst.l actab *...757 move.w #CLRMNT,F_MNT(a0) *set time mantissa758 tst.l actab *delay759 tst.l actab *...760 * 761 move.w #0,F_SF3(a0) *set scale factor 3762 tst.l actab *delay763 tst.l actab *...764 move.w #0,F_CV3(a0) *set voltage 3765 tst.l actab *delay766 tst.l actab *...767 * 768 move.w #0,F_SF2(a0) *set scale factor 2769 tst.l actab *delay770 tst.l actab *...771 move.w #0,F_CV2(a0) *set voltage 2772 tst.l actab *delay773 tst.l actab *...774 * 775 move.w #0,F_SF1(a0) *set scale factor 1776 tst.l actab *delay777 tst.l actab *...778 move.w #0,F_CV1(a0) *set voltage 1779 tst.l actab *delay780 tst.l actab *...781 * 782 move.w (a2),F_VAL10(a0) *set value from variable table783 tst.l actab *delay784 tst.l actab *...785 move.w (a2)+,F_VAL01(a0) *...786 tst.l actab *delay787 tst.l actab *...788 move.w #FSEND,F_CTL(a0) *set control word789 tst.l actab *delay790 tst.l actab *...791 * 792 .page 793 adda.w # $0020,a0 *point at 2nd function794 lea fprescon,a1 *set reset constant pointer795 move.w #14,d0 *set inner loop count796 * 797 *------------------------------------------------------------------------------798 *reset the other functions for the voice799 *------------------------------------------------------------------------------800 clr1: move.w #CLREXP,F_EXP(a0) *set time exponent801 tst.l actab *delay802 tst.l actab *...803 move.w #CLRMNT,F_MNT(a0) *set time mantissa804 tst.l actab *delay805 tst.l actab *...806 * 807 move.w #0,F_SF3(a0) *set scale factor 3808 tst.l actab *delay809 tst.l actab *...810 move.w #0,F_CV3(a0) *set voltage 3811 tst.l actab *delay812 tst.l actab *...813 * 814 move.w #0,F_SF2(a0) *set scale factor 2815 tst.l actab *delay816 tst.l actab *...817 move.w #0,F_CV2(a0) *set voltage 2818 tst.l actab *delay819 tst.l actab *...820 * 821 move.w #0,F_SF1(a0) *set scale factor 1822 tst.l actab *delay823 tst.l actab *...824 move.w #0,F_CV1(a0) *set voltage 1825 tst.l actab *delay826 tst.l actab *...827 * 828 move.w (a1),F_VAL10(a0) *set value from constant table829 tst.l actab *delay830 tst.l actab *...831 move.w (a1)+,F_VAL01(a0) *...832 tst.l actab *delay833 tst.l actab *...834 move.w #FSEND,F_CTL(a0) *set control word835 tst.l actab *delay836 tst.l actab *...837 * 838 .page 839 *------------------------------------------------------------------------------840 *loop through reset for all of the voices and functions841 *------------------------------------------------------------------------------842 adda.w # $0020,a0 *point at next function843 dbra d0,clr1 *loop until all funcs. cleared844 * 845 dbra d1,clr0 *loop until all voices cleared846 *------------------------------------------------------------------------------847 *clear the FPU interrupt, and return848 *------------------------------------------------------------------------------849 move.w #0,FPUINT2 *clear FPU interrupt850 move.w (a7)+,sr *restore interrupts851 unlk a6 *unlink stack frames852 rts *return to caller853 * 854 .page 855 * 856 *_clrvce -- quiet a voice857 *------- -------------858 * 859 *void860 *clrvce(vce)861 *short vce;862 * 863 *Quiet the voice by resetting the FPU functions it uses.864 * 865 _clrvce: link a6,#0 *link stack frames866 move.w sr,-(a7) *save the interrupt level867 ori.w # $0700,sr *turn off interrupts868 * 869 lea FPUFUNC+ $20,a0 *point at the 2nd function870 move.w 8(a6),d0 *get voice number871 ext.l d0 *...872 lsl.l #8,d0 *shift into position873 add.l d0,d0 *...874 adda.l d0,a0 *add to function base875 lea fprescon,a1 *set reset constant pointer876 move.w #14,d0 *set inner loop count877 * 878 vclr1: move.l a0,d1 *see if we reset this function879 and.w # $01F0,d1 *...880 * 881 cmpi.w # $0100,d1 *dynamics ?882 beq vclr2 *skip it if so883 * 884 move.w #CLREXP,F_EXP(a0) *set time exponent885 tst.l actab *delay886 tst.l actab *...887 move.w #CLRMNT,F_MNT(a0) *set time mantissa888 tst.l actab *delay889 tst.l actab *...890 * 891 cmpi.w # $0020,d1 *freq 1 ?892 beq vclr3 *don't reset CV3 (fine tune)893 * 894 move.w #0,F_SF3(a0) *set scale factor 3895 tst.l actab *delay896 tst.l actab *...897 move.w #0,F_CV3(a0) *set voltage 3898 tst.l actab *delay899 tst.l actab *...900 * 901 vclr3: move.w #0,F_SF1(a0) *set scale factor 1902 tst.l actab *delay903 tst.l actab *...904 move.w #0,F_CV1(a0) *set voltage 1905 tst.l actab *delay906 tst.l actab *...907 * 908 .page 909 * 910 move.w (a1),F_VAL10(a0) *set value from constant table911 tst.l actab *delay912 tst.l actab *...913 move.w (a1),F_VAL01(a0) *...914 tst.l actab *delay915 tst.l actab *...916 move.w #FSEND,F_CTL(a0) *set control word917 tst.l actab *delay918 tst.l actab *...919 * 920 vclr2: adda.w #2,a1 *point at next function921 adda.w # $0020,a0 *922 dbra d0,vclr1 *loop until all funcs. cleared923 * 924 move.w (a7)+,sr *restore interrupts925 unlk a6 *unlink stack frames926 rts *return to caller927 * 928 .page 929 *------------------------------------------------------------------------------545 546 outseg1: move.w d3,F_VAL10(a3,d1.W) | send value to FPU 547 548 outseg2: andi.w #MSK_CTL,d0 | mask off software bits 549 ori.w #UPD_BIT+INT_BIT,d0 | set the update & !lastseg bits 550 move.w d0,F_CTL(a3,d1.W) | send control word to FPU 551 bra fpexit | done -- exit 552 553 .page 554 555 | ------------------------------------------------------------------------------ 556 | act1 -- AC_SUST -- pause if key is down (sustain) 557 | ---- ------------------------------------------ 558 act1: move.w _fpuifnc,d0 | get voice as a word index 559 lsr.w #3,d0 | ... 560 andi.w #0x001E,d0 | ... 561 lea _vce2trg,a0 | point at voice to trigger table 562 move.w 0(a0,d0.W),d0 | get trigger table entry into d0 563 cmpi.w #-1,d0 | see if voice is free 564 beq act0 | continue function if so 565 566 btst #15,d0 | see if voice is held by a pedal 567 bne act1a | sustain if so 568 569 btst #14,d0 | see if voice is sustained by a pedal 570 bne act1a | sustain if so 571 572 lea _trgtab,a0 | point at trigger table 573 tst.b 0(a0,d0.W) | check trigger status 574 beq act0 | continue function if not active 575 576 act1a: move.l _pfqhdr,d3 | see if any pflist entries remain 577 beq act0 | continue if not (shouldn't happen!) 578 579 move.b FH_PT1(a1),d0 | get first point number 580 add.b FH_PIF(a1),d0 | add base to first point 581 subq.b #1,d0 | make d0 last point number 582 cmp.b FH_CPT(a1),d0 | check current point number 583 beq stopfn | done if this is the last point 584 585 addq.b #1,FH_CPT(a1) | update current point number 586 addi.w #PT_LEN,d2 | advance the point index 587 movea.l d3,a0 | acquire a new pflist entry 588 move.l (a0),_pfqhdr | ... 589 move.l _pflist,(a0) | chain it to pflist 590 move.l a0,_pflist | ... 591 move.w FH_TRG(a1),PF_TRIG(a0) | set trigger number in entry 592 move.w _fpuifnc,PF_FUNC(a0) | set v/p word in entry 593 movem.l d1-d2/d4/a1-a3,PF_D1(a0) | set registers in entry 594 move.b FH_TMD(a1),d0 | stop the function 595 andi.w #MSK_RNVB,d0 | ... 596 move.w d0,d3 | ... 597 add.w d3,d3 | ... 598 andi.w #MSK_ONVB,d3 | ... 599 or.w d3,d0 | ... 600 move.w d0,F_CTL(a3,d1.W) | ... 601 bra fpexit | exit 602 603 .page 604 605 | ------------------------------------------------------------------------------ 606 | act2 -- AC_ENBL -- stop if key is up 607 | ---- ---------------------------- 608 act2: move.w _fpuifnc,d0 | get voice as a word index 609 lsr.w #3,d0 | ... 610 andi.w #0x001E,d0 | ... 611 lea _vce2trg,a0 | check to see if voice is free 612 move.w 0(a0,d0.W),d0 | ... 613 cmpi.w #-1,d0 | ... 614 beq stopfn | if so, stop the function 615 616 btst #15,d0 | see if voice is held 617 bne act0 | continue if so 618 619 btst #14,d0 | ... 620 bne act0 | ... 621 622 lea _trgtab,a0 | check trigger table entry 623 tst.b 0(a0,d0.W) | ... 624 bne act0 | if trigger is active, continue 625 626 bra stopfn | if not, stop the function 627 628 | ------------------------------------------------------------------------------ 629 | act3 -- AC_JUMP -- unconditional jump 630 | ---- ----------------------------- 631 act3: cmp.b FH_PIF(a1),d4 | check jump point against limit 632 bcc stopfn | stop function if jump point invalid 633 634 clr.w d2 | get index of first point 635 move.b FH_PT1(a1),d2 | ... 636 add.b d4,d2 | add jump point 637 move.b d2,FH_CPT(a1) | make it the current point 638 lsl.w #2,d2 | develop new point index in d2 639 move.w d2,d0 | ... (fast multiply by PT_LEN = 12 640 add.w d2,d2 | ... via shift and add) 641 add.w d0,d2 | ... 642 bra outseg | output the segment 643 644 .page 645 646 | ------------------------------------------------------------------------------ 647 | act4 -- AC_LOOP -- jump to point PT_PAR1 PT_PAR2 times 648 | ---- ---------------------------------------------- 649 act4: tst.b PT_PAR3(a2,d2.W) | check counter 650 bne act4a | jump if it's running 651 652 move.b PT_PAR2(a2,d2.W),d0 | get parameter 653 subi.w #90,d0 | put parameter in random range 654 bmi act4b | treat as normal if < 90 655 656 movem.l d1-d2/a0-a2,-(a7) | get ranged random number 657 move.w d0,-(a7) | ... 658 jsr _irand | ... 659 tst.w (a7)+ | ... 660 movem.l (a7)+,d1-d2/a0-a2 | ... 661 move.b d0,PT_PAR3(a2,d2.w) | set counter 662 beq act0 | next segment if cntr set to 0 663 664 bra act3 | else jump to the point 665 666 act4b: move.b PT_PAR2(a2,d2.W),PT_PAR3(a2,d2.W) | set counter 667 beq act0 | next segment if cntr set to 0 668 669 bra act3 | else jump to the point 670 671 act4a: subq.b #1,PT_PAR3(a2,d2.W) | decrement counter 672 beq act0 | next segment if cntr ran out 673 674 bra act3 | jump if it's still non-zero 675 676 | ------------------------------------------------------------------------------ 677 | act5 -- AC_KYUP -- jump if key is up 678 | ---- ---------------------------- 679 act5: move.w _fpuifnc,d0 | get voice as a word index 680 lsr.w #3,d0 | ... 681 andi.w #0x001E,d0 | ... 682 lea _vce2trg,a0 | check to see if voice is free 683 move.w 0(a0,d0.W),d0 | ... 684 cmpi.w #-1,d0 | ... 685 beq act3 | if so (inactive), do the jump 686 687 btst #15,d0 | see if voice is held 688 bne act0 | continue if so 689 690 btst #14,d0 | ... 691 bne act0 | ... 692 693 lea _trgtab,a0 | check trigger table entry 694 tst.b 0(a0,d0.W) | see if the trigger is active 695 beq act3 | if not, do the jump 696 697 bra act0 | if so, do next segment 698 699 .page 700 701 | ------------------------------------------------------------------------------ 702 | act6 -- AC_KYDN -- jump if key is down 703 | ---- ------------------------------ 704 act6: move.w _fpuifnc,d0 | get voice as a word index 705 lsr.w #3,d0 | ... 706 andi.w #0x001E,d0 | ... 707 lea _vce2trg,a0 | check to see if voice is free 708 move.w 0(a0,d0.W),d0 | ... 709 cmpi.w #-1,d0 | ... 710 beq act0 | if so (inactive), continue 711 712 btst #15,d0 | see if voice is held 713 bne act3 | do jump if so 714 715 btst #14,d0 | ... 716 bne act3 | ... 717 718 lea _trgtab,a0 | check trigger table entry 719 tst.b 0(a0,d0.W) | see if the trigger is active 720 bne act3 | if so, do the jump 721 722 bra act0 | if not, do next segment 723 724 | ------------------------------------------------------------------------------ 725 | Test stub 726 | --------- 727 act7: bra act0 | AC_HERE: treat act7 as AC_NULL 728 729 .page 730 | ------------------------------------------------------------------------------ 731 732 | _fpuclr -- clear the FPU 733 | ------- ------------- 734 735 | void 736 | fpuclr() 737 738 | Resets the FPU functions to their nominal values. 739 740 | ------------------------------------------------------------------------------ 741 742 _fpuclr: link a6,#0 | link stack frames 743 move.w sr,-(a7) | save the interrupt level 744 ori.w #0x0700,sr | turn off interrupts 745 746 lea FPUFUNC,a0 | point at the first function 747 lea _fp_resv,a2 | point at reset value table 748 move.w #11,d1 | set the outer loop count 749 750 .page 751 | ------------------------------------------------------------------------------ 752 | reset the 'spare' function for the voice 753 | ------------------------------------------------------------------------------ 754 clr0: move.w #CLREXP,F_EXP(a0) | set time exponent 755 tst.l actab | delay 756 tst.l actab | ... 757 move.w #CLRMNT,F_MNT(a0) | set time mantissa 758 tst.l actab | delay 759 tst.l actab | ... 760 761 move.w #0,F_SF3(a0) | set scale factor 3 762 tst.l actab | delay 763 tst.l actab | ... 764 move.w #0,F_CV3(a0) | set voltage 3 765 tst.l actab | delay 766 tst.l actab | ... 767 768 move.w #0,F_SF2(a0) | set scale factor 2 769 tst.l actab | delay 770 tst.l actab | ... 771 move.w #0,F_CV2(a0) | set voltage 2 772 tst.l actab | delay 773 tst.l actab | ... 774 775 move.w #0,F_SF1(a0) | set scale factor 1 776 tst.l actab | delay 777 tst.l actab | ... 778 move.w #0,F_CV1(a0) | set voltage 1 779 tst.l actab | delay 780 tst.l actab | ... 781 782 move.w (a2),F_VAL10(a0) | set value from variable table 783 tst.l actab | delay 784 tst.l actab | ... 785 move.w (a2)+,F_VAL01(a0) | ... 786 tst.l actab | delay 787 tst.l actab | ... 788 move.w #FSEND,F_CTL(a0) | set control word 789 tst.l actab | delay 790 tst.l actab | ... 791 792 .page 793 adda.w #0x0020,a0 | point at 2nd function 794 lea fprescon,a1 | set reset constant pointer 795 move.w #14,d0 | set inner loop count 796 797 | ------------------------------------------------------------------------------ 798 | reset the other functions for the voice 799 | ------------------------------------------------------------------------------ 800 clr1: move.w #CLREXP,F_EXP(a0) | set time exponent 801 tst.l actab | delay 802 tst.l actab | ... 803 move.w #CLRMNT,F_MNT(a0) | set time mantissa 804 tst.l actab | delay 805 tst.l actab | ... 806 807 move.w #0,F_SF3(a0) | set scale factor 3 808 tst.l actab | delay 809 tst.l actab | ... 810 move.w #0,F_CV3(a0) | set voltage 3 811 tst.l actab | delay 812 tst.l actab | ... 813 814 move.w #0,F_SF2(a0) | set scale factor 2 815 tst.l actab | delay 816 tst.l actab | ... 817 move.w #0,F_CV2(a0) | set voltage 2 818 tst.l actab | delay 819 tst.l actab | ... 820 821 move.w #0,F_SF1(a0) | set scale factor 1 822 tst.l actab | delay 823 tst.l actab | ... 824 move.w #0,F_CV1(a0) | set voltage 1 825 tst.l actab | delay 826 tst.l actab | ... 827 828 move.w (a1),F_VAL10(a0) | set value from constant table 829 tst.l actab | delay 830 tst.l actab | ... 831 move.w (a1)+,F_VAL01(a0) | ... 832 tst.l actab | delay 833 tst.l actab | ... 834 move.w #FSEND,F_CTL(a0) | set control word 835 tst.l actab | delay 836 tst.l actab | ... 837 838 .page 839 | ------------------------------------------------------------------------------ 840 | loop through reset for all of the voices and functions 841 | ------------------------------------------------------------------------------ 842 adda.w #0x0020,a0 | point at next function 843 dbra d0,clr1 | loop until all funcs. cleared 844 845 dbra d1,clr0 | loop until all voices cleared 846 | ------------------------------------------------------------------------------ 847 | clear the FPU interrupt, and return 848 | ------------------------------------------------------------------------------ 849 move.w #0,FPUINT2 | clear FPU interrupt 850 move.w (a7)+,sr | restore interrupts 851 unlk a6 | unlink stack frames 852 rts | return to caller 853 854 .page 855 856 | _clrvce -- quiet a voice 857 | ------- ------------- 858 859 | void 860 | clrvce(vce) 861 | short vce; 862 863 | Quiet the voice by resetting the FPU functions it uses. 864 865 _clrvce: link a6,#0 | link stack frames 866 move.w sr,-(a7) | save the interrupt level 867 ori.w #0x0700,sr | turn off interrupts 868 869 lea FPUFUNC+0x20,a0 | point at the 2nd function 870 move.w 8(a6),d0 | get voice number 871 ext.l d0 | ... 872 lsl.l #8,d0 | shift into position 873 add.l d0,d0 | ... 874 adda.l d0,a0 | add to function base 875 lea fprescon,a1 | set reset constant pointer 876 move.w #14,d0 | set inner loop count 877 878 vclr1: move.l a0,d1 | see if we reset this function 879 and.w #0x01F0,d1 | ... 880 881 cmpi.w #0x0100,d1 | dynamics ? 882 beq vclr2 | skip it if so 883 884 move.w #CLREXP,F_EXP(a0) | set time exponent 885 tst.l actab | delay 886 tst.l actab | ... 887 move.w #CLRMNT,F_MNT(a0) | set time mantissa 888 tst.l actab | delay 889 tst.l actab | ... 890 891 cmpi.w #0x0020,d1 | freq 1 ? 892 beq vclr3 | don't reset CV3 (fine tune) 893 894 move.w #0,F_SF3(a0) | set scale factor 3 895 tst.l actab | delay 896 tst.l actab | ... 897 move.w #0,F_CV3(a0) | set voltage 3 898 tst.l actab | delay 899 tst.l actab | ... 900 901 vclr3: move.w #0,F_SF1(a0) | set scale factor 1 902 tst.l actab | delay 903 tst.l actab | ... 904 move.w #0,F_CV1(a0) | set voltage 1 905 tst.l actab | delay 906 tst.l actab | ... 907 908 .page 909 910 move.w (a1),F_VAL10(a0) | set value from constant table 911 tst.l actab | delay 912 tst.l actab | ... 913 move.w (a1),F_VAL01(a0) | ... 914 tst.l actab | delay 915 tst.l actab | ... 916 move.w #FSEND,F_CTL(a0) | set control word 917 tst.l actab | delay 918 tst.l actab | ... 919 920 vclr2: adda.w #2,a1 | point at next function 921 adda.w #0x0020,a0 | 922 dbra d0,vclr1 | loop until all funcs. cleared 923 924 move.w (a7)+,sr | restore interrupts 925 unlk a6 | unlink stack frames 926 rts | return to caller 927 928 .page 929 | ------------------------------------------------------------------------------ 930 930 .data 931 *------------------------------------------------------------------------------932 * 933 *actab -- action code dispatch table934 *----- --------------------------935 actab: dc.l act0 *0 - AC_NULL: no action936 dc.l act1 *1 - AC_SUST: sustain937 dc.l act2 *2 - AC_ENBL: enable938 dc.l act3 *3 - AC_JUMP: unconditional jump939 dc.l act4 *4 - AC_LOOP: jump n times (loop)940 dc.l act5 *5 - AC_KYUP: jump if key up (enable jump)941 dc.l act6 *6 - AC_KYDN: jump if key down (sustain jump)942 dc.l act7 *7 - AC_HERE: here on key up943 * 944 *fprescon -- FPU reset constant table945 *-------- ------------------------946 fprescon: dc.w $0000 *frq 1 0.00947 dc.w $8300 *level -10.00948 dc.w $0000 *frq 2 0.00949 dc.w $0000 *locn 0.00950 dc.w $0000 *frq 3 0.00951 dc.w $0000 *reson 0.00952 dc.w $0000 *frq 4 0.00953 dc.w $7D00 *dyn +10.00954 dc.w $0000 *ind 1 0.00955 dc.w $3E80 *filt +5.00956 dc.w $0000 *ind 2 0.00957 dc.w $0000 *ind 3 0.00958 dc.w $0000 *ind 4 0.00959 dc.w $0000 *ind 5 0.00960 dc.w $0000 *ind 6 0.00961 * 962 *------------------------------------------------------------------------------931 | ------------------------------------------------------------------------------ 932 933 | actab -- action code dispatch table 934 | ----- -------------------------- 935 actab: dc.l act0 | 0 - AC_NULL: no action 936 dc.l act1 | 1 - AC_SUST: sustain 937 dc.l act2 | 2 - AC_ENBL: enable 938 dc.l act3 | 3 - AC_JUMP: unconditional jump 939 dc.l act4 | 4 - AC_LOOP: jump n times (loop) 940 dc.l act5 | 5 - AC_KYUP: jump if key up (enable jump) 941 dc.l act6 | 6 - AC_KYDN: jump if key down (sustain jump) 942 dc.l act7 | 7 - AC_HERE: here on key up 943 944 | fprescon -- FPU reset constant table 945 | -------- ------------------------ 946 fprescon: dc.w 0x0000 | frq 1 0.00 947 dc.w 0x8300 | level -10.00 948 dc.w 0x0000 | frq 2 0.00 949 dc.w 0x0000 | locn 0.00 950 dc.w 0x0000 | frq 3 0.00 951 dc.w 0x0000 | reson 0.00 952 dc.w 0x0000 | frq 4 0.00 953 dc.w 0x7D00 | dyn +10.00 954 dc.w 0x0000 | ind 1 0.00 955 dc.w 0x3E80 | filt +5.00 956 dc.w 0x0000 | ind 2 0.00 957 dc.w 0x0000 | ind 3 0.00 958 dc.w 0x0000 | ind 4 0.00 959 dc.w 0x0000 | ind 5 0.00 960 dc.w 0x0000 | ind 6 0.00 961 962 | ------------------------------------------------------------------------------ 963 963 .bss 964 *------------------------------------------------------------------------------965 * 966 _fp_resv: ds.w 12 *fpu spare function reset values967 _fpuifnc: ds.w 1 *interrupting function number from FPU968 * 964 | ------------------------------------------------------------------------------ 965 966 _fp_resv: ds.w 12 | fpu spare function reset values 967 _fpuifnc: ds.w 1 | interrupting function number from FPU 968 969 969 .end -
ram/procpfl.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *procpfl.s -- process pendant functions (sustain release processing)3 *Version 8 -- 1988-08-31 -- D.N. Lynx Crowe4 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | procpfl.s -- process pendant functions (sustain release processing) 3 | Version 8 -- 1988-08-31 -- D.N. Lynx Crowe 4 | ------------------------------------------------------------------------------ 5 5 .text 6 * 6 7 7 .xdef _procpfl 8 * 9 .xdef _curpf_f *current function (v/p)10 .xdef _curpf_l *current pflist entry11 .xdef _curpf_t *current trigger12 * 8 9 .xdef _curpf_f | current function (v/p) 10 .xdef _curpf_l | current pflist entry 11 .xdef _curpf_t | current trigger 12 13 13 .xref _irand 14 14 .xref _xgetran 15 * 15 16 16 .xref _expbit 17 17 .xref _funcndx … … 26 26 .xref _vce2trg 27 27 .xref _veltab 28 * 29 .page 30 *------------------------------------------------------------------------------31 *Register usage32 *--------------33 *d0 scratch34 *d1 FPU function index35 *d2 point index from FH_CPT (idfcpt)36 *d3 scratch37 *d4 jump point number from PT_PAR1 (ippar1)38 *d5 scratch39 * 40 *a0 scratch41 *a1 function header base42 *a2 point table base43 *a3 FPU base44 * 45 *------------------------------------------------------------------------------46 *FPU definitions47 *---------------48 * 49 UPD_BIT .equ $0001 *update bit (1 = update)50 INT_BIT .equ $0002 *int. bit (0 = disable)51 RAT_BIT .equ $0004 *ratio bit (0 = ratio)52 * 53 VSUBNBIT .equ 3 *new value select bit number54 VAL_BITS .equ $0018 *new value select bit mask55 * 56 MSK_RNVB .equ $000C *new value / ratio bits57 MSK_ONVB .equ $0010 *old new value bit58 * 59 FKILL .equ $0014 *kill value for function60 FSEND .equ $0015 *send new value to function61 * 62 CLREXP .equ $8000 *clear value for time exponent63 CLRMNT .equ $8000 *clear value for time mantissa64 * 65 *------------------------------------------------------------------------------66 *Miscellaneous definitions67 *-------------------------68 * 69 PCHMAX .equ 21920 *maximum pitch value70 VALMAX .equ 32000 *maximum value to send to FPU71 VALMIN .equ -32000 *minimum value to send to FPU72 * 73 LSPCH .equ 2 *left shift for sources to freq74 * 75 VALLEN .equ 10 *length of the 'valent' struct76 VT_VAL .equ 8 *value offset in 'valent'77 * 78 .page 79 *------------------------------------------------------------------------------80 *FPU addresses81 *-------------82 * 83 FPUBASE .equ $180000 *FPU base address84 * 85 FPUWST .equ FPUBASE *FPU waveshape base86 FPUFUNC .equ FPUBASE+$4000 *FPU function base87 FPUINT1 .equ FPUBASE+$4000 *FPU int. input address (R/O)88 FPUINT2 .equ FPUBASE+$6000 *FPU int. reset address (W/O)89 FPUCFG .equ FPUBASE+$5FE0 *FPU config. data address (W/O)90 * 91 F_CTL .equ $00 *control word92 F_VAL10 .equ $02 *new value "10"93 F_CV1 .equ $08 *control voltage 194 F_SF1 .equ $0A *scale factor 195 F_CV2 .equ $0C *control voltage 296 F_SF2 .equ $0E *scale factor 297 F_CV3 .equ $10 *control voltage 398 F_SF3 .equ $12 *scale factor 399 F_MNT .equ $14 *time mantissa100 F_EXP .equ $16 *time exponent101 F_VAL01 .equ $1C *new value "01"102 * 103 P_FREQ1 .equ $0020 *frequency 1104 P_FREQ2 .equ $0060 *frequency 2105 P_FREQ3 .equ $00A0 *frequency 3106 P_FREQ4 .equ $00E0 *frequency 4107 P_FILTER .equ $0140 *filter108 P_FILTRQ .equ $00C0 *filter q109 * 110 P_INDEX1 .equ $0120 *index 1111 P_INDEX2 .equ $0160 *index 2112 P_INDEX3 .equ $0180 *index 3113 P_INDEX4 .equ $01A0 *index 4114 P_INDEX5 .equ $01C0 *index 5115 P_INDEX6 .equ $01E0 *index 6116 * 117 P_LEVEL .equ $0040 *level118 * 119 P_LOCN .equ $0080 *location120 P_DYNAM .equ $0100 *dynamics121 * 122 .page 123 *------------------------------------------------------------------------------124 *Structure definitions125 *------------------------------------------------------------------------------126 *The following MUST match the idfnhdr structure definition in instdsp.h:127 * 128 FH_LEN .equ 12 *length of the idfnhdr structure129 * 130 FH_PCH .equ 0 *WORD - pitch offset131 FH_MLT .equ 2 *WORD - overall value multiplier132 FH_SRC .equ 4 *BYTE - overall value source133 FH_PIF .equ 5 *BYTE - # of points in the function134 FH_PT1 .equ 6 *BYTE - index of first point135 FH_TMD .equ 7 *BYTE - trigger mode / control bits136 FH_CPT .equ 8 *BYTE - current point137 FH_PRM .equ 9 *BYTE - misc. function parameter138 FH_TRG .equ 10 *WORD - trigger139 * 140 I_ACTIVE .equ 1 *'Active' bit number (in FH_TMD)141 * 142 MSK_CTL .equ $001C *mask for FPU hardware bits (in FH_TMD)143 * 144 *------------------------------------------------------------------------------145 *The following MUST match the instpnt structure definition in instdsp.h:146 * 147 PT_LEN .equ 12 *length of the instpnt structure148 * 149 PT_TIM .equ 0 *WORD - time (packed)150 PT_VAL .equ 2 *WORD - value151 PT_VMLT .equ 4 *WORD - value multiplier152 PT_VSRC .equ 6 *BYTE - value source153 PT_ACT .equ 7 *BYTE - action154 PT_PAR1 .equ 8 *BYTE - parameter 1155 PT_PAR2 .equ 9 *BYTE - parameter 2156 PT_PAR3 .equ 10 *BYTE - parameter 3157 PT_PAD .equ 11 *BYTE - padding for even boundary158 * 159 MSK_MNT .equ $FFF0 *mask for mantissa (in PT_TIM)160 MSK_EXP .equ $000F *mask for exponent (in PT_TIM)161 * 162 MAX_ACT .equ 7 *maximum action code value163 * 164 *------------------------------------------------------------------------------165 *Source definitions -- must match those in 'smdefs.h'166 * 167 SM_RAND .equ 1 *random168 SM_PTCH .equ 5 *pitch169 SM_KPRS .equ 6 *key pressure170 SM_KVEL .equ 7 *key velocity171 SM_FREQ .equ 10 *frequency172 * 173 .page 174 * 175 *Layout of pflist entries 32 bytes each176 *------------------------177 PF_NEXT .equ 0 *LONG - next entry pointer178 PF_TRIG .equ 4 *WORD - trigger number179 PF_FUNC .equ 6 *WORD - fpuifnc value180 PF_D1 .equ 8 *LONG - d1181 PF_D2 .equ 12 *LONG - d2182 PF_D4 .equ 16 *LONG - d4183 PF_A1 .equ 20 *LONG - a1184 PF_A2 .equ 24 *LONG - a2185 PF_A3 .equ 28 *LONG - a3186 * 187 *Parameter offset188 *----------------189 TRIG .equ 8 *WORD - trigger number190 * 191 *Register equates192 *----------------193 RCUR .equ a4 *current pflist entry pointer194 RPRV .equ a5 *previous pflist entry pointer195 * 196 .page 197 *------------------------------------------------------------------------------198 *_procpfl() -- process pendant functions199 * 200 *void201 *procpfl(trig);202 *unsigned trig;203 * 204 *Processes pendant (sustained) functions by restarting them205 *when the trigger (trig) that's sustaining them is released.206 *Invoked by key release processing in msm() and localkb().207 * 208 *------------------------------------------------------------------------------209 * 210 _procpfl: nop *FOR DEBUGGING PATCH211 * 212 link a6,#0 *allocate stack frame213 movem.l d3-d7/a3-a5,-(a7) *preserve registers we use214 * 215 move.w sr,d7 *save interrupt state216 move.w # $2200,sr *turn off FPU interrupts217 * 218 move.w TRIG(a6),d6 *get trigger we're processing219 move.w d6,_curpf_t *...220 movea.l #_pflist,RPRV *point at 'previous' pflist entry221 bra pfscan *go scan the chain222 * 223 pfpass: movea.l RCUR,RPRV *point at previous entry224 * 225 pfscan: move.l (RPRV),d5 *get next pflist entry pointer226 beq pfexit *done if no more227 * 228 movea.l d5,RCUR *point at current entry229 move.l d5,_curpf_l *...230 * 231 cmp.w PF_TRIG(RCUR),d6 *see if this entry is wanted232 bne pfpass *jump if not233 * 234 movem.l PF_D1(RCUR),d1-d2/d4/a1-a3 *restore processing state235 move.w PF_FUNC(RCUR),_curpf_f *...236 * 237 btst #I_ACTIVE,FH_TMD(a1) *see if function is active238 bne doact *continue function if so239 * 240 bra stopfn *stop function if not241 * 242 pfnext: move.l (RCUR),(RPRV) *remove entry from pflist243 move.l _pfqhdr,(RCUR) *chain entry to free list244 move.l RCUR,_pfqhdr *...245 bra pfscan *go look at next entry246 * 247 pfexit: move.w d7,sr *restore interrupt level248 movem.l (a7)+,d3-d7/a3-a5 *restore the registers we used249 unlk a6 *deallocate stack frame250 rts *return to caller251 * 252 .page 253 * 254 *------------------------------------------------------------------------------255 *stop a function256 *------------------------------------------------------------------------------257 stopfn: move.b FH_TMD(a1),d0 *get function control bits258 andi.w #MSK_RNVB,d0 *mask for ratio / new new-value bit259 move.w d0,d3 *isolate new new-value bit260 add.w d3,d3 *... from function header261 andi.w #MSK_ONVB,d3 *... shift to old new-value bit262 or.w d3,d0 * ... and put new bit in old bit263 move.w d0,F_CTL(a3,d1.W) *stop the function264 bclr #I_ACTIVE,FH_TMD(a1) *reset the active bit265 bra pfnext *go restore registers and exit266 * 267 *------------------------------------------------------------------------------268 *setup for and dispatch to the proper action handler269 *------------------------------------------------------------------------------270 doact: clr.w d2 *get current point index in d2271 move.b FH_CPT(a1),d2 *...272 lsl.w #2,d2 *multiply it by the length of a point273 move.w d2,d0 *... (fast multiply by PT_LEN = 12274 add.w d2,d2 *... via shift and add)275 add.w d0,d2 *...276 clr.w d4 *get jump point # into d4277 move.b PT_PAR1(a2,d2.W),d4 *...278 clr.w d3 *get action code in d3279 move.b PT_ACT(a2,d2.W),d3 *...280 cmpi.b #MAX_ACT,d3 *check against the limit281 bgt stopfn *stop things if it's a bad action code282 * 283 lsl.w #2,d3 *develop index to action dispatch table284 lea actab,a0 *get the address of the action handler285 movea.l 0(a0,d3.W),a0 *...286 * 287 *------------------------------------------------------------------------------288 *At this point we're ready to do the action associated with the point,289 *and the registers are set up, and will remain, as follows:290 * 291 *d1 FPU function index a1 function header base292 *d2 point table index a2 point table base293 *a3 FPU function base294 *d4 jump point number295 * 296 *d0, d3, d5, and a0 are used as scratch throughout the code.297 * 298 *------------------------------------------------------------------------------299 * 300 jmp (a0) *dispatch to action handler301 * 302 .page 303 *------------------------------------------------------------------------------304 *act0 -- AC_NULL -- no action305 *---- --------------------306 act0: move.b FH_PT1(a1),d0 *get first point number307 add.b FH_PIF(a1),d0 *add number of points in function308 subq.b #1,d0 *make it last point number309 cmp.b FH_CPT(a1),d0 *see if we're at the last point310 beq stopfn *stop function if so311 * 312 addq.b #1,FH_CPT(a1) *update function header for next point313 addi.w #PT_LEN,d2 *advance the point index314 * 315 *------------------------------------------------------------------------------316 *outseg -- output a segment317 *------ ----------------318 outseg: move.w PT_TIM(a2,d2.w),d3 *get packed time319 move.w d3,d0 *extract mantissa320 andi.w #MSK_MNT,d0 *...321 mulu _timemlt,d0 *multiply by panel time pot value322 lsr.l #8,d0 *... and scale it323 lsr.l #7,d0 *...324 move.w d0,F_MNT(a3,d1.W) *send mantissa to FPU325 andi.w #MSK_EXP,d3 *extract exponent code326 add.w d3,d3 *look up decoded exponent327 lea _expbit,a0 *... in expbit328 move.w 0(a0,d3.W),F_EXP(a3,d1.W) *send exponent to FPU329 move.w PT_VAL(a2,d2.W),d3 *get the function value330 * 331 .page 332 *------------------------------------------------------------------------------333 *get the point source, if any334 *------------------------------------------------------------------------------335 tst.w PT_VMLT(a2,d2.W) *see if we have a point mlt.336 beq nosrc *don't do anything for zero337 * 338 clr.w d0 *get the source number339 move.b PT_VSRC(a2,d2.W),d0 *...340 beq nosrc *don't do anything for zero341 * 342 *------------------------------------------------------------------------------343 *SM_RAND -- random344 *------------------------------------------------------------------------------345 cmpi.w #SM_RAND,d0 *is this the random source ?346 bne srctyp0 *jump if not347 * 348 movem.l d1-d2/a0-a2,-(a7) *preserve registers around call349 move.w PT_VMLT(a2,d2.W),-(a7) *pass multiplier to xgetran()350 jsr _xgetran *call for a random number351 tst.w (a7)+ *clean up stack352 movem.l (a7)+,d1-d2/a0-a2 *restore registers353 move.w d0,d5 *put random value in the value register354 bra applym *go apply the multiplier355 * 356 .page 357 *------------------------------------------------------------------------------358 *SM_FREQ -- frequency359 *------------------------------------------------------------------------------360 srctyp0: cmpi.w #SM_FREQ,d0 *is this the frequency source ?361 bne srctyp1 *jump if not362 * 363 move.w (a1),d0 *get the pitch364 lsr.w #6,d0 *shift to a word index365 andi.w # $01FE,d0 *mask out extraneous bits366 lea _ptoftab,a0 *get entry from ptoftab[]367 move.w 0(a0,d0.W),d5 *...368 bra applym *go apply the multiplier369 * 370 *------------------------------------------------------------------------------371 *SM_PTCH -- pitch372 *------------------------------------------------------------------------------373 srctyp1: cmpi.w #SM_PTCH,d0 *is this the pitch source ?374 bne srctyp2 *jump if not375 * 376 move.w (a1),d5 *get the pitch as the value377 bra applym *go apply the multiplier378 * 379 *------------------------------------------------------------------------------380 *SM_KVEL -- velocity381 *------------------------------------------------------------------------------382 srctyp2: cmpi.w #SM_KVEL,d0 *is this the key velocity source ?383 bne srctyp3 *jump if not384 * 385 move.w FH_TRG(a1),d0 *get the trigger number386 add.w d0,d0 *... as a word index387 lea _veltab,a0 *... into veltab[]388 move.w 0(a0,d0.W),d5 *get the velocity from veltab[trg]389 bra applym *go apply the multiplier390 * 391 *------------------------------------------------------------------------------392 *SM_KPRS -- pressure393 *------------------------------------------------------------------------------394 srctyp3: cmpi.w #SM_KPRS,d0 *is this the key pressure source ?395 bne srctyp4 *jump if not (must be an analog input)396 * 397 move.w FH_TRG(a1),d0 *get the trigger number398 add.w d0,d0 *... as a word index399 lea _prstab,a0 *... into prstab[]400 move.w 0(a0,d0.W),d5 *get the pressure from prstab[trg]401 bra applym *go apply the multiplier402 * 403 .page 404 *------------------------------------------------------------------------------405 *all other sources come out of the valents[] array406 *------------------------------------------------------------------------------407 srctyp4: lea _vce2grp,a0 *point at vce2grp[]408 move.w _curpf_f,d5 *get voice number in d5409 lsr.w #3,d5 *...410 andi.w # $001E,d5 *... as a word index411 move.w 0(a0,d5.W),d5 *get the group number412 subq.w #1,d5 *...413 lsl.w #4,d5 *shift it left a nybble414 or.w d5,d0 *OR it into the source number415 add.w d0,d0 *make source number a valents[] index416 move.w d0,d5 *... (fast multiply by VALLEN = 10417 lsl.w #2,d0 *... via shift and add)418 add.w d5,d0 *...419 lea _valents,a0 *get base of valents[]420 move.w VT_VAL(a0,d0.W),d5 *get value421 * 422 *------------------------------------------------------------------------------423 *apply the multiplier to the source, and add it to the function value424 *------------------------------------------------------------------------------425 applym: muls PT_VMLT(a2,d2.W),d5 *apply the multiplier426 asr.l #7,d5 *scale the result427 asr.l #8,d5 *...428 ext.l d3 *add the function value429 add.l d3,d5 *...430 cmpi.l #VALMAX,d5 *check for overflow431 ble srcmlt1 *jump if no overflow432 * 433 move.l #VALMAX,d5 *limit at VALMAX434 bra srcmlt2 *...435 * 436 srcmlt1: cmpi.l #VALMIN,d5 *check for underflow437 bge srcmlt2 *jump if no underflow438 * 439 move.l #VALMIN,d5 *limit at VALMIN440 * 441 srcmlt2: move.w d5,d3 *setup value for output to FPU442 * 443 .page 444 *------------------------------------------------------------------------------445 *adjust the value according to the function type446 *------------------------------------------------------------------------------447 nosrc: move.w d1,d0 *get function type448 andi.w # $01E0,d0 *...449 * 450 *------------------------------------------------------------------------------451 *level or location452 *------------------------------------------------------------------------------453 cmpi.w #P_LEVEL,d0 *see if it's the level454 beq outsegl *jump if so455 * 456 cmpi.w #P_LOCN,d0 *see if it's the location457 bne outsegf *jump if not458 * 459 tst.w d3 *check sign of value460 bpl outsegc *jump if positive461 * 462 clr.w d3 *force negative values to 0463 * 464 outsegc: asr.w #5,d3 *shift value to LS bits465 sub.w #500,d3 *subtract 5.00 from value466 asl.w #6,d3 *readjust to MS bits467 bra outseg3 *go output the value468 * 469 outsegl: tst.w d3 *check sign of value470 bpl outsegm *jump if positive471 * 472 clr.w d3 *limit negative values at 0473 * 474 outsegm: asr.w #5,d3 *shift value to LS bits475 sub.w #500,d3 *subtract 5.00 from value476 asl.w #6,d3 *readjust to MS bits477 bra outseg3 *go output the value478 * 479 .page 480 *------------------------------------------------------------------------------481 *filter482 *------------------------------------------------------------------------------483 outsegf: cmpi.w #P_FILTER,d0 *see if it's the filter484 bne outsegp *jump if not485 * 486 ext.l d3 *make function value a long487 asr.l #1,d3 *multiply function value by .75488 move.l d3,d0 *... (fast multiply by .75489 asr.l #1,d0 *... via shift and add)490 add.l d0,d3 *...491 move.w (a1),d0 *add pitch492 ext.l d0 *...493 add.l d0,d3 *...494 cmpi.l #VALMAX,d3 *see if it's within limits495 ble outsega *...496 * 497 move.w #VALMAX,d3 *limit at VALMAX498 bra outseg3 *...499 * 500 outsega: cmpi.l #VALMIN,d3 *...501 bge outseg3 *...502 * 503 move.w #VALMIN,d3 *limit at VALMIN504 bra outseg3 *...505 * 506 .page 507 *------------------------------------------------------------------------------508 *freq 1..4509 *------------------------------------------------------------------------------510 outsegp: cmpi.w #P_FREQ1,d0 *see if it's freq1511 beq outseg0 *go process freq1512 * 513 outsegq: cmpi.w #P_FREQ2,d0 *see if it's freq2514 beq outseg0 *process it if so515 * 516 cmpi.w #P_FREQ3,d0 *see if it's freq3517 beq outseg0 *process it if so518 * 519 cmpi.w #P_FREQ4,d0 *see if it's freq4520 bne outseg3 *jump if not521 * 522 outseg0: ext.l d3 *scale the point value to cents offset523 asr.l #5,d3 *...524 sub.l #500,d3 *... value - 500525 asl.l #LSPCH,d3 *mult. by 2 and scale for 1/2 cent lsb526 move.w (a1),d0 *add pitch from function header527 ext.l d0 *...528 add.l d0,d3 *...529 cmp.l #PCHMAX,d3 *see if result is valid530 ble outseg3 *jump if within pitch limits531 * 532 move.l #PCHMAX,d3 *limit at maximum pitch533 * 534 *------------------------------------------------------------------------------535 *send the value to the FPU536 *------------------------------------------------------------------------------537 outseg3: move.b FH_TMD(a1),d0 *get hardware bits from function header538 eor.w #VAL_BITS,d0 *toggle new value select bits539 move.b d0,FH_TMD(a1) *store updated word540 btst.l #VSUBNBIT,d0 *check which value address to use28 29 .page 30 | ------------------------------------------------------------------------------ 31 | Register usage 32 | -------------- 33 | d0 scratch 34 | d1 FPU function index 35 | d2 point index from FH_CPT (idfcpt) 36 | d3 scratch 37 | d4 jump point number from PT_PAR1 (ippar1) 38 | d5 scratch 39 40 | a0 scratch 41 | a1 function header base 42 | a2 point table base 43 | a3 FPU base 44 45 | ------------------------------------------------------------------------------ 46 | FPU definitions 47 | --------------- 48 49 UPD_BIT = 0x0001 | update bit (1 = update) 50 INT_BIT = 0x0002 | int. bit (0 = disable) 51 RAT_BIT = 0x0004 | ratio bit (0 = ratio) 52 53 VSUBNBIT = 3 | new value select bit number 54 VAL_BITS = 0x0018 | new value select bit mask 55 56 MSK_RNVB = 0x000C | new value / ratio bits 57 MSK_ONVB = 0x0010 | old new value bit 58 59 FKILL = 0x0014 | kill value for function 60 FSEND = 0x0015 | send new value to function 61 62 CLREXP = 0x8000 | clear value for time exponent 63 CLRMNT = 0x8000 | clear value for time mantissa 64 65 | ------------------------------------------------------------------------------ 66 | Miscellaneous definitions 67 | ------------------------- 68 69 PCHMAX = 21920 | maximum pitch value 70 VALMAX = 32000 | maximum value to send to FPU 71 VALMIN = -32000 | minimum value to send to FPU 72 73 LSPCH = 2 | left shift for sources to freq 74 75 VALLEN = 10 | length of the 'valent' struct 76 VT_VAL = 8 | value offset in 'valent' 77 78 .page 79 | ------------------------------------------------------------------------------ 80 | FPU addresses 81 | ------------- 82 83 FPUBASE = 0x180000 | FPU base address 84 85 FPUWST = FPUBASE | FPU waveshape base 86 FPUFUNC = FPUBASE+0x4000 | FPU function base 87 FPUINT1 = FPUBASE+0x4000 | FPU int. input address (R/O) 88 FPUINT2 = FPUBASE+0x6000 | FPU int. reset address (W/O) 89 FPUCFG = FPUBASE+0x5FE0 | FPU config. data address (W/O) 90 91 F_CTL = 0x00 | control word 92 F_VAL10 = 0x02 | new value "10" 93 F_CV1 = 0x08 | control voltage 1 94 F_SF1 = 0x0A | scale factor 1 95 F_CV2 = 0x0C | control voltage 2 96 F_SF2 = 0x0E | scale factor 2 97 F_CV3 = 0x10 | control voltage 3 98 F_SF3 = 0x12 | scale factor 3 99 F_MNT = 0x14 | time mantissa 100 F_EXP = 0x16 | time exponent 101 F_VAL01 = 0x1C | new value "01" 102 103 P_FREQ1 = 0x0020 | frequency 1 104 P_FREQ2 = 0x0060 | frequency 2 105 P_FREQ3 = 0x00A0 | frequency 3 106 P_FREQ4 = 0x00E0 | frequency 4 107 P_FILTER = 0x0140 | filter 108 P_FILTRQ = 0x00C0 | filter q 109 110 P_INDEX1 = 0x0120 | index 1 111 P_INDEX2 = 0x0160 | index 2 112 P_INDEX3 = 0x0180 | index 3 113 P_INDEX4 = 0x01A0 | index 4 114 P_INDEX5 = 0x01C0 | index 5 115 P_INDEX6 = 0x01E0 | index 6 116 117 P_LEVEL = 0x0040 | level 118 119 P_LOCN = 0x0080 | location 120 P_DYNAM = 0x0100 | dynamics 121 122 .page 123 | ------------------------------------------------------------------------------ 124 | Structure definitions 125 | ------------------------------------------------------------------------------ 126 | The following MUST match the idfnhdr structure definition in instdsp.h: 127 128 FH_LEN = 12 | length of the idfnhdr structure 129 130 FH_PCH = 0 | WORD - pitch offset 131 FH_MLT = 2 | WORD - overall value multiplier 132 FH_SRC = 4 | BYTE - overall value source 133 FH_PIF = 5 | BYTE - # of points in the function 134 FH_PT1 = 6 | BYTE - index of first point 135 FH_TMD = 7 | BYTE - trigger mode / control bits 136 FH_CPT = 8 | BYTE - current point 137 FH_PRM = 9 | BYTE - misc. function parameter 138 FH_TRG = 10 | WORD - trigger 139 140 I_ACTIVE = 1 | 'Active' bit number (in FH_TMD) 141 142 MSK_CTL = 0x001C | mask for FPU hardware bits (in FH_TMD) 143 144 | ------------------------------------------------------------------------------ 145 | The following MUST match the instpnt structure definition in instdsp.h: 146 147 PT_LEN = 12 | length of the instpnt structure 148 149 PT_TIM = 0 | WORD - time (packed) 150 PT_VAL = 2 | WORD - value 151 PT_VMLT = 4 | WORD - value multiplier 152 PT_VSRC = 6 | BYTE - value source 153 PT_ACT = 7 | BYTE - action 154 PT_PAR1 = 8 | BYTE - parameter 1 155 PT_PAR2 = 9 | BYTE - parameter 2 156 PT_PAR3 = 10 | BYTE - parameter 3 157 PT_PAD = 11 | BYTE - padding for even boundary 158 159 MSK_MNT = 0xFFF0 | mask for mantissa (in PT_TIM) 160 MSK_EXP = 0x000F | mask for exponent (in PT_TIM) 161 162 MAX_ACT = 7 | maximum action code value 163 164 | ------------------------------------------------------------------------------ 165 | Source definitions -- must match those in 'smdefs.h' 166 167 SM_RAND = 1 | random 168 SM_PTCH = 5 | pitch 169 SM_KPRS = 6 | key pressure 170 SM_KVEL = 7 | key velocity 171 SM_FREQ = 10 | frequency 172 173 .page 174 175 | Layout of pflist entries 32 bytes each 176 | ------------------------ 177 PF_NEXT = 0 | LONG - next entry pointer 178 PF_TRIG = 4 | WORD - trigger number 179 PF_FUNC = 6 | WORD - fpuifnc value 180 PF_D1 = 8 | LONG - d1 181 PF_D2 = 12 | LONG - d2 182 PF_D4 = 16 | LONG - d4 183 PF_A1 = 20 | LONG - a1 184 PF_A2 = 24 | LONG - a2 185 PF_A3 = 28 | LONG - a3 186 187 | Parameter offset 188 | ---------------- 189 TRIG = 8 | WORD - trigger number 190 191 | Register equates 192 | ---------------- 193 RCUR = a4 | current pflist entry pointer 194 RPRV = a5 | previous pflist entry pointer 195 196 .page 197 | ------------------------------------------------------------------------------ 198 | _procpfl() -- process pendant functions 199 200 | void 201 | procpfl(trig); 202 | unsigned trig; 203 204 | Processes pendant (sustained) functions by restarting them 205 | when the trigger (trig) that's sustaining them is released. 206 | Invoked by key release processing in msm() and localkb(). 207 208 | ------------------------------------------------------------------------------ 209 210 _procpfl: nop | FOR DEBUGGING PATCH 211 212 link a6,#0 | allocate stack frame 213 movem.l d3-d7/a3-a5,-(a7) | preserve registers we use 214 215 move.w sr,d7 | save interrupt state 216 move.w #0x2200,sr | turn off FPU interrupts 217 218 move.w TRIG(a6),d6 | get trigger we're processing 219 move.w d6,_curpf_t | ... 220 movea.l #_pflist,RPRV | point at 'previous' pflist entry 221 bra pfscan | go scan the chain 222 223 pfpass: movea.l RCUR,RPRV | point at previous entry 224 225 pfscan: move.l (RPRV),d5 | get next pflist entry pointer 226 beq pfexit | done if no more 227 228 movea.l d5,RCUR | point at current entry 229 move.l d5,_curpf_l | ... 230 231 cmp.w PF_TRIG(RCUR),d6 | see if this entry is wanted 232 bne pfpass | jump if not 233 234 movem.l PF_D1(RCUR),d1-d2/d4/a1-a3 | restore processing state 235 move.w PF_FUNC(RCUR),_curpf_f | ... 236 237 btst #I_ACTIVE,FH_TMD(a1) | see if function is active 238 bne doact | continue function if so 239 240 bra stopfn | stop function if not 241 242 pfnext: move.l (RCUR),(RPRV) | remove entry from pflist 243 move.l _pfqhdr,(RCUR) | chain entry to free list 244 move.l RCUR,_pfqhdr | ... 245 bra pfscan | go look at next entry 246 247 pfexit: move.w d7,sr | restore interrupt level 248 movem.l (a7)+,d3-d7/a3-a5 | restore the registers we used 249 unlk a6 | deallocate stack frame 250 rts | return to caller 251 252 .page 253 254 | ------------------------------------------------------------------------------ 255 | stop a function 256 | ------------------------------------------------------------------------------ 257 stopfn: move.b FH_TMD(a1),d0 | get function control bits 258 andi.w #MSK_RNVB,d0 | mask for ratio / new new-value bit 259 move.w d0,d3 | isolate new new-value bit 260 add.w d3,d3 | ... from function header 261 andi.w #MSK_ONVB,d3 | ... shift to old new-value bit 262 or.w d3,d0 | ... and put new bit in old bit 263 move.w d0,F_CTL(a3,d1.W) | stop the function 264 bclr #I_ACTIVE,FH_TMD(a1) | reset the active bit 265 bra pfnext | go restore registers and exit 266 267 | ------------------------------------------------------------------------------ 268 | setup for and dispatch to the proper action handler 269 | ------------------------------------------------------------------------------ 270 doact: clr.w d2 | get current point index in d2 271 move.b FH_CPT(a1),d2 | ... 272 lsl.w #2,d2 | multiply it by the length of a point 273 move.w d2,d0 | ... (fast multiply by PT_LEN = 12 274 add.w d2,d2 | ... via shift and add) 275 add.w d0,d2 | ... 276 clr.w d4 | get jump point # into d4 277 move.b PT_PAR1(a2,d2.W),d4 | ... 278 clr.w d3 | get action code in d3 279 move.b PT_ACT(a2,d2.W),d3 | ... 280 cmpi.b #MAX_ACT,d3 | check against the limit 281 bgt stopfn | stop things if it's a bad action code 282 283 lsl.w #2,d3 | develop index to action dispatch table 284 lea actab,a0 | get the address of the action handler 285 movea.l 0(a0,d3.W),a0 | ... 286 287 | ------------------------------------------------------------------------------ 288 | At this point we're ready to do the action associated with the point, 289 | and the registers are set up, and will remain, as follows: 290 291 | d1 FPU function index a1 function header base 292 | d2 point table index a2 point table base 293 | a3 FPU function base 294 | d4 jump point number 295 296 | d0, d3, d5, and a0 are used as scratch throughout the code. 297 298 | ------------------------------------------------------------------------------ 299 300 jmp (a0) | dispatch to action handler 301 302 .page 303 | ------------------------------------------------------------------------------ 304 | act0 -- AC_NULL -- no action 305 | ---- -------------------- 306 act0: move.b FH_PT1(a1),d0 | get first point number 307 add.b FH_PIF(a1),d0 | add number of points in function 308 subq.b #1,d0 | make it last point number 309 cmp.b FH_CPT(a1),d0 | see if we're at the last point 310 beq stopfn | stop function if so 311 312 addq.b #1,FH_CPT(a1) | update function header for next point 313 addi.w #PT_LEN,d2 | advance the point index 314 315 | ------------------------------------------------------------------------------ 316 | outseg -- output a segment 317 | ------ ---------------- 318 outseg: move.w PT_TIM(a2,d2.w),d3 | get packed time 319 move.w d3,d0 | extract mantissa 320 andi.w #MSK_MNT,d0 | ... 321 mulu _timemlt,d0 | multiply by panel time pot value 322 lsr.l #8,d0 | ... and scale it 323 lsr.l #7,d0 | ... 324 move.w d0,F_MNT(a3,d1.W) | send mantissa to FPU 325 andi.w #MSK_EXP,d3 | extract exponent code 326 add.w d3,d3 | look up decoded exponent 327 lea _expbit,a0 | ... in expbit 328 move.w 0(a0,d3.W),F_EXP(a3,d1.W) | send exponent to FPU 329 move.w PT_VAL(a2,d2.W),d3 | get the function value 330 331 .page 332 | ------------------------------------------------------------------------------ 333 | get the point source, if any 334 | ------------------------------------------------------------------------------ 335 tst.w PT_VMLT(a2,d2.W) | see if we have a point mlt. 336 beq nosrc | don't do anything for zero 337 338 clr.w d0 | get the source number 339 move.b PT_VSRC(a2,d2.W),d0 | ... 340 beq nosrc | don't do anything for zero 341 342 | ------------------------------------------------------------------------------ 343 | SM_RAND -- random 344 | ------------------------------------------------------------------------------ 345 cmpi.w #SM_RAND,d0 | is this the random source ? 346 bne srctyp0 | jump if not 347 348 movem.l d1-d2/a0-a2,-(a7) | preserve registers around call 349 move.w PT_VMLT(a2,d2.W),-(a7) | pass multiplier to xgetran() 350 jsr _xgetran | call for a random number 351 tst.w (a7)+ | clean up stack 352 movem.l (a7)+,d1-d2/a0-a2 | restore registers 353 move.w d0,d5 | put random value in the value register 354 bra applym | go apply the multiplier 355 356 .page 357 | ------------------------------------------------------------------------------ 358 | SM_FREQ -- frequency 359 | ------------------------------------------------------------------------------ 360 srctyp0: cmpi.w #SM_FREQ,d0 | is this the frequency source ? 361 bne srctyp1 | jump if not 362 363 move.w (a1),d0 | get the pitch 364 lsr.w #6,d0 | shift to a word index 365 andi.w #0x01FE,d0 | mask out extraneous bits 366 lea _ptoftab,a0 | get entry from ptoftab[] 367 move.w 0(a0,d0.W),d5 | ... 368 bra applym | go apply the multiplier 369 370 | ------------------------------------------------------------------------------ 371 | SM_PTCH -- pitch 372 | ------------------------------------------------------------------------------ 373 srctyp1: cmpi.w #SM_PTCH,d0 | is this the pitch source ? 374 bne srctyp2 | jump if not 375 376 move.w (a1),d5 | get the pitch as the value 377 bra applym | go apply the multiplier 378 379 | ------------------------------------------------------------------------------ 380 | SM_KVEL -- velocity 381 | ------------------------------------------------------------------------------ 382 srctyp2: cmpi.w #SM_KVEL,d0 | is this the key velocity source ? 383 bne srctyp3 | jump if not 384 385 move.w FH_TRG(a1),d0 | get the trigger number 386 add.w d0,d0 | ... as a word index 387 lea _veltab,a0 | ... into veltab[] 388 move.w 0(a0,d0.W),d5 | get the velocity from veltab[trg] 389 bra applym | go apply the multiplier 390 391 | ------------------------------------------------------------------------------ 392 | SM_KPRS -- pressure 393 | ------------------------------------------------------------------------------ 394 srctyp3: cmpi.w #SM_KPRS,d0 | is this the key pressure source ? 395 bne srctyp4 | jump if not (must be an analog input) 396 397 move.w FH_TRG(a1),d0 | get the trigger number 398 add.w d0,d0 | ... as a word index 399 lea _prstab,a0 | ... into prstab[] 400 move.w 0(a0,d0.W),d5 | get the pressure from prstab[trg] 401 bra applym | go apply the multiplier 402 403 .page 404 | ------------------------------------------------------------------------------ 405 | all other sources come out of the valents[] array 406 | ------------------------------------------------------------------------------ 407 srctyp4: lea _vce2grp,a0 | point at vce2grp[] 408 move.w _curpf_f,d5 | get voice number in d5 409 lsr.w #3,d5 | ... 410 andi.w #0x001E,d5 | ... as a word index 411 move.w 0(a0,d5.W),d5 | get the group number 412 subq.w #1,d5 | ... 413 lsl.w #4,d5 | shift it left a nybble 414 or.w d5,d0 | OR it into the source number 415 add.w d0,d0 | make source number a valents[] index 416 move.w d0,d5 | ... (fast multiply by VALLEN = 10 417 lsl.w #2,d0 | ... via shift and add) 418 add.w d5,d0 | ... 419 lea _valents,a0 | get base of valents[] 420 move.w VT_VAL(a0,d0.W),d5 | get value 421 422 | ------------------------------------------------------------------------------ 423 | apply the multiplier to the source, and add it to the function value 424 | ------------------------------------------------------------------------------ 425 applym: muls PT_VMLT(a2,d2.W),d5 | apply the multiplier 426 asr.l #7,d5 | scale the result 427 asr.l #8,d5 | ... 428 ext.l d3 | add the function value 429 add.l d3,d5 | ... 430 cmpi.l #VALMAX,d5 | check for overflow 431 ble srcmlt1 | jump if no overflow 432 433 move.l #VALMAX,d5 | limit at VALMAX 434 bra srcmlt2 | ... 435 436 srcmlt1: cmpi.l #VALMIN,d5 | check for underflow 437 bge srcmlt2 | jump if no underflow 438 439 move.l #VALMIN,d5 | limit at VALMIN 440 441 srcmlt2: move.w d5,d3 | setup value for output to FPU 442 443 .page 444 | ------------------------------------------------------------------------------ 445 | adjust the value according to the function type 446 | ------------------------------------------------------------------------------ 447 nosrc: move.w d1,d0 | get function type 448 andi.w #0x01E0,d0 | ... 449 450 | ------------------------------------------------------------------------------ 451 | level or location 452 | ------------------------------------------------------------------------------ 453 cmpi.w #P_LEVEL,d0 | see if it's the level 454 beq outsegl | jump if so 455 456 cmpi.w #P_LOCN,d0 | see if it's the location 457 bne outsegf | jump if not 458 459 tst.w d3 | check sign of value 460 bpl outsegc | jump if positive 461 462 clr.w d3 | force negative values to 0 463 464 outsegc: asr.w #5,d3 | shift value to LS bits 465 sub.w #500,d3 | subtract 5.00 from value 466 asl.w #6,d3 | readjust to MS bits 467 bra outseg3 | go output the value 468 469 outsegl: tst.w d3 | check sign of value 470 bpl outsegm | jump if positive 471 472 clr.w d3 | limit negative values at 0 473 474 outsegm: asr.w #5,d3 | shift value to LS bits 475 sub.w #500,d3 | subtract 5.00 from value 476 asl.w #6,d3 | readjust to MS bits 477 bra outseg3 | go output the value 478 479 .page 480 | ------------------------------------------------------------------------------ 481 | filter 482 | ------------------------------------------------------------------------------ 483 outsegf: cmpi.w #P_FILTER,d0 | see if it's the filter 484 bne outsegp | jump if not 485 486 ext.l d3 | make function value a long 487 asr.l #1,d3 | multiply function value by .75 488 move.l d3,d0 | ... (fast multiply by .75 489 asr.l #1,d0 | ... via shift and add) 490 add.l d0,d3 | ... 491 move.w (a1),d0 | add pitch 492 ext.l d0 | ... 493 add.l d0,d3 | ... 494 cmpi.l #VALMAX,d3 | see if it's within limits 495 ble outsega | ... 496 497 move.w #VALMAX,d3 | limit at VALMAX 498 bra outseg3 | ... 499 500 outsega: cmpi.l #VALMIN,d3 | ... 501 bge outseg3 | ... 502 503 move.w #VALMIN,d3 | limit at VALMIN 504 bra outseg3 | ... 505 506 .page 507 | ------------------------------------------------------------------------------ 508 | freq 1..4 509 | ------------------------------------------------------------------------------ 510 outsegp: cmpi.w #P_FREQ1,d0 | see if it's freq1 511 beq outseg0 | go process freq1 512 513 outsegq: cmpi.w #P_FREQ2,d0 | see if it's freq2 514 beq outseg0 | process it if so 515 516 cmpi.w #P_FREQ3,d0 | see if it's freq3 517 beq outseg0 | process it if so 518 519 cmpi.w #P_FREQ4,d0 | see if it's freq4 520 bne outseg3 | jump if not 521 522 outseg0: ext.l d3 | scale the point value to cents offset 523 asr.l #5,d3 | ... 524 sub.l #500,d3 | ... value - 500 525 asl.l #LSPCH,d3 | mult. by 2 and scale for 1/2 cent lsb 526 move.w (a1),d0 | add pitch from function header 527 ext.l d0 | ... 528 add.l d0,d3 | ... 529 cmp.l #PCHMAX,d3 | see if result is valid 530 ble outseg3 | jump if within pitch limits 531 532 move.l #PCHMAX,d3 | limit at maximum pitch 533 534 | ------------------------------------------------------------------------------ 535 | send the value to the FPU 536 | ------------------------------------------------------------------------------ 537 outseg3: move.b FH_TMD(a1),d0 | get hardware bits from function header 538 eor.w #VAL_BITS,d0 | toggle new value select bits 539 move.b d0,FH_TMD(a1) | store updated word 540 btst.l #VSUBNBIT,d0 | check which value address to use 541 541 beq outseg1 542 * 543 move.w d3,F_VAL01(a3,d1.W) *send value to FPU542 543 move.w d3,F_VAL01(a3,d1.W) | send value to FPU 544 544 bra outseg2 545 * 546 outseg1: move.w d3,F_VAL10(a3,d1.W) *send value to FPU547 * 548 outseg2: andi.w #MSK_CTL,d0 *mask off software bits549 ori.w #UPD_BIT+INT_BIT,d0 *set the update & !lastseg bits550 move.w d0,F_CTL(a3,d1.W) *send control word to FPU551 bra pfnext *done -- exit552 * 553 .page 554 * 555 *------------------------------------------------------------------------------556 *act2 -- AC_ENBL -- stop if key is up557 *---- ----------------------------558 act2: move.w _curpf_f,d0 *get voice as a word index559 lsr.w #3,d0 *...560 andi.w # $001E,d0 *...561 lea _vce2trg,a0 *check to see if voice is free562 move.w 0(a0,d0.W),d0 *...563 cmpi.w #-1,d0 *...564 beq stopfn *if so, stop the function565 * 566 btst #15,d0 *see if voice is held567 bne act0 *continue if so568 * 569 btst #14,d0 *...570 bne act0 *...571 * 572 lea _trgtab,a0 *check trigger table entry573 tst.b 0(a0,d0.W) *...574 bne act0 *if trigger is active, continue575 * 576 bra stopfn *if not, stop the function577 * 578 *------------------------------------------------------------------------------579 *act3 -- AC_JUMP -- unconditional jump580 *---- -----------------------------581 act3: cmp.b FH_PIF(a1),d4 *check jump point against limit582 bcc stopfn *stop function if jump point invalid583 * 584 clr.w d2 *get index of first point585 move.b FH_PT1(a1),d2 *...586 add.b d4,d2 *add jump point587 move.b d2,FH_CPT(a1) *make it the current point588 lsl.w #2,d2 *develop new point index in d2589 move.w d2,d0 *... (fast multiply by PT_LEN = 12590 add.w d2,d2 *... via shift and add)591 add.w d0,d2 *...592 bra outseg *output the segment593 * 594 .page 595 * 596 *------------------------------------------------------------------------------597 *act4 -- AC_LOOP -- jump to point PT_PAR1 PT_PAR2 times598 *---- ----------------------------------------------599 act4: tst.b PT_PAR3(a2,d2.W) *check counter600 bne act4a *jump if it's running601 * 602 move.b PT_PAR2(a2,d2.W),d0 *get parameter603 subi.w #90,d0 *put parameter in random range604 bmi act4b *treat as normal if < 90605 * 606 movem.l d1-d2/a0-a2,-(a7) *get ranged random number607 move.w d0,-(a7) *...608 jsr _irand *...609 tst.w (a7)+ *...610 movem.l (a7)+,d1-d2/a0-a2 *...611 move.b d0,PT_PAR3(a2,d2.w) *set counter612 beq act0 *next segment if cntr set to 0613 * 614 bra act3 *else jump to the point615 * 616 act4b: move.b PT_PAR2(a2,d2.W),PT_PAR3(a2,d2.W) *set counter617 beq act0 *next segment if cntr set to 0618 * 619 bra act3 *else jump to the point620 * 621 act4a: subq.b #1,PT_PAR3(a2,d2.W) *decrement counter622 beq act0 *next segment if cntr ran out623 * 624 bra act3 *jump if it's still non-zero625 * 626 *------------------------------------------------------------------------------627 *act5 -- AC_KYUP -- jump if key is up628 *---- ----------------------------629 act5: move.w _curpf_f,d0 *get voice as a word index630 lsr.w #3,d0 *...631 andi.w # $001E,d0 *...632 lea _vce2trg,a0 *check to see if voice is free633 move.w 0(a0,d0.W),d0 *...634 cmpi.w #-1,d0 *...635 beq act3 *if so (inactive), do the jump636 * 637 btst #15,d0 *see if voice is held638 bne act0 *continue if so639 * 640 btst #14,d0 *...641 bne act0 *...642 * 643 lea _trgtab,a0 *check trigger table entry644 tst.b 0(a0,d0.W) *see if the trigger is active645 beq act3 *if not, do the jump646 * 647 bra act0 *if so, do next segment648 * 649 .page 650 * 651 *------------------------------------------------------------------------------652 *act6 -- AC_KYDN -- jump if key is down653 *---- ------------------------------654 act6: move.w _curpf_f,d0 *get voice as a word index655 lsr.w #3,d0 *...656 andi.w # $001E,d0 *...657 lea _vce2trg,a0 *check to see if voice is free658 move.w 0(a0,d0.W),d0 *...659 cmpi.w #-1,d0 *...660 beq act0 *if so (inactive), continue661 * 662 btst #15,d0 *see if voice is held663 bne act3 *do jump if so664 * 665 btst #14,d0 *...666 bne act3 *...667 * 668 lea _trgtab,a0 *check trigger table entry669 tst.b 0(a0,d0.W) *see if the trigger is active670 bne act3 *if so, do the jump671 * 672 bra act0 *if not, do next segment673 * 674 *------------------------------------------------------------------------------675 act7: bra act0 *AC_HERE: treat act7 as AC_NULL676 * 677 .page 678 * 679 *act1 -- AC_SUST -- pause if key is down (sustain)680 *---- -----------------------------------------681 act1: move.w _curpf_f,d0 *get voice as a word index682 lsr.w #3,d0 *...683 andi.w # $001E,d0 *...684 lea _vce2trg,a0 *point at voice to trigger table685 move.w 0(a0,d0.W),d0 *get trigger table entry686 cmpi.w #-1,d0 *see if voice is free687 beq act0 *treat as no-op if so688 * 689 btst #15,d0 *see if voice is held by a pedal690 bne act1a *sustain if so691 * 692 btst #14,d0 *see if voice is sustained by a pedal693 bne act1a *sustain if so694 * 695 lea _trgtab,a0 *point at trigger table696 tst.b 0(a0,d0.W) *check trigger status697 beq act0 *continue if not active698 * 699 act1a: move.l _pfqhdr,d3 *see if any pflist entries remain700 beq act0 *no-op if not (shouldn't happen ...)701 * 702 move.b FH_PT1(a1),d0 *get first point number703 add.b FH_PIF(a1),d0 *add base to first point704 subq.b #1,d0 *make d0 last point number705 cmp.b FH_CPT(a1),d0 *check current point number706 beq stopfn *done if this is the last point707 * 708 addq.b #1,FH_CPT(a1) *update current point number709 addi.w #PT_LEN,d2 *update point index710 movea.l d3,a0 *acquire a new pflist entry711 move.l (a0),_pfqhdr *...712 move.l _pflist,(a0) *...713 move.l a0,_pflist *...714 move.w FH_TRG(a1),PF_TRIG(a0) *set trigger number in entry715 move.w _curpf_f,PF_FUNC(a0) *set v/p word in entry716 movem.l d1-d2/d4/a1-a3,PF_D1(a0) *set registers in entry717 move.b FH_TMD(a1),d0 *stop the function718 andi.w #MSK_RNVB,d0 *...719 move.w d0,d3 *...720 add.w d3,d3 *...721 andi.w #MSK_ONVB,d3 *...722 or.w d3,d0 *...723 move.w d0,F_CTL(a3,d1.W) *...724 bra pfnext *go do next list entry725 * 726 .page 727 *------------------------------------------------------------------------------545 546 outseg1: move.w d3,F_VAL10(a3,d1.W) | send value to FPU 547 548 outseg2: andi.w #MSK_CTL,d0 | mask off software bits 549 ori.w #UPD_BIT+INT_BIT,d0 | set the update & !lastseg bits 550 move.w d0,F_CTL(a3,d1.W) | send control word to FPU 551 bra pfnext | done -- exit 552 553 .page 554 555 | ------------------------------------------------------------------------------ 556 | act2 -- AC_ENBL -- stop if key is up 557 | ---- ---------------------------- 558 act2: move.w _curpf_f,d0 | get voice as a word index 559 lsr.w #3,d0 | ... 560 andi.w #0x001E,d0 | ... 561 lea _vce2trg,a0 | check to see if voice is free 562 move.w 0(a0,d0.W),d0 | ... 563 cmpi.w #-1,d0 | ... 564 beq stopfn | if so, stop the function 565 566 btst #15,d0 | see if voice is held 567 bne act0 | continue if so 568 569 btst #14,d0 | ... 570 bne act0 | ... 571 572 lea _trgtab,a0 | check trigger table entry 573 tst.b 0(a0,d0.W) | ... 574 bne act0 | if trigger is active, continue 575 576 bra stopfn | if not, stop the function 577 578 | ------------------------------------------------------------------------------ 579 | act3 -- AC_JUMP -- unconditional jump 580 | ---- ----------------------------- 581 act3: cmp.b FH_PIF(a1),d4 | check jump point against limit 582 bcc stopfn | stop function if jump point invalid 583 584 clr.w d2 | get index of first point 585 move.b FH_PT1(a1),d2 | ... 586 add.b d4,d2 | add jump point 587 move.b d2,FH_CPT(a1) | make it the current point 588 lsl.w #2,d2 | develop new point index in d2 589 move.w d2,d0 | ... (fast multiply by PT_LEN = 12 590 add.w d2,d2 | ... via shift and add) 591 add.w d0,d2 | ... 592 bra outseg | output the segment 593 594 .page 595 596 | ------------------------------------------------------------------------------ 597 | act4 -- AC_LOOP -- jump to point PT_PAR1 PT_PAR2 times 598 | ---- ---------------------------------------------- 599 act4: tst.b PT_PAR3(a2,d2.W) | check counter 600 bne act4a | jump if it's running 601 602 move.b PT_PAR2(a2,d2.W),d0 | get parameter 603 subi.w #90,d0 | put parameter in random range 604 bmi act4b | treat as normal if < 90 605 606 movem.l d1-d2/a0-a2,-(a7) | get ranged random number 607 move.w d0,-(a7) | ... 608 jsr _irand | ... 609 tst.w (a7)+ | ... 610 movem.l (a7)+,d1-d2/a0-a2 | ... 611 move.b d0,PT_PAR3(a2,d2.w) | set counter 612 beq act0 | next segment if cntr set to 0 613 614 bra act3 | else jump to the point 615 616 act4b: move.b PT_PAR2(a2,d2.W),PT_PAR3(a2,d2.W) | set counter 617 beq act0 | next segment if cntr set to 0 618 619 bra act3 | else jump to the point 620 621 act4a: subq.b #1,PT_PAR3(a2,d2.W) | decrement counter 622 beq act0 | next segment if cntr ran out 623 624 bra act3 | jump if it's still non-zero 625 626 | ------------------------------------------------------------------------------ 627 | act5 -- AC_KYUP -- jump if key is up 628 | ---- ---------------------------- 629 act5: move.w _curpf_f,d0 | get voice as a word index 630 lsr.w #3,d0 | ... 631 andi.w #0x001E,d0 | ... 632 lea _vce2trg,a0 | check to see if voice is free 633 move.w 0(a0,d0.W),d0 | ... 634 cmpi.w #-1,d0 | ... 635 beq act3 | if so (inactive), do the jump 636 637 btst #15,d0 | see if voice is held 638 bne act0 | continue if so 639 640 btst #14,d0 | ... 641 bne act0 | ... 642 643 lea _trgtab,a0 | check trigger table entry 644 tst.b 0(a0,d0.W) | see if the trigger is active 645 beq act3 | if not, do the jump 646 647 bra act0 | if so, do next segment 648 649 .page 650 651 | ------------------------------------------------------------------------------ 652 | act6 -- AC_KYDN -- jump if key is down 653 | ---- ------------------------------ 654 act6: move.w _curpf_f,d0 | get voice as a word index 655 lsr.w #3,d0 | ... 656 andi.w #0x001E,d0 | ... 657 lea _vce2trg,a0 | check to see if voice is free 658 move.w 0(a0,d0.W),d0 | ... 659 cmpi.w #-1,d0 | ... 660 beq act0 | if so (inactive), continue 661 662 btst #15,d0 | see if voice is held 663 bne act3 | do jump if so 664 665 btst #14,d0 | ... 666 bne act3 | ... 667 668 lea _trgtab,a0 | check trigger table entry 669 tst.b 0(a0,d0.W) | see if the trigger is active 670 bne act3 | if so, do the jump 671 672 bra act0 | if not, do next segment 673 674 | ------------------------------------------------------------------------------ 675 act7: bra act0 | AC_HERE: treat act7 as AC_NULL 676 677 .page 678 679 | act1 -- AC_SUST -- pause if key is down (sustain) 680 | ---- ----------------------------------------- 681 act1: move.w _curpf_f,d0 | get voice as a word index 682 lsr.w #3,d0 | ... 683 andi.w #0x001E,d0 | ... 684 lea _vce2trg,a0 | point at voice to trigger table 685 move.w 0(a0,d0.W),d0 | get trigger table entry 686 cmpi.w #-1,d0 | see if voice is free 687 beq act0 | treat as no-op if so 688 689 btst #15,d0 | see if voice is held by a pedal 690 bne act1a | sustain if so 691 692 btst #14,d0 | see if voice is sustained by a pedal 693 bne act1a | sustain if so 694 695 lea _trgtab,a0 | point at trigger table 696 tst.b 0(a0,d0.W) | check trigger status 697 beq act0 | continue if not active 698 699 act1a: move.l _pfqhdr,d3 | see if any pflist entries remain 700 beq act0 | no-op if not (shouldn't happen ...) 701 702 move.b FH_PT1(a1),d0 | get first point number 703 add.b FH_PIF(a1),d0 | add base to first point 704 subq.b #1,d0 | make d0 last point number 705 cmp.b FH_CPT(a1),d0 | check current point number 706 beq stopfn | done if this is the last point 707 708 addq.b #1,FH_CPT(a1) | update current point number 709 addi.w #PT_LEN,d2 | update point index 710 movea.l d3,a0 | acquire a new pflist entry 711 move.l (a0),_pfqhdr | ... 712 move.l _pflist,(a0) | ... 713 move.l a0,_pflist | ... 714 move.w FH_TRG(a1),PF_TRIG(a0) | set trigger number in entry 715 move.w _curpf_f,PF_FUNC(a0) | set v/p word in entry 716 movem.l d1-d2/d4/a1-a3,PF_D1(a0) | set registers in entry 717 move.b FH_TMD(a1),d0 | stop the function 718 andi.w #MSK_RNVB,d0 | ... 719 move.w d0,d3 | ... 720 add.w d3,d3 | ... 721 andi.w #MSK_ONVB,d3 | ... 722 or.w d3,d0 | ... 723 move.w d0,F_CTL(a3,d1.W) | ... 724 bra pfnext | go do next list entry 725 726 .page 727 | ------------------------------------------------------------------------------ 728 728 .data 729 *------------------------------------------------------------------------------730 * 731 *actab -- action code dispatch table732 *----- --------------------------733 actab: dc.l act0 *0 - AC_NULL: no action734 dc.l act1 *1 - AC_SUST: sustain735 dc.l act2 *2 - AC_ENBL: enable736 dc.l act3 *3 - AC_JUMP: unconditional jump737 dc.l act4 *4 - AC_LOOP: jump n times (loop)738 dc.l act5 *5 - AC_KYUP: jump if key up (enable jump)739 dc.l act6 *6 - AC_KYDN: jump if key down (sustain jump)740 dc.l act7 *7 - AC_HERE: here on key up741 * 742 *------------------------------------------------------------------------------729 | ------------------------------------------------------------------------------ 730 731 | actab -- action code dispatch table 732 | ----- -------------------------- 733 actab: dc.l act0 | 0 - AC_NULL: no action 734 dc.l act1 | 1 - AC_SUST: sustain 735 dc.l act2 | 2 - AC_ENBL: enable 736 dc.l act3 | 3 - AC_JUMP: unconditional jump 737 dc.l act4 | 4 - AC_LOOP: jump n times (loop) 738 dc.l act5 | 5 - AC_KYUP: jump if key up (enable jump) 739 dc.l act6 | 6 - AC_KYDN: jump if key down (sustain jump) 740 dc.l act7 | 7 - AC_HERE: here on key up 741 742 | ------------------------------------------------------------------------------ 743 743 .bss 744 *------------------------------------------------------------------------------745 * 746 *----------------- local variables --------------------------------------------747 * 748 _curpf_f: ds.w 1 *interrupting voice & parameter from FPU749 * 750 *----------------- debug variables --------------------------------------------751 * 752 _curpf_t: ds.w 1 *current trigger753 * 754 _curpf_l: ds.l 1 *current pflist entry755 * 756 *------------------------------------------------------------------------------757 * 744 | ------------------------------------------------------------------------------ 745 746 | ----------------- local variables -------------------------------------------- 747 748 _curpf_f: ds.w 1 | interrupting voice & parameter from FPU 749 750 | ----------------- debug variables -------------------------------------------- 751 752 _curpf_t: ds.w 1 | current trigger 753 754 _curpf_l: ds.l 1 | current pflist entry 755 756 | ------------------------------------------------------------------------------ 757 758 758 .end -
ram/sedisp.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *sedisp.s -- score event display driver3 *Version 43 -- 1988-09-26 -- D.N. Lynx Crowe4 * 5 *se_disp(ep, sd, gdstb, cf)6 * struct s_entry *ep;7 *short sd;8 * struct gdsel *gdstb[];9 *short cf;10 * 11 *Displays the event at 'ep', scrolling in direction 'sd', by12 *updating 'gdstb'. Uses the accidental code in 'ac_code', and13 *the note type table 'nsvtab'. Checks 'cf' to determine if14 *we're displaying in the center of the screen.15 *Allocates gdsel events as needed for new events.16 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | sedisp.s -- score event display driver 3 | Version 43 -- 1988-09-26 -- D.N. Lynx Crowe 4 5 | se_disp(ep, sd, gdstb, cf) 6 | struct s_entry |ep; 7 | short sd; 8 | struct gdsel |gdstb[]; 9 | short cf; 10 11 | Displays the event at 'ep', scrolling in direction 'sd', by 12 | updating 'gdstb'. Uses the accidental code in 'ac_code', and 13 | the note type table 'nsvtab'. Checks 'cf' to determine if 14 | we're displaying in the center of the screen. 15 | Allocates gdsel events as needed for new events. 16 | ------------------------------------------------------------------------------ 17 17 .text 18 * 18 19 19 .xdef _se_disp 20 * 20 21 21 .xdef _ac_code 22 22 .xdef numstr 23 * 23 24 24 .xref _dclkmd 25 25 .xref _dsgmodz … … 29 29 .xref _vputc 30 30 .xref _vputs 31 * 31 32 32 .xref _angroup 33 33 .xref _ctrsw … … 49 49 .xref _vrbw15 50 50 .xref _vrcw 51 * 52 .page 53 * 54 *parameter offsets55 *-----------------56 *for se_disp:57 *------------58 P_EP .equ 8 *LONG - event pointer59 P_SD .equ 12 *WORD - scroll direction60 P_SL .equ 14 *LONG - slice control table pointer61 P_CF .equ 18 *WORD - center slice flag62 * 63 *for vputa:64 *----------65 ROW .equ 4 *WORD - 'row' parameter offset66 COL .equ 6 *WORD - 'col' parameter offset67 ATR .equ 8 *WORD - 'atr' parameter offset68 * 69 *Character field attributes for highlighting70 *-------------------------------------------71 AT01 .equ $005472 AT04 .equ $005373 AT05 .equ $005474 AT06 .equ $005375 AT07 .equ $005476 AT08 .equ $005377 AT09 .equ $005478 AT10 .equ $005379 AT11 .equ $005280 AT12 .equ $005281 * 82 *Special character equates83 *-------------------------84 SP_M1 .equ $A1 *-185 SP_P1 .equ $A0 *+186 * 87 .page 88 * 89 *event structure offsets90 *-----------------------91 *offset length92 *------ ------93 E_TIME .equ 0 *LONG94 E_SIZE .equ 4 *BYTE95 E_TYPE .equ 5 *BYTE96 E_DATA1 .equ 6 *BYTE97 E_NOTE .equ 6 *BYTE98 E_DATA2 .equ 7 *BYTE99 E_GROUP .equ 7 *BYTE100 E_BAK .equ 8 *LONG101 E_FWD .equ 12 *LONG102 E_DN .equ 16 *LONG103 E_VEL .equ 16 *WORD104 E_DATA4 .equ 18 *WORD105 E_UP .equ 20 *LONG106 E_LFT .equ 24 *LONG107 E_RGT .equ 28 *LONG108 * 109 N_ETYPES .equ 25 *number of event types110 * 111 *gdsel structure definitions112 *---------------------------113 G_NEXT .equ 0 * long - 'next' field (struct gdsel *)114 G_NOTE .equ 4 *word - 'note' field (short)115 G_CODE .equ 6 *word - 'code' field (short)116 * 117 NATCH_B .equ 3 *uslice note code: 'begin natural'118 NOTE_E .equ 6 *uslice note code: 'end note'119 * 120 NGDSEL .equ 17 *number of event slots in gdstb121 * 122 BARFLAG .equ 4*(NGDSEL-1) *offset to the bar marker flag123 * 124 .page 125 * 126 *A few words about se_disp:127 *--------------------------128 *se_disp has to be very fast, so it's written in assembly language,129 *rather than C, which is usually pretty good, but not quite good enough130 *for this application. The faster this routine runs, the higher the131 *tempo we can keep up with. If this code is fast enough, we end up132 *hardware limited by the maximum rate of the timer, and the VSDD update rate.133 * 134 _se_disp: link a6,#0 *allocate and link stack frame135 movea.l P_EP(a6),a0 *get event pointer 'ep' into a0136 move.b E_TYPE(a0),d1 *get event type into d1.W137 andi.w # $007F,d1 *mask off new-note flag138 cmp.b #N_ETYPES,d1 *see if it's valid139 blt seds1 *jump if it is140 * 141 dsexit: unlk a6 *done -- unlink stack frames142 rts *return to caller143 * 144 seds1: lea sddtab,a1 *get base of dispatch table145 lsl.w #2,d1 *multiplty event by 4 for index146 movea.l 0(a1,d1.W),a2 *get address of event routine147 jmp (a2) *jump to event display routine148 * 149 *On entry, the individual display routines only depend on a0 pointing at the150 *event they were dispatched for. Registers a6 and a7 have their usual meaning,151 *a6 = frame pointer, a7 = stack pointer.152 * 153 *d0..d2 are used for scratch, as are a0..a2, and are not saved by this code.154 * 155 .page 156 * 157 *dsnbx -- dispatch to begin / end based on sd158 *----- -----------------------------------159 dsnbx: tst.w P_SD(a7) *check direction160 bne dsne *treat as end if going backward161 * 162 *dsnb -- display note begin163 *---- ------------------164 dsnb: move.b E_TYPE(a0),d1 *get event type165 move.w d1,d2 *save in d2166 andi.w # $007F,d1 *clear new-note flag167 move.b d1,E_TYPE(a0) *store type back in event168 clr.w d0 *get group number169 move.b E_GROUP(a0),d0 *... in d0170 move.w d0,d1 *save group in d1171 add.w d0,d0 *make d0 a word offset172 lea _grpstat,a1 *check grpstat[grp]173 tst.w 0(a1,d0.W) *...174 beq dsexit *done if not enabled175 * 176 tst.w P_CF(a6) *check center slice flag177 beq dsnb0 *jump if not center slice178 * 179 tst.w _velflag *see if we display velocity180 beq dsnvx *jump if not181 * 182 move.w d2,-(a7) *save new-note flag on stack183 move.w d1,-(a7) *save group number on stack184 move.w E_VEL(a0),d0 *get velocity185 move.w d1,d2 *point into lastvel[]186 add.w d2,d2 *...187 lea _lastvel,a1 *...188 move.w d0,0(a1,d2.W) *update lastvel[group]189 ext.l d0 *scale190 divu #252,d0 *...191 cmpi.w #100,d0 *convert MS digit192 bcs dsnv0 *...193 * 194 move.b #'1',numstr *...195 subi.w #100,d0 *...196 bra dsnv1 *...197 * 198 dsnv0: move.b #'0',numstr *...199 * 200 dsnv1: ext.l d0 *convert middle & LS digits201 divu #10,d0 *...202 addi.l # $00300030,d0 *...203 move.b d0,numstr+1 *...204 swap d0 *...205 move.b d0,numstr+2 *...206 clr.b numstr+3 *terminate string207 move.w d1,d0 *col = group208 asl.w #2,d0 * ... *5209 add.w d1,d0 *...210 add.w #6,d0 *... + 6211 move.l a0,-(a7) *save event pointer on stack212 move.w #AT11,-(a7) *put attribute on stack213 move.l #numstr,-(a7) *put string address on stack214 move.w d0,-(a7) *put column on stack215 move.w #5,-(a7) *put row on stack216 move.l _obj8,-(a7) *put VSDD address on stack217 jsr _vputs *update the screen218 add.l #14,a7 *clean up stack219 movea.l (a7)+,a0 *restore event pointer220 * 221 .page 222 * 223 move.w (a7)+,d0 *get group from stack224 cmpi.w #12,d0 *see which byte it's in225 bcc dsnv2 *jump if in MS byte226 * 227 bset d0,_vrbw12+1 *set group bit in LS byte228 bra dsnv3 *...229 * 230 dsnv2: bset d0,_vrbw12 *set group bit in MS byte231 * 232 dsnv3: bset #4,_vrcw *set video reset type bit233 move.w (a7)+,d2 *get new-note flag from stack234 * 235 dsnvx: btst.l #7,d2 *check new-note flag236 beq dsexit *done if not set237 * 238 dsnb0: clr.w d1 *get note number nn (0..127)239 move.b E_NOTE(a0),d1 *... in d1240 sub.w #21,d1 *subtract base of piano scale241 bmi dsexit *done if not displayable242 * 243 cmp.w #87,d1 *see if it's too high244 bgt dsexit *done if not displayable245 * 246 move.l _gdfsep,d0 *quit if no elements left247 beq dsexit *...248 * 249 movea.l d0,a1 *a1 = gdsp250 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next251 clr.w d2 *d2 = ep->group252 move.b E_GROUP(a0),d2 *...253 lsl.w #2,d2 * ... *4254 movea.l P_SL(a6),a2 *a2 points at gdstb255 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[ep->group]256 move.l a1,0(a2,d2.W) *gdstb[ep->group] = gdsp257 move.w d1,G_NOTE(a1) *gdsp->note = nn258 lea _nsvtab,a2 *a2 points at nsvtab259 tst.b 0(a2,d1.W) *check nsvtab[nn]260 beq dsnb1 *jump if natural note261 * 262 move.b _ac_code,d1 *setup for an accidental note263 bra dsnb2 *...264 * 265 dsnb1: move.b #NATCH_B,d1 *setup for a natural note266 * 267 dsnb2: move.w d1,G_CODE(a1) *gdsp->code = note type268 bra dsexit *done269 * 270 .page 271 * 272 *dsnex -- dispatch to end/begin based on sd273 *----- ---------------------------------274 dsnex: tst.w P_SD(a7) *check direction275 bne dsnb *treat as begin if going backward276 * 277 *dsne -- display note end278 *---- ----------------279 dsne: move.b E_TYPE(a0),d1 *get event type280 move.w d1,d2 *save in d2281 andi.w # $007F,d1 *clear new-note flag282 move.b d1,E_TYPE(a0) *store type back in event283 clr.w d0 *get group number284 move.b E_GROUP(a0),d0 *... in d0285 add.w d0,d0 *... as a word offset286 lea _grpstat,a1 *check grpstat[grp]287 tst.w 0(a1,d0.W) *...288 beq dsexit *done if not enabled289 * 290 tst.w P_CF(a6) *check center slice flag291 beq dsne3 *jump if not center slice292 * 293 btst.l #7,d2 *check new-note flag294 beq dsexit *done if not set295 * 296 dsne3: move.b E_NOTE(a0),d1 *d1 = note number nn (0..127)297 sub.w #21,d1 *subtract base of piano scale298 bmi dsexit *done if not displayable299 * 300 cmp.w #87,d1 *see if it's too high301 bgt dsexit *done if not displayable302 * 303 movea.l P_SL(a6),a2 *a2 points at gdstb304 clr.w d2 *get group in d2305 move.b E_GROUP(a0),d2 *...306 lsl.w #2,d2 * ... *4307 move.l 0(a2,d2.W),d0 *check gdstb[ep->group]51 52 .page 53 54 | parameter offsets 55 | ----------------- 56 | for se_disp: 57 | ------------ 58 P_EP = 8 | LONG - event pointer 59 P_SD = 12 | WORD - scroll direction 60 P_SL = 14 | LONG - slice control table pointer 61 P_CF = 18 | WORD - center slice flag 62 63 | for vputa: 64 | ---------- 65 ROW = 4 | WORD - 'row' parameter offset 66 COL = 6 | WORD - 'col' parameter offset 67 ATR = 8 | WORD - 'atr' parameter offset 68 69 | Character field attributes for highlighting 70 | ------------------------------------------- 71 AT01 = 0x0054 72 AT04 = 0x0053 73 AT05 = 0x0054 74 AT06 = 0x0053 75 AT07 = 0x0054 76 AT08 = 0x0053 77 AT09 = 0x0054 78 AT10 = 0x0053 79 AT11 = 0x0052 80 AT12 = 0x0052 81 82 | Special character equates 83 | ------------------------- 84 SP_M1 = 0xA1 | -1 85 SP_P1 = 0xA0 | +1 86 87 .page 88 89 | event structure offsets 90 | ----------------------- 91 | offset length 92 | ------ ------ 93 E_TIME = 0 | LONG 94 E_SIZE = 4 | BYTE 95 E_TYPE = 5 | BYTE 96 E_DATA1 = 6 | BYTE 97 E_NOTE = 6 | BYTE 98 E_DATA2 = 7 | BYTE 99 E_GROUP = 7 | BYTE 100 E_BAK = 8 | LONG 101 E_FWD = 12 | LONG 102 E_DN = 16 | LONG 103 E_VEL = 16 | WORD 104 E_DATA4 = 18 | WORD 105 E_UP = 20 | LONG 106 E_LFT = 24 | LONG 107 E_RGT = 28 | LONG 108 109 N_ETYPES = 25 | number of event types 110 111 | gdsel structure definitions 112 | --------------------------- 113 G_NEXT = 0 | long - 'next' field (struct gdsel |) 114 G_NOTE = 4 | word - 'note' field (short) 115 G_CODE = 6 | word - 'code' field (short) 116 117 NATCH_B = 3 | uslice note code: 'begin natural' 118 NOTE_E = 6 | uslice note code: 'end note' 119 120 NGDSEL = 17 | number of event slots in gdstb 121 122 BARFLAG = 4|(NGDSEL-1) | offset to the bar marker flag 123 124 .page 125 126 | A few words about se_disp: 127 | -------------------------- 128 | se_disp has to be very fast, so it's written in assembly language, 129 | rather than C, which is usually pretty good, but not quite good enough 130 | for this application. The faster this routine runs, the higher the 131 | tempo we can keep up with. If this code is fast enough, we end up 132 | hardware limited by the maximum rate of the timer, and the VSDD update rate. 133 134 _se_disp: link a6,#0 | allocate and link stack frame 135 movea.l P_EP(a6),a0 | get event pointer 'ep' into a0 136 move.b E_TYPE(a0),d1 | get event type into d1.W 137 andi.w #0x007F,d1 | mask off new-note flag 138 cmp.b #N_ETYPES,d1 | see if it's valid 139 blt seds1 | jump if it is 140 141 dsexit: unlk a6 | done -- unlink stack frames 142 rts | return to caller 143 144 seds1: lea sddtab,a1 | get base of dispatch table 145 lsl.w #2,d1 | multiplty event by 4 for index 146 movea.l 0(a1,d1.W),a2 | get address of event routine 147 jmp (a2) | jump to event display routine 148 149 | On entry, the individual display routines only depend on a0 pointing at the 150 | event they were dispatched for. Registers a6 and a7 have their usual meaning, 151 | a6 = frame pointer, a7 = stack pointer. 152 153 | d0..d2 are used for scratch, as are a0..a2, and are not saved by this code. 154 155 .page 156 157 | dsnbx -- dispatch to begin / end based on sd 158 | ----- ----------------------------------- 159 dsnbx: tst.w P_SD(a7) | check direction 160 bne dsne | treat as end if going backward 161 162 | dsnb -- display note begin 163 | ---- ------------------ 164 dsnb: move.b E_TYPE(a0),d1 | get event type 165 move.w d1,d2 | save in d2 166 andi.w #0x007F,d1 | clear new-note flag 167 move.b d1,E_TYPE(a0) | store type back in event 168 clr.w d0 | get group number 169 move.b E_GROUP(a0),d0 | ... in d0 170 move.w d0,d1 | save group in d1 171 add.w d0,d0 | make d0 a word offset 172 lea _grpstat,a1 | check grpstat[grp] 173 tst.w 0(a1,d0.W) | ... 174 beq dsexit | done if not enabled 175 176 tst.w P_CF(a6) | check center slice flag 177 beq dsnb0 | jump if not center slice 178 179 tst.w _velflag | see if we display velocity 180 beq dsnvx | jump if not 181 182 move.w d2,-(a7) | save new-note flag on stack 183 move.w d1,-(a7) | save group number on stack 184 move.w E_VEL(a0),d0 | get velocity 185 move.w d1,d2 | point into lastvel[] 186 add.w d2,d2 | ... 187 lea _lastvel,a1 | ... 188 move.w d0,0(a1,d2.W) | update lastvel[group] 189 ext.l d0 | scale 190 divu #252,d0 | ... 191 cmpi.w #100,d0 | convert MS digit 192 bcs dsnv0 | ... 193 194 move.b #'1',numstr | ... 195 subi.w #100,d0 | ... 196 bra dsnv1 | ... 197 198 dsnv0: move.b #'0',numstr | ... 199 200 dsnv1: ext.l d0 | convert middle & LS digits 201 divu #10,d0 | ... 202 addi.l #0x00300030,d0 | ... 203 move.b d0,numstr+1 | ... 204 swap d0 | ... 205 move.b d0,numstr+2 | ... 206 clr.b numstr+3 | terminate string 207 move.w d1,d0 | col = group 208 asl.w #2,d0 | ... | 5 209 add.w d1,d0 | ... 210 add.w #6,d0 | ... + 6 211 move.l a0,-(a7) | save event pointer on stack 212 move.w #AT11,-(a7) | put attribute on stack 213 move.l #numstr,-(a7) | put string address on stack 214 move.w d0,-(a7) | put column on stack 215 move.w #5,-(a7) | put row on stack 216 move.l _obj8,-(a7) | put VSDD address on stack 217 jsr _vputs | update the screen 218 add.l #14,a7 | clean up stack 219 movea.l (a7)+,a0 | restore event pointer 220 221 .page 222 223 move.w (a7)+,d0 | get group from stack 224 cmpi.w #12,d0 | see which byte it's in 225 bcc dsnv2 | jump if in MS byte 226 227 bset d0,_vrbw12+1 | set group bit in LS byte 228 bra dsnv3 | ... 229 230 dsnv2: bset d0,_vrbw12 | set group bit in MS byte 231 232 dsnv3: bset #4,_vrcw | set video reset type bit 233 move.w (a7)+,d2 | get new-note flag from stack 234 235 dsnvx: btst.l #7,d2 | check new-note flag 236 beq dsexit | done if not set 237 238 dsnb0: clr.w d1 | get note number nn (0..127) 239 move.b E_NOTE(a0),d1 | ... in d1 240 sub.w #21,d1 | subtract base of piano scale 241 bmi dsexit | done if not displayable 242 243 cmp.w #87,d1 | see if it's too high 244 bgt dsexit | done if not displayable 245 246 move.l _gdfsep,d0 | quit if no elements left 247 beq dsexit | ... 248 249 movea.l d0,a1 | a1 = gdsp 250 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 251 clr.w d2 | d2 = ep->group 252 move.b E_GROUP(a0),d2 | ... 253 lsl.w #2,d2 | ... | 4 254 movea.l P_SL(a6),a2 | a2 points at gdstb 255 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[ep->group] 256 move.l a1,0(a2,d2.W) | gdstb[ep->group] = gdsp 257 move.w d1,G_NOTE(a1) | gdsp->note = nn 258 lea _nsvtab,a2 | a2 points at nsvtab 259 tst.b 0(a2,d1.W) | check nsvtab[nn] 260 beq dsnb1 | jump if natural note 261 262 move.b _ac_code,d1 | setup for an accidental note 263 bra dsnb2 | ... 264 265 dsnb1: move.b #NATCH_B,d1 | setup for a natural note 266 267 dsnb2: move.w d1,G_CODE(a1) | gdsp->code = note type 268 bra dsexit | done 269 270 .page 271 272 | dsnex -- dispatch to end/begin based on sd 273 | ----- --------------------------------- 274 dsnex: tst.w P_SD(a7) | check direction 275 bne dsnb | treat as begin if going backward 276 277 | dsne -- display note end 278 | ---- ---------------- 279 dsne: move.b E_TYPE(a0),d1 | get event type 280 move.w d1,d2 | save in d2 281 andi.w #0x007F,d1 | clear new-note flag 282 move.b d1,E_TYPE(a0) | store type back in event 283 clr.w d0 | get group number 284 move.b E_GROUP(a0),d0 | ... in d0 285 add.w d0,d0 | ... as a word offset 286 lea _grpstat,a1 | check grpstat[grp] 287 tst.w 0(a1,d0.W) | ... 288 beq dsexit | done if not enabled 289 290 tst.w P_CF(a6) | check center slice flag 291 beq dsne3 | jump if not center slice 292 293 btst.l #7,d2 | check new-note flag 294 beq dsexit | done if not set 295 296 dsne3: move.b E_NOTE(a0),d1 | d1 = note number nn (0..127) 297 sub.w #21,d1 | subtract base of piano scale 298 bmi dsexit | done if not displayable 299 300 cmp.w #87,d1 | see if it's too high 301 bgt dsexit | done if not displayable 302 303 movea.l P_SL(a6),a2 | a2 points at gdstb 304 clr.w d2 | get group in d2 305 move.b E_GROUP(a0),d2 | ... 306 lsl.w #2,d2 | ... | 4 307 move.l 0(a2,d2.W),d0 | check gdstb[ep->group] 308 308 beq dsexit 309 * 310 dsne0: movea.l d0,a1 *a1 = gdsp311 * 312 dsne1: cmp.w G_NOTE(a1),d1 *compare nn to gdsp->note313 bne dsne2 *jump if not the one we want314 * 315 move.w #NOTE_E,G_CODE(a1) *gdsp->code = NOTE_E (end note)316 * 317 dsne2: move.l G_NEXT(a1),d0 *get gdsp->next318 beq dsexit *done if next = NULL319 * 320 bra dsne0 *loop for next one321 * 322 .page 323 * 324 *dssbgn -- display section begin325 *------ ---------------------326 dssbgn: tst.w P_CF(a6) *center update ?327 beq dsbgn0 *jump if not328 * 329 clr.w d1 *get section number330 move.b E_DATA1(a0),d1 *... from the event331 addq.w #1,d1 *... adjusted for display332 ext.l d1 *... as a long in d1333 divu #10,d1 *divide by 10 for conversion334 add.l # $00300030,d1 *add '0' for ASCII conversion335 move.b d1,numstr *put MS byte in work area336 swap d1 *swap register halves337 move.b d1,numstr+1 *put LS byte in work area338 clr.b numstr+2 *terminate string339 move.w #AT01,-(a7) *put attribute on stack340 move.l #numstr,-(a7) *put buffer address on stack341 move.w #6,-(a7) *put column on stack342 move.w #0,-(a7) *put row on stack343 move.l _obj8,-(a7) *put sbase on stack344 jsr _vputs *update the screen345 add.l #14,a7 *clean up stack346 bset #4,_vrcw+1 *set video reset type bit347 tst.w _ctrsw *update center for scupd ?348 beq dsexit *done if not349 * 350 dsbgn0: move.l _gdfsep,d0 *quit if no elements left351 beq dsexit *...352 * 353 movea.l d0,a1 *a1 = gdsp354 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next355 move.w #48,d2 * d2 = event PRIORITY *4356 movea.l P_SL(a6),a2 *a2 points at gdstb357 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]358 move.w # $1111,G_NOTE(a1) *gdsp->note = COLOR359 move.w #0,G_CODE(a1) *gdsp->code = PATTERN360 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp361 bra dsexit *done362 * 363 .page 364 * 365 *dssend -- display section end366 *------ -------------------367 dssend: tst.w P_CF(a6) *center update ?368 beq dssend0 *jump if not369 * 370 tst.w _ctrsw *update center for scupd ?371 beq dsexit *done if not372 * 373 dssend0: move.l _gdfsep,d0 *quit if no elements left374 beq dsexit *...375 * 376 movea.l d0,a1 *a1 = gdsp377 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next378 move.w #48,d2 * d2 = event PRIORITY *4379 movea.l P_SL(a6),a2 *a2 points at gdstb380 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]381 move.w # $1111,G_NOTE(a1) *gdsp->note = COLOR382 move.w #2,G_CODE(a1) *gdsp->code = PATTERN383 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp384 bra dsexit *done385 * 386 *dsbeat -- display beat387 *------ ------------388 dsbeat: tst.w P_CF(a6) *center update ?389 bne dsexit *done if so390 * 391 move.l _gdfsep,d0 *quit if no elements left392 beq dsexit *...393 * 394 movea.l d0,a1 *a1 = gdsp395 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next396 move.w #48,d2 * d2 = event PRIORITY *4397 movea.l P_SL(a6),a2 *a2 points at gdstb398 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]399 move.w # $1111,G_NOTE(a1) *gdsp->note = COLOR400 move.w #1,G_CODE(a1) *gdsp->code = PATTERN401 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp402 bra dsexit *done403 * 404 .page 405 * 406 *dstune -- display tuning407 *------ --------------408 dstune: tst.w P_CF(a6) *center update ?409 beq dstune0 *jump if not410 * 411 clr.w d1 *get current tuning412 move.b E_DATA1(a0),d1 *...413 add.w # $0030,d1 *add '0' for ASCII conversion414 move.w #AT05,-(a7) *put attribute on stack415 move.w d1,-(a7) *put character on stack416 move.w #19,-(a7) *put column on stack417 move.w #1,-(a7) *put row on stack418 move.l _obj8,-(a7) *put sbase on stack419 jsr _vputc *display character420 add.l #12,a7 *clean up stack421 bset #1,_vrcw+1 *set video reset type bit422 tst.w _ctrsw *update center for scupd ?423 beq dsexit *done if not424 * 425 dstune0: move.l _gdfsep,d0 *quit if no elements left426 beq dsexit *...427 * 428 movea.l d0,a1 *a1 = gdsp429 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next430 move.w #52,d2 * d2 = event PRIORITY *4431 movea.l P_SL(a6),a2 *a2 points at gdstb432 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]433 move.w # $CCCC,G_NOTE(a1) *gdsp->note = COLOR434 move.w #3,G_CODE(a1) *gdsp->code = PATTERN435 move.l a1,0(a2,d2.W) *gdstb[priority] = gdsp436 bra dsexit *done437 * 438 .page 439 * 440 *dstrns -- display transposition441 *------ ---------------------442 dstrns: clr.w d0 *get group number443 move.b E_DATA1(a0),d0 *... in d0444 add.w d0,d0 *... as a word offset445 lea _grpstat,a1 *check grpstat[grp]446 tst.w 0(a1,d0.W) *...447 beq dsexit *done if not enabled448 * 449 tst.w P_CF(a6) *center update450 beq dstrns0 *jump if not451 * 452 move.w E_LFT(a0),d1 *get transposition value453 bpl dstrns1 *jump if positive454 * 455 move.b #'-',numstr *note negative sign456 neg.w d1 *make number positive457 bra dstrns2 *...458 * 459 dstrns1: move.b #'+',numstr *note positive sign460 * 461 dstrns2: cmpi.w #1000,d1 *is number GE 1000 ?462 bcs dstrns3 *jump if not463 * 464 subi.w #1000,d1 *adjust number465 cmpi.b #'-',numstr *was number negative466 bne dstrns4 *jump if not467 * 468 move.b #SP_M1,numstr *set -1 in numstr469 bra dstrns3 *...470 * 471 dstrns4: move.b #SP_P1,numstr *set +1 in numstr472 * 473 dstrns3: ext.l d1 *make d1 a long474 divu #100,d1 *convert 1st digit475 addi.w # $0030,d1 *... to ASCII476 move.b d1,numstr+1 *... in numstr477 swap d1 *convert 2nd digit478 ext.l d1 *...479 divu #10,d1 *...480 addi.w # $0030,d1 *... to ASCII481 move.b d1,numstr+2 *... in numstr482 swap d1 *convert 3rd digit483 addi.w # $0030,d1 *... to ASCII484 move.b d1,numstr+3 *... in numstr485 clr.b numstr+4 *terminate numstr486 * 487 .page 488 * 489 move.w d0,d1 *get group number490 asr.w #1,d1 *... in d1491 move.w d1,-(a7) *save group number on stack492 add.w d0,d0 *calculate column493 add.w d0,d1 * ... = 5 *group494 addi.w #5,d1 *... + 5495 move.w #AT11,-(a7) *vputs(obj8, 3, col, numstr, atr11)496 move.l #numstr,-(a7) *...497 move.w d1,-(a7) *...498 move.w #3,-(a7) *...499 move.l _obj8,-(a7) *...500 jsr _vputs *...501 add.l #14,a7 *...502 move.w (a7)+,d0 *get group number503 cmpi.w #8,d0 *see which byte it's in504 bcc dstrns5 *jump if in MS byte505 * 506 bset d0,_vrbw09+1 *set group bit in LS byte507 bra dstrns6 *...508 * 509 dstrns5: sub.w #8,d0 *adjust for byte510 bset d0,_vrbw09 *set group bit in MS byte511 * 512 dstrns6: bset #1,_vrcw *set video reset type bit513 tst.w _ctrsw *update center for scupd ?514 beq dsexit *done if not515 * 516 dstrns0: move.l _gdfsep,d0 *quit if no elements left517 beq dsexit *...518 * 519 movea.l d0,a1 *a1 = gdsp520 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next521 move.w #52,d2 * d2 = event PRIORITY *4522 movea.l P_SL(a6),a2 *a2 points at gdstb523 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]524 move.w # $9999,G_NOTE(a1) *gdsp->note = COLOR525 move.w #4,G_CODE(a1) *gdsp->code = PATTERN526 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp527 bra dsexit *done528 * 529 .page 530 * 531 *dsdyn -- display dynamics532 *----- ----------------533 dsdyn: clr.w d0 *get group number534 move.b E_DATA1(a0),d0 *... in d0535 add.w d0,d0 *... as a word offset536 lea _grpstat,a1 *check grpstat[grp]537 tst.w 0(a1,d0.W) *...538 beq dsexit *done if not enabled539 * 540 tst.w P_CF(a6) *center update ?541 beq dsdyn00 *jump if not542 * 543 clr.w d0 *get dynamics544 move.b E_DATA2(a0),d0 *... in d0545 move.w d0,-(a7) *save dyanmics546 clr.w d1 *get group number547 move.b E_DATA1(a0),d1 *... in d1548 move.w d1,-(a7) *save group number549 move.w (a7),d0 *col = group number550 add.w d0,d0 * ... *5551 add.w d0,d0 *...552 move.w (a7)+,d2 *... (d2 = group number)553 add.w d2,d0 *...554 add.w #6,d0 *... + 6555 move.w (a7)+,d1 *get dynamics556 add.w # $0030,d1 *add '0' for ASCII conversion557 move.w d2,-(a7) *save group number558 move.w #AT11,-(a7) *put attribute on stack559 move.w d1,-(a7) *put digit on stack560 move.w d0,-(a7) *put column on stack561 move.w #4,-(a7) *put row on stack562 move.l _obj8,-(a7) *put object address on stack563 jsr _vputc *update the screen564 add.l #12,a7 *clean up stack565 move.w (a7)+,d0 *get group number566 cmp.w #8,d0 *see which word it's in567 bcc dsdyn1 *jump if in MS word568 * 569 bset d0,_vrbw10+1 *set group bit in LS byte570 bra dsdyn2 *...571 * 572 dsdyn1: sub.w #8,d0 *adjust for for byte573 bset d0,_vrbw10 *set group bit in MS byte574 * 575 dsdyn2: bset #2,_vrcw *set video reset type bit576 tst.w _ctrsw *update center for scupd ?577 beq dsexit *done if not578 * 579 .page 580 dsdyn00: move.l _gdfsep,d0 *quit if no elements left581 beq dsexit *...582 * 583 movea.l d0,a1 *a1 = gdsp584 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next585 move.w #52,d2 * d2 = event PRIORITY *4586 movea.l P_SL(a6),a2 *a2 points at gdstb587 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]588 move.w # $9999,G_NOTE(a1) *gdsp->note = COLOR589 move.w #5,G_CODE(a1) *gdsp->code = PATTERN590 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp591 bra dsexit *done592 * 593 .page 594 * 595 *dslocn -- display location596 *------ ----------------597 dslocn: clr.w d0 *get group number598 move.b E_DATA1(a0),d0 *... in d0599 add.w d0,d0 *... as a word offset600 lea _grpstat,a1 *check grpstat[grp]601 tst.w 0(a1,d0.W) *...602 beq dsexit *done if not enabled603 * 604 tst.w P_CF(a6) *center update ?605 beq dsloc00 *jump if not606 * 607 clr.w d0 *get location608 move.b E_DATA2(a0),d0 *... in d0609 move.w d0,-(a7) *save location610 clr.w d1 *get group number611 move.b E_DATA1(a0),d1 *... in d1612 move.w d1,-(a7) *save group number613 move.w (a7),d0 *col = group number614 add.w d0,d0 * ... *5615 add.w d0,d0 *...616 move.w (a7)+,d2 *... (d2 = group number)617 add.w d2,d0 *...618 add.w #8,d0 *... + 8619 move.w (a7)+,d1 *get location620 add.w # $0031,d1 *add '0' for ASCII conversion621 move.w d2,-(a7) *save group number622 move.w #AT11,-(a7) *put attribute on stack623 move.w d1,-(a7) *put character on stack624 move.w d0,-(a7) *put column on stack625 move.w #4,-(a7) *put row on stack626 move.l _obj8,-(a7) *put object address on stack627 jsr _vputc *update the screen628 add.l #12,a7 *clean up stack629 move.w (a7)+,d0 *get group number630 cmp.w #8,d0 *see which word it's in631 bcc dslocn1 *jump if in MS word632 * 633 bset d0,_vrbw11+1 *set group bit in LS byte634 bra dslocn2 *...635 * 636 dslocn1: sub.w #8,d0 *adjust for for byte637 bset d0,_vrbw11 *set group bit in MS byte638 * 639 dslocn2: bset #3,_vrcw *set video reset type bit640 tst.w _ctrsw *update center for scupd ?641 beq dsexit *done if not642 * 643 .page 644 dsloc00: move.l _gdfsep,d0 *quit if no elements left645 beq dsexit *...646 * 647 movea.l d0,a1 *a1 = gdsp648 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next649 move.w #52,d2 * d2 = event PRIORITY *4650 movea.l P_SL(a6),a2 *a2 points at gdstb651 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]652 move.w # $9999,G_NOTE(a1) *gdsp->note = COLOR653 move.w #5,G_CODE(a1) *gdsp->code = PATTERN654 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp655 bra dsexit *done656 * 657 .page 658 * 659 *dsanrs -- display analog resolution660 *------ -------------------------661 dsanrs: move.b E_DATA1(a0),d1 *get var / group662 move.w d1,d0 *extract group number663 andi.w # $000F,d0 *... in d0664 add.w d0,d0 *... as a word offset665 lea _grpstat,a1 *check grpstat[grp]666 tst.w 0(a1,d0.W) *...667 beq dsexit *done if not enabled668 * 669 tst.w P_CF(a6) *center update ?670 beq dsanrs0 *jump if not671 * 672 move.w _angroup,d2 *see if we display673 bmi dsexit *jump if not674 * 675 subq.w #1,d2 *adust selected group number676 move.w d1,d0 *extract group from event677 andi.w # $000F,d0 *...678 cmp.w d0,d2 *see if we display679 bne dsexit *jump if not680 * 681 lsr.w #4,d1 *extract variable number682 andi.w # $000F,d1 *...683 move.w d1,-(a7) *save variable number684 move.w d1,d0 *calculate display offset685 lsl.w #3,d0 * ... (var *9) + 6686 add.w d0,d1 *... in d1687 addq.w #6,d1 *...688 move.b E_DATA2(a0),d0 *get resolution689 addi.w # $0030,d0 *convert for display690 move.w #AT12,-(a7) *put attribute on stack691 move.w d0,-(a7) *put character on stack692 move.w d1,-(a7) *put column on stack693 move.w #7,-(a7) *put row on stack694 move.l _obj8,-(a7) *put sbase on stack695 jsr _vputc *update the screen696 add.l #12,a7 *clean up stack697 move.w (a7)+,d0 *get variable number698 bset d0,_vrbw13+1 *set variable bit699 bset #5,_vrcw *set video reset type bit700 tst.w _ctrsw *update center for scupd ?701 beq dsexit *done if not702 * 703 .page 704 dsanrs0: move.l _gdfsep,d0 *quit if no elements left705 beq dsexit *...706 * 707 movea.l d0,a1 *a1 = gdsp708 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next709 move.w #52,d2 * d2 = event PRIORITY *4710 movea.l P_SL(a6),a2 *a2 points at gdstb711 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]712 move.w # $9999,G_NOTE(a1) *gdsp->note = COLOR713 move.w #6,G_CODE(a1) *gdsp->code = PATTERN714 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp715 bra dsexit *done716 * 717 .page 718 * 719 *dsanvl -- display analog value720 *------ --------------------721 dsanvl: move.w _angroup,d2 *see if we display722 bmi dsexit *jump if not723 * 724 move.b E_DATA1(a0),d1 *get var / group725 move.w d1,d0 *extract group number726 andi.w # $000F,d0 *... in d0727 add.w d0,d0 *... as a word offset728 lea _grpstat,a1 *check grpstat[grp]729 tst.w 0(a1,d0.W) *...730 beq dsexit *done if not enabled731 * 732 tst.w P_CF(a6) *center update ?733 beq dsanvl0 *jump if not734 * 735 subq.w #1,d2 *adust group number736 move.w d1,d0 *extract group737 andi.w # $000F,d0 *...738 cmp.w d0,d2 *see if we display739 bne dsexit *jump if not740 * 741 lsr.w #4,d1 *extract variable number742 andi.w # $000F,d1 *...743 move.w d1,-(a7) *save variable number744 move.w d1,d0 *calculate display offset745 lsl.w #3,d0 * ... (var *9) + 8746 add.w d0,d1 *... in d1747 addi.w #8,d1 *...748 move.w E_DN(a0),d0 *get value749 asr.w #5,d0 *adjust to low 11 bits750 bpl dsanvl1 *jump if positive751 * 752 move.b #'-',numstr *set sign = '-'753 neg.w d0 *make value positive309 310 dsne0: movea.l d0,a1 | a1 = gdsp 311 312 dsne1: cmp.w G_NOTE(a1),d1 | compare nn to gdsp->note 313 bne dsne2 | jump if not the one we want 314 315 move.w #NOTE_E,G_CODE(a1) | gdsp->code = NOTE_E (end note) 316 317 dsne2: move.l G_NEXT(a1),d0 | get gdsp->next 318 beq dsexit | done if next = NULL 319 320 bra dsne0 | loop for next one 321 322 .page 323 324 | dssbgn -- display section begin 325 | ------ --------------------- 326 dssbgn: tst.w P_CF(a6) | center update ? 327 beq dsbgn0 | jump if not 328 329 clr.w d1 | get section number 330 move.b E_DATA1(a0),d1 | ... from the event 331 addq.w #1,d1 | ... adjusted for display 332 ext.l d1 | ... as a long in d1 333 divu #10,d1 | divide by 10 for conversion 334 add.l #0x00300030,d1 | add '0' for ASCII conversion 335 move.b d1,numstr | put MS byte in work area 336 swap d1 | swap register halves 337 move.b d1,numstr+1 | put LS byte in work area 338 clr.b numstr+2 | terminate string 339 move.w #AT01,-(a7) | put attribute on stack 340 move.l #numstr,-(a7) | put buffer address on stack 341 move.w #6,-(a7) | put column on stack 342 move.w #0,-(a7) | put row on stack 343 move.l _obj8,-(a7) | put sbase on stack 344 jsr _vputs | update the screen 345 add.l #14,a7 | clean up stack 346 bset #4,_vrcw+1 | set video reset type bit 347 tst.w _ctrsw | update center for scupd ? 348 beq dsexit | done if not 349 350 dsbgn0: move.l _gdfsep,d0 | quit if no elements left 351 beq dsexit | ... 352 353 movea.l d0,a1 | a1 = gdsp 354 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 355 move.w #48,d2 | d2 = event PRIORITY | 4 356 movea.l P_SL(a6),a2 | a2 points at gdstb 357 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 358 move.w #0x1111,G_NOTE(a1) | gdsp->note = COLOR 359 move.w #0,G_CODE(a1) | gdsp->code = PATTERN 360 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 361 bra dsexit | done 362 363 .page 364 365 | dssend -- display section end 366 | ------ ------------------- 367 dssend: tst.w P_CF(a6) | center update ? 368 beq dssend0 | jump if not 369 370 tst.w _ctrsw | update center for scupd ? 371 beq dsexit | done if not 372 373 dssend0: move.l _gdfsep,d0 | quit if no elements left 374 beq dsexit | ... 375 376 movea.l d0,a1 | a1 = gdsp 377 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 378 move.w #48,d2 | d2 = event PRIORITY | 4 379 movea.l P_SL(a6),a2 | a2 points at gdstb 380 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 381 move.w #0x1111,G_NOTE(a1) | gdsp->note = COLOR 382 move.w #2,G_CODE(a1) | gdsp->code = PATTERN 383 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 384 bra dsexit | done 385 386 | dsbeat -- display beat 387 | ------ ------------ 388 dsbeat: tst.w P_CF(a6) | center update ? 389 bne dsexit | done if so 390 391 move.l _gdfsep,d0 | quit if no elements left 392 beq dsexit | ... 393 394 movea.l d0,a1 | a1 = gdsp 395 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 396 move.w #48,d2 | d2 = event PRIORITY | 4 397 movea.l P_SL(a6),a2 | a2 points at gdstb 398 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 399 move.w #0x1111,G_NOTE(a1) | gdsp->note = COLOR 400 move.w #1,G_CODE(a1) | gdsp->code = PATTERN 401 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 402 bra dsexit | done 403 404 .page 405 406 | dstune -- display tuning 407 | ------ -------------- 408 dstune: tst.w P_CF(a6) | center update ? 409 beq dstune0 | jump if not 410 411 clr.w d1 | get current tuning 412 move.b E_DATA1(a0),d1 | ... 413 add.w #0x0030,d1 | add '0' for ASCII conversion 414 move.w #AT05,-(a7) | put attribute on stack 415 move.w d1,-(a7) | put character on stack 416 move.w #19,-(a7) | put column on stack 417 move.w #1,-(a7) | put row on stack 418 move.l _obj8,-(a7) | put sbase on stack 419 jsr _vputc | display character 420 add.l #12,a7 | clean up stack 421 bset #1,_vrcw+1 | set video reset type bit 422 tst.w _ctrsw | update center for scupd ? 423 beq dsexit | done if not 424 425 dstune0: move.l _gdfsep,d0 | quit if no elements left 426 beq dsexit | ... 427 428 movea.l d0,a1 | a1 = gdsp 429 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 430 move.w #52,d2 | d2 = event PRIORITY | 4 431 movea.l P_SL(a6),a2 | a2 points at gdstb 432 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 433 move.w #0xCCCC,G_NOTE(a1) | gdsp->note = COLOR 434 move.w #3,G_CODE(a1) | gdsp->code = PATTERN 435 move.l a1,0(a2,d2.W) | gdstb[priority] = gdsp 436 bra dsexit | done 437 438 .page 439 440 | dstrns -- display transposition 441 | ------ --------------------- 442 dstrns: clr.w d0 | get group number 443 move.b E_DATA1(a0),d0 | ... in d0 444 add.w d0,d0 | ... as a word offset 445 lea _grpstat,a1 | check grpstat[grp] 446 tst.w 0(a1,d0.W) | ... 447 beq dsexit | done if not enabled 448 449 tst.w P_CF(a6) | center update 450 beq dstrns0 | jump if not 451 452 move.w E_LFT(a0),d1 | get transposition value 453 bpl dstrns1 | jump if positive 454 455 move.b #'-',numstr | note negative sign 456 neg.w d1 | make number positive 457 bra dstrns2 | ... 458 459 dstrns1: move.b #'+',numstr | note positive sign 460 461 dstrns2: cmpi.w #1000,d1 | is number GE 1000 ? 462 bcs dstrns3 | jump if not 463 464 subi.w #1000,d1 | adjust number 465 cmpi.b #'-',numstr | was number negative 466 bne dstrns4 | jump if not 467 468 move.b #SP_M1,numstr | set -1 in numstr 469 bra dstrns3 | ... 470 471 dstrns4: move.b #SP_P1,numstr | set +1 in numstr 472 473 dstrns3: ext.l d1 | make d1 a long 474 divu #100,d1 | convert 1st digit 475 addi.w #0x0030,d1 | ... to ASCII 476 move.b d1,numstr+1 | ... in numstr 477 swap d1 | convert 2nd digit 478 ext.l d1 | ... 479 divu #10,d1 | ... 480 addi.w #0x0030,d1 | ... to ASCII 481 move.b d1,numstr+2 | ... in numstr 482 swap d1 | convert 3rd digit 483 addi.w #0x0030,d1 | ... to ASCII 484 move.b d1,numstr+3 | ... in numstr 485 clr.b numstr+4 | terminate numstr 486 487 .page 488 489 move.w d0,d1 | get group number 490 asr.w #1,d1 | ... in d1 491 move.w d1,-(a7) | save group number on stack 492 add.w d0,d0 | calculate column 493 add.w d0,d1 | ... = 5 | group 494 addi.w #5,d1 | ... + 5 495 move.w #AT11,-(a7) | vputs(obj8, 3, col, numstr, atr11) 496 move.l #numstr,-(a7) | ... 497 move.w d1,-(a7) | ... 498 move.w #3,-(a7) | ... 499 move.l _obj8,-(a7) | ... 500 jsr _vputs | ... 501 add.l #14,a7 | ... 502 move.w (a7)+,d0 | get group number 503 cmpi.w #8,d0 | see which byte it's in 504 bcc dstrns5 | jump if in MS byte 505 506 bset d0,_vrbw09+1 | set group bit in LS byte 507 bra dstrns6 | ... 508 509 dstrns5: sub.w #8,d0 | adjust for byte 510 bset d0,_vrbw09 | set group bit in MS byte 511 512 dstrns6: bset #1,_vrcw | set video reset type bit 513 tst.w _ctrsw | update center for scupd ? 514 beq dsexit | done if not 515 516 dstrns0: move.l _gdfsep,d0 | quit if no elements left 517 beq dsexit | ... 518 519 movea.l d0,a1 | a1 = gdsp 520 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 521 move.w #52,d2 | d2 = event PRIORITY | 4 522 movea.l P_SL(a6),a2 | a2 points at gdstb 523 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 524 move.w #0x9999,G_NOTE(a1) | gdsp->note = COLOR 525 move.w #4,G_CODE(a1) | gdsp->code = PATTERN 526 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 527 bra dsexit | done 528 529 .page 530 531 | dsdyn -- display dynamics 532 | ----- ---------------- 533 dsdyn: clr.w d0 | get group number 534 move.b E_DATA1(a0),d0 | ... in d0 535 add.w d0,d0 | ... as a word offset 536 lea _grpstat,a1 | check grpstat[grp] 537 tst.w 0(a1,d0.W) | ... 538 beq dsexit | done if not enabled 539 540 tst.w P_CF(a6) | center update ? 541 beq dsdyn00 | jump if not 542 543 clr.w d0 | get dynamics 544 move.b E_DATA2(a0),d0 | ... in d0 545 move.w d0,-(a7) | save dyanmics 546 clr.w d1 | get group number 547 move.b E_DATA1(a0),d1 | ... in d1 548 move.w d1,-(a7) | save group number 549 move.w (a7),d0 | col = group number 550 add.w d0,d0 | ... | 5 551 add.w d0,d0 | ... 552 move.w (a7)+,d2 | ... (d2 = group number) 553 add.w d2,d0 | ... 554 add.w #6,d0 | ... + 6 555 move.w (a7)+,d1 | get dynamics 556 add.w #0x0030,d1 | add '0' for ASCII conversion 557 move.w d2,-(a7) | save group number 558 move.w #AT11,-(a7) | put attribute on stack 559 move.w d1,-(a7) | put digit on stack 560 move.w d0,-(a7) | put column on stack 561 move.w #4,-(a7) | put row on stack 562 move.l _obj8,-(a7) | put object address on stack 563 jsr _vputc | update the screen 564 add.l #12,a7 | clean up stack 565 move.w (a7)+,d0 | get group number 566 cmp.w #8,d0 | see which word it's in 567 bcc dsdyn1 | jump if in MS word 568 569 bset d0,_vrbw10+1 | set group bit in LS byte 570 bra dsdyn2 | ... 571 572 dsdyn1: sub.w #8,d0 | adjust for for byte 573 bset d0,_vrbw10 | set group bit in MS byte 574 575 dsdyn2: bset #2,_vrcw | set video reset type bit 576 tst.w _ctrsw | update center for scupd ? 577 beq dsexit | done if not 578 579 .page 580 dsdyn00: move.l _gdfsep,d0 | quit if no elements left 581 beq dsexit | ... 582 583 movea.l d0,a1 | a1 = gdsp 584 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 585 move.w #52,d2 | d2 = event PRIORITY | 4 586 movea.l P_SL(a6),a2 | a2 points at gdstb 587 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 588 move.w #0x9999,G_NOTE(a1) | gdsp->note = COLOR 589 move.w #5,G_CODE(a1) | gdsp->code = PATTERN 590 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 591 bra dsexit | done 592 593 .page 594 595 | dslocn -- display location 596 | ------ ---------------- 597 dslocn: clr.w d0 | get group number 598 move.b E_DATA1(a0),d0 | ... in d0 599 add.w d0,d0 | ... as a word offset 600 lea _grpstat,a1 | check grpstat[grp] 601 tst.w 0(a1,d0.W) | ... 602 beq dsexit | done if not enabled 603 604 tst.w P_CF(a6) | center update ? 605 beq dsloc00 | jump if not 606 607 clr.w d0 | get location 608 move.b E_DATA2(a0),d0 | ... in d0 609 move.w d0,-(a7) | save location 610 clr.w d1 | get group number 611 move.b E_DATA1(a0),d1 | ... in d1 612 move.w d1,-(a7) | save group number 613 move.w (a7),d0 | col = group number 614 add.w d0,d0 | ... | 5 615 add.w d0,d0 | ... 616 move.w (a7)+,d2 | ... (d2 = group number) 617 add.w d2,d0 | ... 618 add.w #8,d0 | ... + 8 619 move.w (a7)+,d1 | get location 620 add.w #0x0031,d1 | add '0' for ASCII conversion 621 move.w d2,-(a7) | save group number 622 move.w #AT11,-(a7) | put attribute on stack 623 move.w d1,-(a7) | put character on stack 624 move.w d0,-(a7) | put column on stack 625 move.w #4,-(a7) | put row on stack 626 move.l _obj8,-(a7) | put object address on stack 627 jsr _vputc | update the screen 628 add.l #12,a7 | clean up stack 629 move.w (a7)+,d0 | get group number 630 cmp.w #8,d0 | see which word it's in 631 bcc dslocn1 | jump if in MS word 632 633 bset d0,_vrbw11+1 | set group bit in LS byte 634 bra dslocn2 | ... 635 636 dslocn1: sub.w #8,d0 | adjust for for byte 637 bset d0,_vrbw11 | set group bit in MS byte 638 639 dslocn2: bset #3,_vrcw | set video reset type bit 640 tst.w _ctrsw | update center for scupd ? 641 beq dsexit | done if not 642 643 .page 644 dsloc00: move.l _gdfsep,d0 | quit if no elements left 645 beq dsexit | ... 646 647 movea.l d0,a1 | a1 = gdsp 648 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 649 move.w #52,d2 | d2 = event PRIORITY | 4 650 movea.l P_SL(a6),a2 | a2 points at gdstb 651 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 652 move.w #0x9999,G_NOTE(a1) | gdsp->note = COLOR 653 move.w #5,G_CODE(a1) | gdsp->code = PATTERN 654 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 655 bra dsexit | done 656 657 .page 658 659 | dsanrs -- display analog resolution 660 | ------ ------------------------- 661 dsanrs: move.b E_DATA1(a0),d1 | get var / group 662 move.w d1,d0 | extract group number 663 andi.w #0x000F,d0 | ... in d0 664 add.w d0,d0 | ... as a word offset 665 lea _grpstat,a1 | check grpstat[grp] 666 tst.w 0(a1,d0.W) | ... 667 beq dsexit | done if not enabled 668 669 tst.w P_CF(a6) | center update ? 670 beq dsanrs0 | jump if not 671 672 move.w _angroup,d2 | see if we display 673 bmi dsexit | jump if not 674 675 subq.w #1,d2 | adust selected group number 676 move.w d1,d0 | extract group from event 677 andi.w #0x000F,d0 | ... 678 cmp.w d0,d2 | see if we display 679 bne dsexit | jump if not 680 681 lsr.w #4,d1 | extract variable number 682 andi.w #0x000F,d1 | ... 683 move.w d1,-(a7) | save variable number 684 move.w d1,d0 | calculate display offset 685 lsl.w #3,d0 | ... (var | 9) + 6 686 add.w d0,d1 | ... in d1 687 addq.w #6,d1 | ... 688 move.b E_DATA2(a0),d0 | get resolution 689 addi.w #0x0030,d0 | convert for display 690 move.w #AT12,-(a7) | put attribute on stack 691 move.w d0,-(a7) | put character on stack 692 move.w d1,-(a7) | put column on stack 693 move.w #7,-(a7) | put row on stack 694 move.l _obj8,-(a7) | put sbase on stack 695 jsr _vputc | update the screen 696 add.l #12,a7 | clean up stack 697 move.w (a7)+,d0 | get variable number 698 bset d0,_vrbw13+1 | set variable bit 699 bset #5,_vrcw | set video reset type bit 700 tst.w _ctrsw | update center for scupd ? 701 beq dsexit | done if not 702 703 .page 704 dsanrs0: move.l _gdfsep,d0 | quit if no elements left 705 beq dsexit | ... 706 707 movea.l d0,a1 | a1 = gdsp 708 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 709 move.w #52,d2 | d2 = event PRIORITY | 4 710 movea.l P_SL(a6),a2 | a2 points at gdstb 711 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 712 move.w #0x9999,G_NOTE(a1) | gdsp->note = COLOR 713 move.w #6,G_CODE(a1) | gdsp->code = PATTERN 714 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 715 bra dsexit | done 716 717 .page 718 719 | dsanvl -- display analog value 720 | ------ -------------------- 721 dsanvl: move.w _angroup,d2 | see if we display 722 bmi dsexit | jump if not 723 724 move.b E_DATA1(a0),d1 | get var / group 725 move.w d1,d0 | extract group number 726 andi.w #0x000F,d0 | ... in d0 727 add.w d0,d0 | ... as a word offset 728 lea _grpstat,a1 | check grpstat[grp] 729 tst.w 0(a1,d0.W) | ... 730 beq dsexit | done if not enabled 731 732 tst.w P_CF(a6) | center update ? 733 beq dsanvl0 | jump if not 734 735 subq.w #1,d2 | adust group number 736 move.w d1,d0 | extract group 737 andi.w #0x000F,d0 | ... 738 cmp.w d0,d2 | see if we display 739 bne dsexit | jump if not 740 741 lsr.w #4,d1 | extract variable number 742 andi.w #0x000F,d1 | ... 743 move.w d1,-(a7) | save variable number 744 move.w d1,d0 | calculate display offset 745 lsl.w #3,d0 | ... (var | 9) + 8 746 add.w d0,d1 | ... in d1 747 addi.w #8,d1 | ... 748 move.w E_DN(a0),d0 | get value 749 asr.w #5,d0 | adjust to low 11 bits 750 bpl dsanvl1 | jump if positive 751 752 move.b #'-',numstr | set sign = '-' 753 neg.w d0 | make value positive 754 754 bra dsanvl2 755 * 756 dsanvl1: move.b #'+',numstr *set sign = '+'757 * 758 .page 759 dsanvl2: ext.l d0 *convert MS digit760 divu #1000,d0 *...761 add.w # $0030,d0 *...762 move.b d0,numstr+1 *...763 swap d0 *convert middle digit764 ext.l d0 *...765 divu #100,d0 *...766 add.w # $0030,d0 *...767 move.b d0,numstr+2 *...768 move.b #'.',numstr+3 *insert decimal point769 swap d0 *convert LS digit770 ext.l d0 *...771 divu #10,d0 *...772 add.w # $0030,d0 *...773 move.b d0,numstr+4 *...774 clr.b numstr+5 *terminate string775 move.w #AT12,-(a7) *put attribute on stack776 move.l #numstr,-(a7) *put buffer address on stack777 move.w d1,-(a7) *put column on stack778 move.w #7,-(a7) *put row on stack779 move.l _obj8,-(a7) *put sbase on stack780 jsr _vputs *update the screen781 add.l #14,a7 *clean up stack782 move.w (a7)+,d0 *get variable number783 bset d0,_vrbw14+1 *set variable bit784 bset #6,_vrcw *set video reset type bit785 tst.w _ctrsw *update center for scupd ?786 beq dsexit *done if not787 * 788 dsanvl0: move.l _gdfsep,d0 *quit if no elements left789 beq dsexit *...790 * 791 movea.l d0,a1 *a1 = gdsp792 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next793 move.w #52,d2 * d2 = event PRIORITY *4794 movea.l P_SL(a6),a2 *a2 points at gdstb795 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]796 move.w # $9999,G_NOTE(a1) *gdsp->note = COLOR797 move.w #6,G_CODE(a1) *gdsp->code = PATTERN798 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp799 bra dsexit *done800 * 801 .page 802 * 803 *dsasgn -- display assignment804 *------ ------------------805 dsasgn: tst.w P_CF(a6) *center update ?806 beq dsasgn0 *jump if not807 * 808 move.l a0,-(a7) *stash a0809 jsr _mpcupd *update changed stuff810 movea.l (a7)+,a0 *restore a0811 clr.w d1 *get assignment812 move.b E_DATA1(a0),d1 *... from the event813 ext.l d1 *... as a long in d1814 divu #10,d1 *divide by 10 for conversion815 add.l # $00300030,d1 *add '0' for ASCII conversion816 move.b d1,numstr *put MS byte in work area817 swap d1 *swap register halves818 move.b d1,numstr+1 *put LS byte in work area819 clr.b numstr+2 *terminate string820 move.w #AT04,-(a7) *put attribute on stack821 move.l #numstr,-(a7) *put buffer address on stack822 move.w #11,-(a7) *put column on stack823 move.w #1,-(a7) *put row on stack824 move.l _obj8,-(a7) *put sbase on stack825 jsr _vputs *update the screen826 add.l #14,a7 *clean up stack827 bset #0,_vrcw+1 *set video reset type bit828 tst.w _ctrsw *update center for scupd ?829 beq dsexit *done if not830 * 831 dsasgn0: move.l _gdfsep,d0 *quit if no elements left832 beq dsexit *...833 * 834 movea.l d0,a1 *a1 = gdsp835 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next836 move.w #56,d2 * d2 = event PRIORITY *4837 movea.l P_SL(a6),a2 *a2 points at gdstb838 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]839 move.w # $3333,G_NOTE(a1) *gdsp->note = COLOR840 move.w #3,G_CODE(a1) *gdsp->code = PATTERN841 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp842 bra dsexit *done843 * 844 .page 845 * 846 *dstmpo -- display tempo847 *------ -------------848 dstmpo: tst.w P_CF(a6) *center update ?849 beq dstmpo0 *jump if not850 * 851 clr.w d1 *get tempo852 move.b E_DATA1(a0),d1 *... from event853 ext.l d1 *... as a long in d1854 divu #10,d1 *divide by 10 for conversion855 swap d1 *swap register halves856 add.w # $0030,d1 *add '0' for ASCII conversion857 move.b d1,numstr+2 *put LS byte in work area858 swap d1 *swap register halves859 ext.l d1 *divide again860 divu #10,d1 *...861 add.l # $00300030,d1 *add '0' for ASCII conversion862 move.b d1,numstr *put MS byte in work area863 swap d1 *swap register halves864 move.b d1,numstr+1 *put middle byte in work area865 clr.b numstr+3 *terminate string866 move.w #AT06,-(a7) *put attribute on stack867 move.l #numstr,-(a7) *put buffer address on stack868 move.w #27,-(a7) *put column on stack869 move.w #1,-(a7) *put row on stack870 move.l _obj8,-(a7) *put sbase on stack871 jsr _vputs *display tempo872 add.l #14,a7 *clean up stack873 bset #2,_vrcw+1 *set video reset type bit874 tst.w _ctrsw *update center for scupd ?875 beq dsexit *done if not876 * 877 dstmpo0: move.l _gdfsep,d0 *quit if no elements left878 beq dsexit *...879 * 880 movea.l d0,a1 *a1 = gdsp881 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next882 move.w #56,d2 * d2 = event PRIORITY *4883 movea.l P_SL(a6),a2 *a2 points at gdstb884 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]885 move.w # $3333,G_NOTE(a1) *gdsp->note = COLOR886 move.w #4,G_CODE(a1) *gdsp->code = PATTERN887 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp888 bra dsexit *done889 * 890 .page 891 * 892 *dsstop -- display stop893 *------ ------------894 dsstop: tst.w P_CF(a6) *center update ?895 beq dsstop0 *jump if not896 * 897 jsr _dclkmd *show that clock is stopped898 move.w #AT08,-(a7) *put attribute on stack899 move.w #40,-(a7) *put 1st column on stack900 move.w #1,-(a7) *put row on stack901 move.l _obj8,-(a7) *put sbase on stack902 jsr _vputa *hilite first column903 move.w #41,COL(a7) *put 2nd column on stack904 jsr _vputa *hilite second column905 move.w #42,COL(a7) *put 3rd column on stack906 jsr _vputa *hilite third column907 move.w #43,COL(a7) *put 4th column on stack908 jsr _vputa *hilite fourth column909 add.l #10,a7 *clean up stack910 bset #7,_vrcw *set video reset type bits911 bset #0,_vrbw15 *...912 tst.w _ctrsw *update center for scupd ?913 beq dsexit *done if not914 * 915 dsstop0: move.l _gdfsep,d0 *quit if no elements left916 beq dsexit *...917 * 918 movea.l d0,a1 *a1 = gdsp919 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next920 move.w #56,d2 * d2 = event PRIORITY *4921 movea.l P_SL(a6),a2 *a2 points at gdstb922 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]923 move.w # $3333,G_NOTE(a1) *gdsp->note = COLOR924 move.w #5,G_CODE(a1) *gdsp->code = PATTERN925 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp926 bra dsexit *done927 * 928 .page 929 * 930 *dsnext -- display next931 *------ ------------932 dsnext: tst.w P_CF(a6) *center update ?933 beq dsnext0 *jump if not934 * 935 move.w #AT08,-(a7) *put attribute on stack936 move.w #45,-(a7) *put 1st column on stack937 move.w #1,-(a7) *put row on stack938 move.l _obj8,-(a7) *put sbase on stack939 jsr _vputa *hilite first column940 move.w #46,COL(a7) *put 2nd column on stack941 jsr _vputa *hilite second column942 move.w #47,COL(a7) *put 3rd column on stack943 jsr _vputa *hilite third column944 move.w #48,COL(a7) *put 4th column on stack945 jsr _vputa *hilite fourth column946 add.l #10,a7 *clean up stack947 bset #7,_vrcw *set video reset type bits948 bset #1,_vrbw15 *...949 tst.w _ctrsw *update center for scupd ?950 beq dsexit *done if not951 * 952 dsnext0: move.l _gdfsep,d0 *quit if no elements left953 beq dsexit *...954 * 955 movea.l d0,a1 *a1 = gdsp956 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next957 move.w #56,d2 * d2 = event PRIORITY *4958 movea.l P_SL(a6),a2 *a2 points at gdstb959 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]960 move.w # $3333,G_NOTE(a1) *gdsp->note = COLOR961 move.w #5,G_CODE(a1) *gdsp->code = PATTERN962 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp963 bra dsexit *done964 * 965 .page 966 * 967 *dsgrp -- display group status968 *----- --------------------969 dsgrp: tst.w P_CF(a6) *center update ?970 beq dsgrp0 *jump if not971 * 972 tst.w _ctrsw *update center for scupd ?973 beq dsexit *done if not974 * 975 dsgrp0: move.l _gdfsep,d0 *quit if no elements left976 beq dsexit *...977 * 978 movea.l d0,a1 *a1 = gdsp979 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next980 move.w #60,d2 * d2 = event PRIORITY *4981 movea.l P_SL(a6),a2 *a2 points at gdstb982 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]983 move.w # $9999,G_NOTE(a1) *gdsp->note = COLOR984 move.w #3,G_CODE(a1) *gdsp->code = PATTERN985 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp986 bra dsexit *done987 * 988 .page 989 * 990 *dsinst -- display instrument991 *------ ------------------992 dsinst: clr.w d0 *get group number993 move.b E_DATA1(a0),d0 *... in d0994 add.w d0,d0 *... as a word offset995 lea _grpstat,a1 *check grpstat[grp]996 tst.w 0(a1,d0.W) *...997 beq dsexit *done if not enabled998 * 999 tst.w P_CF(a6) *center update ?1000 beq dsins00 *jump if not1001 * 1002 lea _ins2grp,a1 *point at ins2grp[]1003 clr.w d0 *get instrument number1004 move.b E_DATA2(a0),d0 *... in d01005 move.w d0,-(a7) *save instrument number1006 clr.w d1 *get group number1007 move.b E_DATA1(a0),d1 *... in d11008 move.w d1,-(a7) *save group number1009 move.w (a7),d0 *col = group number1010 add.w d0,d0 * ... *51011 add.w d0,d0 *...1012 move.w (a7)+,d2 *... (d2 = group number)1013 add.w d2,d0 *...1014 add.w #7,d0 *... + 71015 clr.l d1 *get instrument number1016 move.w (a7)+,d1 *... as a long in d11017 divu #10,d1 *divide by 10 for conversion1018 add.l # $00300030,d1 *add '0' for ASCII conversion1019 move.b d1,numstr *put MS byte in work area1020 swap d1 *swap register halves1021 move.b d1,numstr+1 *put LS byte in work area1022 clr.b numstr+2 *terminate string1023 move.w d2,-(a7) *save group number1024 move.w #AT11,-(a7) *put attribute on stack1025 move.l #numstr,-(a7) *put buffer address on stack1026 move.w d0,-(a7) *put column on stack1027 move.w #2,-(a7) *put row on stack1028 move.l _obj8,-(a7) *put object address on stack1029 jsr _vputs *update the screen1030 add.l #14,a7 *clean up stack1031 * 1032 .page 1033 move.w (a7)+,d0 *get group number1034 cmp.w #8,d0 *see which word it's in1035 bcc dsinst1 *jump if in MS word1036 * 1037 bset d0,_vrbw08+1 *set group bit in LS byte1038 bra dsinst2 *...1039 * 1040 dsinst1: sub.w #8,d0 *adjust for for byte1041 bset d0,_vrbw08 *set group bit in MS byte1042 * 1043 dsinst2: bset #0,_vrcw *set video reset type bit1044 tst.w _ctrsw *update center for scupd ?1045 beq dsexit *done if not1046 * 1047 dsins00: move.l _gdfsep,d0 *quit if no elements left1048 beq dsexit *...1049 * 1050 movea.l d0,a1 *a1 = gdsp1051 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next1052 move.w #60,d2 * d2 = event PRIORITY *41053 movea.l P_SL(a6),a2 *a2 points at gdstb1054 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]1055 move.w # $9999,G_NOTE(a1) *gdsp->note = COLOR1056 move.w #3,G_CODE(a1) *gdsp->code = PATTERN1057 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp1058 bra dsexit *done1059 * 1060 .page 1061 * 1062 *dsintp -- display interpolation1063 *------ ---------------------1064 dsintp: tst.w P_CF(a6) *center update ?1065 beq dsintp0 *jump if not1066 * 1067 move.w E_DATA1(a0),-(a7) *get interpolate value1068 jsr _fromfpu *convert to milliseconds1069 tst.w (a7)+ *...1070 andi.l # $0000FFFF,d0 *clear high bits1071 divu #10000,d0 *convert 1st digit1072 addi.w # $0030,d0 *... to ASCII1073 move.b d0,numstr *... in numstr1074 swap d0 *convert 2nd digit1075 ext.l d0 *...1076 divu #1000,d0 *...1077 addi.w # $0030,d0 *... to ASCII1078 move.b d0,numstr+1 *... in numstr1079 move.b #'.',numstr+2 *insert decimal point1080 swap d0 *convert 3rd digit1081 ext.l d0 *...1082 divu #100,d0 *...1083 addi.w # $0030,d0 *... to ASCII1084 move.b d0,numstr+3 *... in numstr1085 clr.b numstr+4 *terminate numstr1086 move.w #AT07,-(a7) *vputs(obj8, 1, 35, numstr, AT07)1087 move.l #numstr,-(a7) *...1088 move.w #35,-(a7) *...1089 move.w #1,-(a7) *...1090 move.l _obj8,-(a7) *...1091 jsr _vputs *...1092 add.l #14,a7 *...1093 bset #3,_vrcw+1 *set video reset bit1094 tst.w _ctrsw *update center for scupd ?1095 beq dsexit *done if not1096 * 1097 dsintp0: move.l _gdfsep,d0 *quit if no elements left1098 beq dsexit *...1099 * 1100 movea.l d0,a1 *a1 = gdsp1101 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next1102 move.w #60,d2 * d2 = event PRIORITY *41103 movea.l P_SL(a6),a2 *a2 points at gdstb1104 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]1105 move.w # $CCCC,G_NOTE(a1) *gdsp->note = COLOR1106 move.w #4,G_CODE(a1) *gdsp->code = PATTERN1107 move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp1108 bra dsexit *done1109 * 1110 .page 1111 * 1112 *dspnch -- display punch in/out1113 *------ --------------------1114 dspnch: tst.w P_CF(a6) *center update ?1115 beq dspnch0 *jump if not1116 * 1117 tst.w E_DATA1(a0) *punch in ?1118 beq dspnch1 *jump if not1119 * 1120 move.w #AT09,-(a7) *put attribute on stack1121 move.w #50,-(a7) *put 1st col on stack1122 move.w #1,-(a7) *put row on stack1123 move.l _obj8,-(a7) *put object address on stack1124 jsr _vputa *highlight 1st column1125 move.w #51,COL(a7) *put 2nd col on stack1126 jsr _vputa *highlight 2nd col1127 add.l #10,a7 *clean up stack1128 bset #5,_vrcw+1 *set video reset bit1129 bra dspnch2 *go do maker update1130 * 1131 dspnch1: move.w #AT09,-(a7) *put attribute on stack1132 move.w #53,-(a7) *put 1st col on stack1133 move.w #1,-(a7) *put row on stack1134 move.l _obj8,-(a7) *put object address on stack1135 jsr _vputa *highlight 1st column1136 move.w #54,COL(a7) *put 2nd col on stack1137 jsr _vputa *highlight 2nd column1138 move.w #55,COL(a7) *put 3rd col on stack1139 jsr _vputa *highlight 3rd column1140 add.l #10,a7 *clean up stack1141 bset #6,_vrcw+1 *set video reset bit1142 * 1143 dspnch2: jsr _dsgmodz *display updated modes1144 tst.w _ctrsw *update center for scupd ?1145 beq dsexit *done if not1146 * 1147 dspnch0: move.l _gdfsep,d0 *quit if no elements left1148 beq dsexit *...1149 * 1150 movea.l d0,a1 *a1 = gdsp1151 move.l G_NEXT(a1),_gdfsep *gdfsep = gdsp->next1152 move.w #60,d2 * d2 = event PRIORITY *41153 movea.l P_SL(a6),a2 *a2 points at gdstb1154 move.l 0(a2,d2.W),G_NEXT(a1) *gdsp->next = gdstb[pri]1155 move.w # $CCCC,G_NOTE(a1) *gdsp->note = COLOR1156 tst.w E_DATA1(a0) *see which kind we have1157 bne dspnchi *jump if 'punch in'1158 * 1159 move.w #6,G_CODE(a1) *gdsp->code = 'out' PATTERN755 756 dsanvl1: move.b #'+',numstr | set sign = '+' 757 758 .page 759 dsanvl2: ext.l d0 | convert MS digit 760 divu #1000,d0 | ... 761 add.w #0x0030,d0 | ... 762 move.b d0,numstr+1 | ... 763 swap d0 | convert middle digit 764 ext.l d0 | ... 765 divu #100,d0 | ... 766 add.w #0x0030,d0 | ... 767 move.b d0,numstr+2 | ... 768 move.b #'.',numstr+3 | insert decimal point 769 swap d0 | convert LS digit 770 ext.l d0 | ... 771 divu #10,d0 | ... 772 add.w #0x0030,d0 | ... 773 move.b d0,numstr+4 | ... 774 clr.b numstr+5 | terminate string 775 move.w #AT12,-(a7) | put attribute on stack 776 move.l #numstr,-(a7) | put buffer address on stack 777 move.w d1,-(a7) | put column on stack 778 move.w #7,-(a7) | put row on stack 779 move.l _obj8,-(a7) | put sbase on stack 780 jsr _vputs | update the screen 781 add.l #14,a7 | clean up stack 782 move.w (a7)+,d0 | get variable number 783 bset d0,_vrbw14+1 | set variable bit 784 bset #6,_vrcw | set video reset type bit 785 tst.w _ctrsw | update center for scupd ? 786 beq dsexit | done if not 787 788 dsanvl0: move.l _gdfsep,d0 | quit if no elements left 789 beq dsexit | ... 790 791 movea.l d0,a1 | a1 = gdsp 792 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 793 move.w #52,d2 | d2 = event PRIORITY | 4 794 movea.l P_SL(a6),a2 | a2 points at gdstb 795 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 796 move.w #0x9999,G_NOTE(a1) | gdsp->note = COLOR 797 move.w #6,G_CODE(a1) | gdsp->code = PATTERN 798 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 799 bra dsexit | done 800 801 .page 802 803 | dsasgn -- display assignment 804 | ------ ------------------ 805 dsasgn: tst.w P_CF(a6) | center update ? 806 beq dsasgn0 | jump if not 807 808 move.l a0,-(a7) | stash a0 809 jsr _mpcupd | update changed stuff 810 movea.l (a7)+,a0 | restore a0 811 clr.w d1 | get assignment 812 move.b E_DATA1(a0),d1 | ... from the event 813 ext.l d1 | ... as a long in d1 814 divu #10,d1 | divide by 10 for conversion 815 add.l #0x00300030,d1 | add '0' for ASCII conversion 816 move.b d1,numstr | put MS byte in work area 817 swap d1 | swap register halves 818 move.b d1,numstr+1 | put LS byte in work area 819 clr.b numstr+2 | terminate string 820 move.w #AT04,-(a7) | put attribute on stack 821 move.l #numstr,-(a7) | put buffer address on stack 822 move.w #11,-(a7) | put column on stack 823 move.w #1,-(a7) | put row on stack 824 move.l _obj8,-(a7) | put sbase on stack 825 jsr _vputs | update the screen 826 add.l #14,a7 | clean up stack 827 bset #0,_vrcw+1 | set video reset type bit 828 tst.w _ctrsw | update center for scupd ? 829 beq dsexit | done if not 830 831 dsasgn0: move.l _gdfsep,d0 | quit if no elements left 832 beq dsexit | ... 833 834 movea.l d0,a1 | a1 = gdsp 835 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 836 move.w #56,d2 | d2 = event PRIORITY | 4 837 movea.l P_SL(a6),a2 | a2 points at gdstb 838 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 839 move.w #0x3333,G_NOTE(a1) | gdsp->note = COLOR 840 move.w #3,G_CODE(a1) | gdsp->code = PATTERN 841 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 842 bra dsexit | done 843 844 .page 845 846 | dstmpo -- display tempo 847 | ------ ------------- 848 dstmpo: tst.w P_CF(a6) | center update ? 849 beq dstmpo0 | jump if not 850 851 clr.w d1 | get tempo 852 move.b E_DATA1(a0),d1 | ... from event 853 ext.l d1 | ... as a long in d1 854 divu #10,d1 | divide by 10 for conversion 855 swap d1 | swap register halves 856 add.w #0x0030,d1 | add '0' for ASCII conversion 857 move.b d1,numstr+2 | put LS byte in work area 858 swap d1 | swap register halves 859 ext.l d1 | divide again 860 divu #10,d1 | ... 861 add.l #0x00300030,d1 | add '0' for ASCII conversion 862 move.b d1,numstr | put MS byte in work area 863 swap d1 | swap register halves 864 move.b d1,numstr+1 | put middle byte in work area 865 clr.b numstr+3 | terminate string 866 move.w #AT06,-(a7) | put attribute on stack 867 move.l #numstr,-(a7) | put buffer address on stack 868 move.w #27,-(a7) | put column on stack 869 move.w #1,-(a7) | put row on stack 870 move.l _obj8,-(a7) | put sbase on stack 871 jsr _vputs | display tempo 872 add.l #14,a7 | clean up stack 873 bset #2,_vrcw+1 | set video reset type bit 874 tst.w _ctrsw | update center for scupd ? 875 beq dsexit | done if not 876 877 dstmpo0: move.l _gdfsep,d0 | quit if no elements left 878 beq dsexit | ... 879 880 movea.l d0,a1 | a1 = gdsp 881 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 882 move.w #56,d2 | d2 = event PRIORITY | 4 883 movea.l P_SL(a6),a2 | a2 points at gdstb 884 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 885 move.w #0x3333,G_NOTE(a1) | gdsp->note = COLOR 886 move.w #4,G_CODE(a1) | gdsp->code = PATTERN 887 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 888 bra dsexit | done 889 890 .page 891 892 | dsstop -- display stop 893 | ------ ------------ 894 dsstop: tst.w P_CF(a6) | center update ? 895 beq dsstop0 | jump if not 896 897 jsr _dclkmd | show that clock is stopped 898 move.w #AT08,-(a7) | put attribute on stack 899 move.w #40,-(a7) | put 1st column on stack 900 move.w #1,-(a7) | put row on stack 901 move.l _obj8,-(a7) | put sbase on stack 902 jsr _vputa | hilite first column 903 move.w #41,COL(a7) | put 2nd column on stack 904 jsr _vputa | hilite second column 905 move.w #42,COL(a7) | put 3rd column on stack 906 jsr _vputa | hilite third column 907 move.w #43,COL(a7) | put 4th column on stack 908 jsr _vputa | hilite fourth column 909 add.l #10,a7 | clean up stack 910 bset #7,_vrcw | set video reset type bits 911 bset #0,_vrbw15 | ... 912 tst.w _ctrsw | update center for scupd ? 913 beq dsexit | done if not 914 915 dsstop0: move.l _gdfsep,d0 | quit if no elements left 916 beq dsexit | ... 917 918 movea.l d0,a1 | a1 = gdsp 919 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 920 move.w #56,d2 | d2 = event PRIORITY | 4 921 movea.l P_SL(a6),a2 | a2 points at gdstb 922 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 923 move.w #0x3333,G_NOTE(a1) | gdsp->note = COLOR 924 move.w #5,G_CODE(a1) | gdsp->code = PATTERN 925 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 926 bra dsexit | done 927 928 .page 929 930 | dsnext -- display next 931 | ------ ------------ 932 dsnext: tst.w P_CF(a6) | center update ? 933 beq dsnext0 | jump if not 934 935 move.w #AT08,-(a7) | put attribute on stack 936 move.w #45,-(a7) | put 1st column on stack 937 move.w #1,-(a7) | put row on stack 938 move.l _obj8,-(a7) | put sbase on stack 939 jsr _vputa | hilite first column 940 move.w #46,COL(a7) | put 2nd column on stack 941 jsr _vputa | hilite second column 942 move.w #47,COL(a7) | put 3rd column on stack 943 jsr _vputa | hilite third column 944 move.w #48,COL(a7) | put 4th column on stack 945 jsr _vputa | hilite fourth column 946 add.l #10,a7 | clean up stack 947 bset #7,_vrcw | set video reset type bits 948 bset #1,_vrbw15 | ... 949 tst.w _ctrsw | update center for scupd ? 950 beq dsexit | done if not 951 952 dsnext0: move.l _gdfsep,d0 | quit if no elements left 953 beq dsexit | ... 954 955 movea.l d0,a1 | a1 = gdsp 956 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 957 move.w #56,d2 | d2 = event PRIORITY | 4 958 movea.l P_SL(a6),a2 | a2 points at gdstb 959 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 960 move.w #0x3333,G_NOTE(a1) | gdsp->note = COLOR 961 move.w #5,G_CODE(a1) | gdsp->code = PATTERN 962 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 963 bra dsexit | done 964 965 .page 966 967 | dsgrp -- display group status 968 | ----- -------------------- 969 dsgrp: tst.w P_CF(a6) | center update ? 970 beq dsgrp0 | jump if not 971 972 tst.w _ctrsw | update center for scupd ? 973 beq dsexit | done if not 974 975 dsgrp0: move.l _gdfsep,d0 | quit if no elements left 976 beq dsexit | ... 977 978 movea.l d0,a1 | a1 = gdsp 979 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 980 move.w #60,d2 | d2 = event PRIORITY | 4 981 movea.l P_SL(a6),a2 | a2 points at gdstb 982 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 983 move.w #0x9999,G_NOTE(a1) | gdsp->note = COLOR 984 move.w #3,G_CODE(a1) | gdsp->code = PATTERN 985 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 986 bra dsexit | done 987 988 .page 989 990 | dsinst -- display instrument 991 | ------ ------------------ 992 dsinst: clr.w d0 | get group number 993 move.b E_DATA1(a0),d0 | ... in d0 994 add.w d0,d0 | ... as a word offset 995 lea _grpstat,a1 | check grpstat[grp] 996 tst.w 0(a1,d0.W) | ... 997 beq dsexit | done if not enabled 998 999 tst.w P_CF(a6) | center update ? 1000 beq dsins00 | jump if not 1001 1002 lea _ins2grp,a1 | point at ins2grp[] 1003 clr.w d0 | get instrument number 1004 move.b E_DATA2(a0),d0 | ... in d0 1005 move.w d0,-(a7) | save instrument number 1006 clr.w d1 | get group number 1007 move.b E_DATA1(a0),d1 | ... in d1 1008 move.w d1,-(a7) | save group number 1009 move.w (a7),d0 | col = group number 1010 add.w d0,d0 | ... | 5 1011 add.w d0,d0 | ... 1012 move.w (a7)+,d2 | ... (d2 = group number) 1013 add.w d2,d0 | ... 1014 add.w #7,d0 | ... + 7 1015 clr.l d1 | get instrument number 1016 move.w (a7)+,d1 | ... as a long in d1 1017 divu #10,d1 | divide by 10 for conversion 1018 add.l #0x00300030,d1 | add '0' for ASCII conversion 1019 move.b d1,numstr | put MS byte in work area 1020 swap d1 | swap register halves 1021 move.b d1,numstr+1 | put LS byte in work area 1022 clr.b numstr+2 | terminate string 1023 move.w d2,-(a7) | save group number 1024 move.w #AT11,-(a7) | put attribute on stack 1025 move.l #numstr,-(a7) | put buffer address on stack 1026 move.w d0,-(a7) | put column on stack 1027 move.w #2,-(a7) | put row on stack 1028 move.l _obj8,-(a7) | put object address on stack 1029 jsr _vputs | update the screen 1030 add.l #14,a7 | clean up stack 1031 1032 .page 1033 move.w (a7)+,d0 | get group number 1034 cmp.w #8,d0 | see which word it's in 1035 bcc dsinst1 | jump if in MS word 1036 1037 bset d0,_vrbw08+1 | set group bit in LS byte 1038 bra dsinst2 | ... 1039 1040 dsinst1: sub.w #8,d0 | adjust for for byte 1041 bset d0,_vrbw08 | set group bit in MS byte 1042 1043 dsinst2: bset #0,_vrcw | set video reset type bit 1044 tst.w _ctrsw | update center for scupd ? 1045 beq dsexit | done if not 1046 1047 dsins00: move.l _gdfsep,d0 | quit if no elements left 1048 beq dsexit | ... 1049 1050 movea.l d0,a1 | a1 = gdsp 1051 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 1052 move.w #60,d2 | d2 = event PRIORITY | 4 1053 movea.l P_SL(a6),a2 | a2 points at gdstb 1054 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 1055 move.w #0x9999,G_NOTE(a1) | gdsp->note = COLOR 1056 move.w #3,G_CODE(a1) | gdsp->code = PATTERN 1057 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 1058 bra dsexit | done 1059 1060 .page 1061 1062 | dsintp -- display interpolation 1063 | ------ --------------------- 1064 dsintp: tst.w P_CF(a6) | center update ? 1065 beq dsintp0 | jump if not 1066 1067 move.w E_DATA1(a0),-(a7) | get interpolate value 1068 jsr _fromfpu | convert to milliseconds 1069 tst.w (a7)+ | ... 1070 andi.l #0x0000FFFF,d0 | clear high bits 1071 divu #10000,d0 | convert 1st digit 1072 addi.w #0x0030,d0 | ... to ASCII 1073 move.b d0,numstr | ... in numstr 1074 swap d0 | convert 2nd digit 1075 ext.l d0 | ... 1076 divu #1000,d0 | ... 1077 addi.w #0x0030,d0 | ... to ASCII 1078 move.b d0,numstr+1 | ... in numstr 1079 move.b #'.',numstr+2 | insert decimal point 1080 swap d0 | convert 3rd digit 1081 ext.l d0 | ... 1082 divu #100,d0 | ... 1083 addi.w #0x0030,d0 | ... to ASCII 1084 move.b d0,numstr+3 | ... in numstr 1085 clr.b numstr+4 | terminate numstr 1086 move.w #AT07,-(a7) | vputs(obj8, 1, 35, numstr, AT07) 1087 move.l #numstr,-(a7) | ... 1088 move.w #35,-(a7) | ... 1089 move.w #1,-(a7) | ... 1090 move.l _obj8,-(a7) | ... 1091 jsr _vputs | ... 1092 add.l #14,a7 | ... 1093 bset #3,_vrcw+1 | set video reset bit 1094 tst.w _ctrsw | update center for scupd ? 1095 beq dsexit | done if not 1096 1097 dsintp0: move.l _gdfsep,d0 | quit if no elements left 1098 beq dsexit | ... 1099 1100 movea.l d0,a1 | a1 = gdsp 1101 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 1102 move.w #60,d2 | d2 = event PRIORITY | 4 1103 movea.l P_SL(a6),a2 | a2 points at gdstb 1104 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 1105 move.w #0xCCCC,G_NOTE(a1) | gdsp->note = COLOR 1106 move.w #4,G_CODE(a1) | gdsp->code = PATTERN 1107 move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 1108 bra dsexit | done 1109 1110 .page 1111 1112 | dspnch -- display punch in/out 1113 | ------ -------------------- 1114 dspnch: tst.w P_CF(a6) | center update ? 1115 beq dspnch0 | jump if not 1116 1117 tst.w E_DATA1(a0) | punch in ? 1118 beq dspnch1 | jump if not 1119 1120 move.w #AT09,-(a7) | put attribute on stack 1121 move.w #50,-(a7) | put 1st col on stack 1122 move.w #1,-(a7) | put row on stack 1123 move.l _obj8,-(a7) | put object address on stack 1124 jsr _vputa | highlight 1st column 1125 move.w #51,COL(a7) | put 2nd col on stack 1126 jsr _vputa | highlight 2nd col 1127 add.l #10,a7 | clean up stack 1128 bset #5,_vrcw+1 | set video reset bit 1129 bra dspnch2 | go do maker update 1130 1131 dspnch1: move.w #AT09,-(a7) | put attribute on stack 1132 move.w #53,-(a7) | put 1st col on stack 1133 move.w #1,-(a7) | put row on stack 1134 move.l _obj8,-(a7) | put object address on stack 1135 jsr _vputa | highlight 1st column 1136 move.w #54,COL(a7) | put 2nd col on stack 1137 jsr _vputa | highlight 2nd column 1138 move.w #55,COL(a7) | put 3rd col on stack 1139 jsr _vputa | highlight 3rd column 1140 add.l #10,a7 | clean up stack 1141 bset #6,_vrcw+1 | set video reset bit 1142 1143 dspnch2: jsr _dsgmodz | display updated modes 1144 tst.w _ctrsw | update center for scupd ? 1145 beq dsexit | done if not 1146 1147 dspnch0: move.l _gdfsep,d0 | quit if no elements left 1148 beq dsexit | ... 1149 1150 movea.l d0,a1 | a1 = gdsp 1151 move.l G_NEXT(a1),_gdfsep | gdfsep = gdsp->next 1152 move.w #60,d2 | d2 = event PRIORITY | 4 1153 movea.l P_SL(a6),a2 | a2 points at gdstb 1154 move.l 0(a2,d2.W),G_NEXT(a1) | gdsp->next = gdstb[pri] 1155 move.w #0xCCCC,G_NOTE(a1) | gdsp->note = COLOR 1156 tst.w E_DATA1(a0) | see which kind we have 1157 bne dspnchi | jump if 'punch in' 1158 1159 move.w #6,G_CODE(a1) | gdsp->code = 'out' PATTERN 1160 1160 bra dspnchx 1161 * 1162 dspnchi: move.w #5,G_CODE(a1) *gdsp->code = 'in' PATTERN1163 * 1164 dspnchx: move.l a1,0(a2,d2.W) *gdstb[pri] = gdsp1165 bra dsexit *done1166 * 1167 .page 1168 * 1169 *dsbar -- display a bar marker1170 *----- --------------------1171 dsbar: tst.w P_CF(a6) *center update ?1172 beq dsbar0 *jump if not1173 * 1174 tst.w _ctrsw *update center for scupd ?1175 beq dsexit *done if not1176 * 1177 dsbar0: movea.l P_SL(a6),a2 *a2 points at gdstb1178 move.l #-1,BARFLAG(a2) *set the bar marker flag1179 bra dsexit *done1180 * 1181 .page 1182 * 1183 *==============================================================================1161 1162 dspnchi: move.w #5,G_CODE(a1) | gdsp->code = 'in' PATTERN 1163 1164 dspnchx: move.l a1,0(a2,d2.W) | gdstb[pri] = gdsp 1165 bra dsexit | done 1166 1167 .page 1168 1169 | dsbar -- display a bar marker 1170 | ----- -------------------- 1171 dsbar: tst.w P_CF(a6) | center update ? 1172 beq dsbar0 | jump if not 1173 1174 tst.w _ctrsw | update center for scupd ? 1175 beq dsexit | done if not 1176 1177 dsbar0: movea.l P_SL(a6),a2 | a2 points at gdstb 1178 move.l #-1,BARFLAG(a2) | set the bar marker flag 1179 bra dsexit | done 1180 1181 .page 1182 1183 | ============================================================================== 1184 1184 .data 1185 *==============================================================================1186 * 1187 *sddtab -- score display dispatch table -- MUST match score.h definitions1188 *------ ---------------------------- ------------------------------1189 sddtab: dc.l dsexit *0 null1190 dc.l dsexit *1 score begin1191 dc.l dssbgn *2 section begin1192 dc.l dssend *3 section end1193 dc.l dsinst *4 instrument change1194 dc.l dsnbx *5 note begin1195 dc.l dsnex *6 note end1196 dc.l dsstop *7 stop1197 dc.l dsintp *8 interpolate1198 dc.l dstmpo *9 tempo1199 dc.l dstune *10 tuning1200 dc.l dsgrp *11 group status1201 dc.l dslocn *12 location1202 dc.l dsdyn *13 dynamics1203 dc.l dsanvl *14 analog value1204 dc.l dsanrs *15 analog resolution1205 dc.l dsasgn *16 I/O assign1206 dc.l dstrns *17 transposition1207 dc.l dsexit *18 repeat1208 dc.l dspnch *19 punch in/out1209 dc.l dsexit *20 polyphonic pressure1210 dc.l dsexit *21 score end1211 dc.l dsexit *22 channel pressure1212 dc.l dsbar *23 bar marker1213 dc.l dsnext *24 next score1214 * 1215 *==============================================================================1185 | ============================================================================== 1186 1187 | sddtab -- score display dispatch table -- MUST match score.h definitions 1188 | ------ ---------------------------- ------------------------------ 1189 sddtab: dc.l dsexit | 0 null 1190 dc.l dsexit | 1 score begin 1191 dc.l dssbgn | 2 section begin 1192 dc.l dssend | 3 section end 1193 dc.l dsinst | 4 instrument change 1194 dc.l dsnbx | 5 note begin 1195 dc.l dsnex | 6 note end 1196 dc.l dsstop | 7 stop 1197 dc.l dsintp | 8 interpolate 1198 dc.l dstmpo | 9 tempo 1199 dc.l dstune | 10 tuning 1200 dc.l dsgrp | 11 group status 1201 dc.l dslocn | 12 location 1202 dc.l dsdyn | 13 dynamics 1203 dc.l dsanvl | 14 analog value 1204 dc.l dsanrs | 15 analog resolution 1205 dc.l dsasgn | 16 I/O assign 1206 dc.l dstrns | 17 transposition 1207 dc.l dsexit | 18 repeat 1208 dc.l dspnch | 19 punch in/out 1209 dc.l dsexit | 20 polyphonic pressure 1210 dc.l dsexit | 21 score end 1211 dc.l dsexit | 22 channel pressure 1212 dc.l dsbar | 23 bar marker 1213 dc.l dsnext | 24 next score 1214 1215 | ============================================================================== 1216 1216 .bss 1217 *==============================================================================1218 * 1219 *globals:1220 *--------1221 _ac_code: ds.b 1 *accidental code1222 * 1223 *locals:1224 *-------1225 numstr: ds.b 65 *video display update work area1226 * 1227 *------------------------------------------------------------------------------1228 * 1217 | ============================================================================== 1218 1219 | globals: 1220 | -------- 1221 _ac_code: ds.b 1 | accidental code 1222 1223 | locals: 1224 | ------- 1225 numstr: ds.b 65 | video display update work area 1226 1227 | ------------------------------------------------------------------------------ 1228 1229 1229 .end -
ram/seexec.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *seexec.s -- score event execution driver3 *Version 40 -- 1988-10-06 -- D.N. Lynx Crowe4 * 5 * struct s_entry * 6 *se_exec(ep, sd)7 * struct s_entry *ep;8 *short sd;9 * 10 *Executes the event at 'ep', scrolling in direction 'sd'.11 * 12 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | seexec.s -- score event execution driver 3 | Version 40 -- 1988-10-06 -- D.N. Lynx Crowe 4 5 | struct s_entry | 6 | se_exec(ep, sd) 7 | struct s_entry |ep; 8 | short sd; 9 10 | Executes the event at 'ep', scrolling in direction 'sd'. 11 12 | ------------------------------------------------------------------------------ 13 13 .text 14 * 14 15 15 .xdef _se_exec 16 * 16 17 17 .xdef BadEvnt 18 * 18 19 19 .xdef _xevent 20 * 20 21 21 .xref _asgvce 22 22 .xref _clkset … … 31 31 .xref _settune 32 32 .xref _setv2gi 33 * 33 34 34 .xref _anrs 35 35 .xref _var2src … … 48 48 .xref _vce2trg 49 49 .xref _veltab 50 * 51 .page 52 * 53 *parameter offsets54 *-----------------55 P_EP .equ 8 *WORD - 'ep' parameter offset56 P_SD .equ 12 *WORD - 'sd' parameter offset57 * 58 *event structure offsets -- MUST match score.h definitions59 *----------------------- ------------------------------60 *offset length61 *------ ------62 E_TIME .equ 0 *LONG63 E_SIZE .equ 4 *BYTE64 E_TYPE .equ 5 *BYTE65 E_DATA1 .equ 6 *BYTE66 E_NOTE .equ 6 *BYTE67 E_DATA2 .equ 7 *BYTE68 E_GROUP .equ 7 *BYTE69 E_BAK .equ 8 *LONG70 E_FWD .equ 12 *LONG71 E_DN .equ 16 *LONG72 E_VEL .equ 16 *WORD73 E_DATA4 .equ 18 *WORD74 E_UP .equ 20 *LONG75 E_LFT .equ 24 *LONG76 E_RGT .equ 28 *LONG77 * 78 *Miscellaneous constants79 *-----------------------80 N_ETYPES .equ 25 *number of event types81 * 82 M_KSTATE .equ $01 *keys status bit83 N_KSTATE .equ $FE *keys status bit complement84 * 85 D_BAK .equ 1 *code for backward scrolling86 * 87 LCL_PRT .equ 2 *0-origin local port number88 LCL_PCH .equ $1080 *port and channel for trigger89 * 90 .page 91 * 92 *A few words about se_exec:93 * 94 *se_exec has to be very fast, so it's written in assembly language,95 *rather than C, which is usually pretty good, but not quite good enough96 *for this application. The faster this routine runs, the higher the97 *tempo we can keep up with. If this code is fast enough, we end up98 *hardware limited by the timer.99 * 100 _se_exec: link a6,#0 *link stack frames101 movea.l P_EP(a6),a0 *get event pointer 'ep' into a0102 move.l a0,_xevent *save in xevent103 move.b E_TYPE(a0),d1 *get event type into d1.W104 andi.w # $007F,d1 *... and mask off new-data flag105 cmp.b #N_ETYPES,d1 *see if it's valid106 blt sexc1 *jump if it is107 * 108 BadEvnt: move.l a0,d0 *setup to return pointer we got109 bra done *exit110 * 111 exexit: movea.l _xevent,a0 *point at next event112 move.l E_FWD(a0),d0 *...113 * 114 done: unlk a6 *done -- unlink stack frames115 rts *return to caller116 * 117 sexc1: lea sextab,a1 *get base of dispatch table118 lsl.w #2,d1 *multiplty event by 4 for index119 movea.l 0(a1,d1.W),a2 *get address of event routine120 jmp (a2) *jump to event execution routine121 * 122 *On entry, the individual execution routines only depend on a0 pointing at the123 *event they were dispatched for.124 * 125 *The usual C function register usage conventions apply:126 * 127 *d0..d2 and a0..a2 are used for scratch, and are not preserved.128 * 129 *d3..d6 and a3..a5 are register variables, and are preserved.130 *a6 = frame pointer, a7 = stack pointer, and are preserved.131 * 132 .page 133 * 134 *exnbeg -- execute note begin135 *------ ------------------136 *If things need to be sped up, we could incorporate the functions of137 *asgvce() here, rather than calling it. asgvce() could also be re-written in138 *assembly language to make it a shade faster.139 * 140 exnbeg: cmpi.w #D_BAK,P_SD(a6) *check direction141 beq nendex *if backward, treat as note end142 * 143 nbegex: clr.w d1 *clear d1144 move.b E_GROUP(a0),d1 *get group number145 add.w d1,d1 * ... *2146 lea _grpstat,a1 *point at grpstat147 tst.w 0(a1,d1.W) *see if group is enabled148 beq exexit *done if not149 * 150 move.b E_NOTE(a0),d1 *d1 = note number nn (0..127)151 move.w #LCL_PCH,d2 *put port and channel in d2152 add.w d1,d2 * d2 = trg153 lea _trgtab,a1 *point at trgtab[trg]154 move.b 0(a1,d2.W),d0 *...155 or.b #M_KSTATE,d0 *set trigger table entry on156 move.b d0,0(a1,d2.W) *...157 lea _veltab,a1 *point at veltab158 add.w d2,d2 *...159 move.w E_VEL(a0),0(a1,d2.W) *put velocity in veltab160 move.w E_VEL(a0),-(a7) *put velocity on the stack161 move.w d1,-(a7) *put note number on the stack162 move.w #1,-(a7) *put channel on the stack163 move.w #LCL_PRT,-(a7) *put port on the stack164 move.b E_GROUP(a0),d1 *d1 = group number (0..11)165 move.w d1,-(a7) *put group number on the stack166 jsr _asgvce *start the note167 add.l #10,a7 * clean up the stack168 bra exexit *done169 * 170 .page 171 * 172 *exnend -- execute note end173 *------ ----------------174 *If things need to be sped up, we could incorporate the functions of175 *procpfl() here, rather than calling it. procpfl() could also be re-written in176 *assembly language to make it a shade faster.177 * 178 exnend: cmpi.w #D_BAK,P_SD(a6) *check direction179 beq nbegex *if backward, treat as beginning180 * 181 nendex: clr.w d1 *clear d1182 move.b E_GROUP(a0),d1 *get group number183 add.w d1,d1 * ... *2184 lea _grpstat,a1 *point at grpstat185 tst.w 0(a1,d1.W) *check group status186 beq exexit *done if disabled187 * 188 move.b E_NOTE(a0),d1 *d1 = note number nn (0..127)189 move.w #LCL_PCH,d2 *put port and channel in d2190 add.w d1,d2 * d2 = trg *2191 add.w d2,d2 *...192 lea _trgtab,a1 *set trigger table entry off193 move.b 0(a1,d2.W),d0 *...194 and.b #N_KSTATE,d0 *...195 move.b d0,0(a1,d2.W) *...196 bne exexit *done if note still active197 * 198 .page 199 * 200 lsr.w #1,d2 *adjust d2201 clr.w d1 *set loop index202 lea _vce2trg,a2 *point at vce2trg table203 * 204 exnend1: cmp.w (a2),d2 *see if this voice uses trg205 bne exnend2 *jump if not206 * 207 move.w #-1,(a2) *set entry to -1208 move.l a2,-(a7) *save a2 on stack209 move.w d1,-(a7) *save d1 on stack210 move.w d2,-(a7) *save d2 on stack211 lea _vce2grp,a1 *put group on stack212 move.w d1,d0 *...213 add.w d0,d0 *...214 move.w 0(a1,d0.W),-(a7) *...215 move.w d2,-(a7) *put trg on stack216 jsr _procpfl *process sustained voices217 addq.l #4,a7 *clean up stack218 move.w (a7)+,d2 *restore d2219 move.w (a7)+,d1 *restore d1220 movea.l (a7)+,a2 *restore a2221 * 222 exnend2: addq.l #2,a2 *point at next vce2trg entry223 addq.w #1,d1 *loop until all are checked224 cmp.w #12,d1 *...225 bne exnend1 *...226 * 227 bra exexit *done228 * 229 .page 230 * 231 *exsbgn -- execute section begin232 *------ ---------------------233 exsbgn: clr.w d0 *get section number234 move.b E_DATA1(a0),d0 *...235 move.w d0,_cursect *set section number236 bra exexit *done237 * 238 *exasgn -- execute assignment event239 *------ ------------------------240 exasgn: clr.w d0 *get assignment241 move.b E_DATA1(a0),d0 *...242 move.w d0,-(a7) *getasg(curasg = asgn)243 move.w d0,_curasg *...244 jsr _getasg *...245 tst.w (a7)+ *...246 bra exexit *done247 * 248 *extune -- execute tuning event249 *------ --------------------250 extune: clr.w d0 *get tuning251 move.b E_DATA1(a0),d0 *...252 move.w d0,-(a7) *gettun(tuning)253 jsr _gettun *...254 tst.w (a7)+ *...255 bra exexit *done256 * 257 *extrns -- execute transposition event258 *------ ---------------------------259 extrns: clr.w d0 *get group number260 move.b E_DATA1(a0),d0 *...261 add.w d0,d0 *... as an index in d0262 lea _grpstat,a1 *check grpstat[grp]263 tst.w 0(a1,d0.W) *...264 beq exexit *done if disabled265 * 266 lea _s_trns,a1 *set group transposition267 move.w E_LFT(a0),0(a1,d0.W) *...268 jsr _settune *...269 bra exexit *done270 * 271 .page 272 * 273 *extmpo -- execute tempo event274 *------ -------------------275 extmpo: clr.w d0 *get tempo276 move.b E_DATA1(a0),d0 *...277 move.w d0,-(a7) *settmpo(tempo)278 jsr _settmpo *...279 tst.w (a7)+ *...280 bra exexit *done281 * 282 *exstop -- execute stop event283 *------ ------------------284 exstop: clr.w -(a7) *stop the clock285 jsr _clkset *...286 tst.w (a7)+ *...287 bra exexit *that's all, folks288 * 289 *exintp -- execute interpolate event290 *------ -------------------------291 exintp: move.w E_DATA1(a0),_curintp *set interpolate value292 bra exexit *done293 * 294 .page 295 * 296 *exinst -- execute instrument change event297 *------ -------------------------------298 exinst: clr.w d0 *get group number299 move.b E_DATA1(a0),d0 *... in d0300 add.w d0,d0 *... as a word offset301 lea _grpstat,a1 *check grpstat[grp]302 tst.w 0(a1,d0.W) *...303 beq exexit *done if not enabled304 * 305 lea _ins2grp,a1 *point at ins2grp[]306 clr.w d0 *get instrument number307 move.b E_DATA2(a0),d0 *... in d0308 clr.w d1 *get group number309 move.b E_DATA1(a0),d1 *... in d1310 move.w d1,-(a7) *put group number on stack311 add.w d1,d1 *make d1 a word pointer312 move.w 0(a1,d1.W),d2 *get ins2grp[group]313 and.w # $FF00,d2 *mask off GTAG1..GTAG8314 or.w d0,d2 *OR in new instrument number315 move.w d2,0(a1,d1.W) *set ins2grp[group]316 jsr _setv2gi *setv2gi(group)317 tst.w (a7)+ *clean up stack318 bra exexit *done319 * 320 .page 321 * 322 *exdyn -- execute dynamics event323 *----- ----------------------324 exdyn: clr.w d0 *get group number325 move.b E_DATA1(a0),d0 *... in d0326 add.w d0,d0 *... as a word offset327 lea _grpstat,a1 *check grpstat[grp]328 tst.w 0(a1,d0.W) *...329 beq exexit *done if not enabled330 * 331 clr.w d0 *get dynamics332 move.b E_DATA2(a0),d0 *... in d0333 clr.w d1 *get group number334 move.b E_DATA1(a0),d1 *... in d1335 move.w d0,-(a7) *setdyn(group, dyn)336 move.w d1,-(a7) *...337 jsr _setdyn *...338 adda.l #4,a7 *clean up stack339 bra exexit *done340 * 341 *exlocn -- execute location event342 *------ ----------------------343 exlocn: clr.w d0 *get group number344 move.b E_DATA1(a0),d0 *... in d0345 add.w d0,d0 *... as a word offset346 lea _grpstat,a1 *check grpstat[grp]347 tst.w 0(a1,d0.W) *...348 beq exexit *done if not enabled349 * 350 clr.w d0 *get location351 move.b E_DATA2(a0),d0 *... in d0352 clr.w d1 *get group number353 move.b E_DATA1(a0),d1 *... in d1354 move.w d0,-(a7) *setloc(group, loc)355 move.w d1,-(a7) *...356 jsr _setloc *...357 adda.l #4,a7 *clean up stack358 bra exexit *done359 * 360 .page 361 * 362 *exanrs -- execute analog resolution event363 *------ -------------------------------364 exanrs: move.b E_DATA1(a0),d0 *get group number365 andi.w # $000F,d0 *... in d0366 add.w d0,d0 *... as a word offset367 lea _grpstat,a1 *check grpstat[grp]368 tst.w 0(a1,d0.W) *...369 beq exexit *done if not enabled370 * 371 clr.w d1 *get variable / group numbers372 move.b E_DATA1(a0),d1 *...373 add.w d1,d1 *convert to word index374 clr.w d0 *get resolution375 move.b E_DATA2(a0),d0 *... in d0376 lea _anrs,a1 *point at resolution table base377 move.w d0,0(a1,d1.W) *save resolution in table378 bra exexit *done379 * 380 *exanvl -- execute analog value event381 *------ --------------------------382 exanvl: move.b E_DATA1(a0),d0 *get group number383 andi.w # $000F,d0 *... in d0384 add.w d0,d0 *... as a word offset385 lea _grpstat,a1 *check grpstat[grp]386 tst.w 0(a1,d0.W) *...387 beq exexit *done if not enabled388 * 389 move.w E_DN(a0),-(a7) *put value on stack390 clr.w d2 *get variable / group numbers391 move.b E_DATA1(a0),d2 *... into d2392 move.w d2,d1 *extract group number393 andi.w # $000F,d1 *... into d1394 lsr.w #3,d2 *extract variable number395 andi.w # $001E,d2 *... as a word index in d2396 lea _var2src,a1 *point at variable map397 move.w 0(a1,d2.W),-(a7) *put source number on stack398 move.w d1,-(a7) *put group number on stack399 jsr _setsv *setsv(group, src, val)400 adda.l #6,a7 *clean up stack401 bra exexit *done402 * 403 *exnext -- next score404 *------ ----------405 exnext: move.w #1,_nxtflag *set next score flag406 bra exexit *done407 * 408 .page 409 * 410 *expnch -- execute punch in/out411 *------ --------------------412 expnch: tst.w _recsw *recording ?413 beq exexit *ignore if not414 * 415 tst.w E_DATA1(a0) *punch in ?416 bne expnch5 *jump if so417 * 418 *punch out419 * 420 lea _grpmode,a1 *setup for group modes421 move.w #11,d0 *...422 * 423 expnch0: cmpi.w #2,(a1) *in record mode ?424 bne expnch1 *jump if not425 * 426 clr.w (a1) *set to play mode427 * 428 expnch1: addq.l #2,a1 *point at next entry429 dbra d0,expnch0 *loop through all groups430 * 431 lea _varmode,a1 *setup for variable modes432 move.w #5,d1 *set variable count433 * 434 expnch4: clr.w d0 *clear offset435 * 436 expnch2: cmpi.w #2,0(a1,d0.W) *in record mode ?437 bne expnch3 *jump if not438 * 439 clr.w 0(a1,d0.W) *set to play mode440 * 441 expnch3: addq.w #2,d0 *update offset442 cmpi.w #24,d0 *check for final group443 bne expnch2 *loop through all groups444 * 445 add.l #32,a1 *point at next variable446 dbra d1,expnch4 *loop through all variables447 * 50 51 .page 52 53 | parameter offsets 54 | ----------------- 55 P_EP = 8 | WORD - 'ep' parameter offset 56 P_SD = 12 | WORD - 'sd' parameter offset 57 58 | event structure offsets -- MUST match score.h definitions 59 | ----------------------- ------------------------------ 60 | offset length 61 | ------ ------ 62 E_TIME = 0 | LONG 63 E_SIZE = 4 | BYTE 64 E_TYPE = 5 | BYTE 65 E_DATA1 = 6 | BYTE 66 E_NOTE = 6 | BYTE 67 E_DATA2 = 7 | BYTE 68 E_GROUP = 7 | BYTE 69 E_BAK = 8 | LONG 70 E_FWD = 12 | LONG 71 E_DN = 16 | LONG 72 E_VEL = 16 | WORD 73 E_DATA4 = 18 | WORD 74 E_UP = 20 | LONG 75 E_LFT = 24 | LONG 76 E_RGT = 28 | LONG 77 78 | Miscellaneous constants 79 | ----------------------- 80 N_ETYPES = 25 | number of event types 81 82 M_KSTATE = 0x01 | keys status bit 83 N_KSTATE = 0xFE | keys status bit complement 84 85 D_BAK = 1 | code for backward scrolling 86 87 LCL_PRT = 2 | 0-origin local port number 88 LCL_PCH = 0x1080 | port and channel for trigger 89 90 .page 91 92 | A few words about se_exec: 93 94 | se_exec has to be very fast, so it's written in assembly language, 95 | rather than C, which is usually pretty good, but not quite good enough 96 | for this application. The faster this routine runs, the higher the 97 | tempo we can keep up with. If this code is fast enough, we end up 98 | hardware limited by the timer. 99 100 _se_exec: link a6,#0 | link stack frames 101 movea.l P_EP(a6),a0 | get event pointer 'ep' into a0 102 move.l a0,_xevent | save in xevent 103 move.b E_TYPE(a0),d1 | get event type into d1.W 104 andi.w #0x007F,d1 | ... and mask off new-data flag 105 cmp.b #N_ETYPES,d1 | see if it's valid 106 blt sexc1 | jump if it is 107 108 BadEvnt: move.l a0,d0 | setup to return pointer we got 109 bra done | exit 110 111 exexit: movea.l _xevent,a0 | point at next event 112 move.l E_FWD(a0),d0 | ... 113 114 done: unlk a6 | done -- unlink stack frames 115 rts | return to caller 116 117 sexc1: lea sextab,a1 | get base of dispatch table 118 lsl.w #2,d1 | multiplty event by 4 for index 119 movea.l 0(a1,d1.W),a2 | get address of event routine 120 jmp (a2) | jump to event execution routine 121 122 | On entry, the individual execution routines only depend on a0 pointing at the 123 | event they were dispatched for. 124 125 | The usual C function register usage conventions apply: 126 127 | d0..d2 and a0..a2 are used for scratch, and are not preserved. 128 129 | d3..d6 and a3..a5 are register variables, and are preserved. 130 | a6 = frame pointer, a7 = stack pointer, and are preserved. 131 132 .page 133 134 | exnbeg -- execute note begin 135 | ------ ------------------ 136 | If things need to be sped up, we could incorporate the functions of 137 | asgvce() here, rather than calling it. asgvce() could also be re-written in 138 | assembly language to make it a shade faster. 139 140 exnbeg: cmpi.w #D_BAK,P_SD(a6) | check direction 141 beq nendex | if backward, treat as note end 142 143 nbegex: clr.w d1 | clear d1 144 move.b E_GROUP(a0),d1 | get group number 145 add.w d1,d1 | ... | 2 146 lea _grpstat,a1 | point at grpstat 147 tst.w 0(a1,d1.W) | see if group is enabled 148 beq exexit | done if not 149 150 move.b E_NOTE(a0),d1 | d1 = note number nn (0..127) 151 move.w #LCL_PCH,d2 | put port and channel in d2 152 add.w d1,d2 | d2 = trg 153 lea _trgtab,a1 | point at trgtab[trg] 154 move.b 0(a1,d2.W),d0 | ... 155 or.b #M_KSTATE,d0 | set trigger table entry on 156 move.b d0,0(a1,d2.W) | ... 157 lea _veltab,a1 | point at veltab 158 add.w d2,d2 | ... 159 move.w E_VEL(a0),0(a1,d2.W) | put velocity in veltab 160 move.w E_VEL(a0),-(a7) | put velocity on the stack 161 move.w d1,-(a7) | put note number on the stack 162 move.w #1,-(a7) | put channel on the stack 163 move.w #LCL_PRT,-(a7) | put port on the stack 164 move.b E_GROUP(a0),d1 | d1 = group number (0..11) 165 move.w d1,-(a7) | put group number on the stack 166 jsr _asgvce | start the note 167 add.l #10,a7 | clean up the stack 168 bra exexit | done 169 170 .page 171 172 | exnend -- execute note end 173 | ------ ---------------- 174 | If things need to be sped up, we could incorporate the functions of 175 | procpfl() here, rather than calling it. procpfl() could also be re-written in 176 | assembly language to make it a shade faster. 177 178 exnend: cmpi.w #D_BAK,P_SD(a6) | check direction 179 beq nbegex | if backward, treat as beginning 180 181 nendex: clr.w d1 | clear d1 182 move.b E_GROUP(a0),d1 | get group number 183 add.w d1,d1 | ... | 2 184 lea _grpstat,a1 | point at grpstat 185 tst.w 0(a1,d1.W) | check group status 186 beq exexit | done if disabled 187 188 move.b E_NOTE(a0),d1 | d1 = note number nn (0..127) 189 move.w #LCL_PCH,d2 | put port and channel in d2 190 add.w d1,d2 | d2 = trg | 2 191 add.w d2,d2 | ... 192 lea _trgtab,a1 | set trigger table entry off 193 move.b 0(a1,d2.W),d0 | ... 194 and.b #N_KSTATE,d0 | ... 195 move.b d0,0(a1,d2.W) | ... 196 bne exexit | done if note still active 197 198 .page 199 200 lsr.w #1,d2 | adjust d2 201 clr.w d1 | set loop index 202 lea _vce2trg,a2 | point at vce2trg table 203 204 exnend1: cmp.w (a2),d2 | see if this voice uses trg 205 bne exnend2 | jump if not 206 207 move.w #-1,(a2) | set entry to -1 208 move.l a2,-(a7) | save a2 on stack 209 move.w d1,-(a7) | save d1 on stack 210 move.w d2,-(a7) | save d2 on stack 211 lea _vce2grp,a1 | put group on stack 212 move.w d1,d0 | ... 213 add.w d0,d0 | ... 214 move.w 0(a1,d0.W),-(a7) | ... 215 move.w d2,-(a7) | put trg on stack 216 jsr _procpfl | process sustained voices 217 addq.l #4,a7 | clean up stack 218 move.w (a7)+,d2 | restore d2 219 move.w (a7)+,d1 | restore d1 220 movea.l (a7)+,a2 | restore a2 221 222 exnend2: addq.l #2,a2 | point at next vce2trg entry 223 addq.w #1,d1 | loop until all are checked 224 cmp.w #12,d1 | ... 225 bne exnend1 | ... 226 227 bra exexit | done 228 229 .page 230 231 | exsbgn -- execute section begin 232 | ------ --------------------- 233 exsbgn: clr.w d0 | get section number 234 move.b E_DATA1(a0),d0 | ... 235 move.w d0,_cursect | set section number 236 bra exexit | done 237 238 | exasgn -- execute assignment event 239 | ------ ------------------------ 240 exasgn: clr.w d0 | get assignment 241 move.b E_DATA1(a0),d0 | ... 242 move.w d0,-(a7) | getasg(curasg = asgn) 243 move.w d0,_curasg | ... 244 jsr _getasg | ... 245 tst.w (a7)+ | ... 246 bra exexit | done 247 248 | extune -- execute tuning event 249 | ------ -------------------- 250 extune: clr.w d0 | get tuning 251 move.b E_DATA1(a0),d0 | ... 252 move.w d0,-(a7) | gettun(tuning) 253 jsr _gettun | ... 254 tst.w (a7)+ | ... 255 bra exexit | done 256 257 | extrns -- execute transposition event 258 | ------ --------------------------- 259 extrns: clr.w d0 | get group number 260 move.b E_DATA1(a0),d0 | ... 261 add.w d0,d0 | ... as an index in d0 262 lea _grpstat,a1 | check grpstat[grp] 263 tst.w 0(a1,d0.W) | ... 264 beq exexit | done if disabled 265 266 lea _s_trns,a1 | set group transposition 267 move.w E_LFT(a0),0(a1,d0.W) | ... 268 jsr _settune | ... 269 bra exexit | done 270 271 .page 272 273 | extmpo -- execute tempo event 274 | ------ ------------------- 275 extmpo: clr.w d0 | get tempo 276 move.b E_DATA1(a0),d0 | ... 277 move.w d0,-(a7) | settmpo(tempo) 278 jsr _settmpo | ... 279 tst.w (a7)+ | ... 280 bra exexit | done 281 282 | exstop -- execute stop event 283 | ------ ------------------ 284 exstop: clr.w -(a7) | stop the clock 285 jsr _clkset | ... 286 tst.w (a7)+ | ... 287 bra exexit | that's all, folks 288 289 | exintp -- execute interpolate event 290 | ------ ------------------------- 291 exintp: move.w E_DATA1(a0),_curintp | set interpolate value 292 bra exexit | done 293 294 .page 295 296 | exinst -- execute instrument change event 297 | ------ ------------------------------- 298 exinst: clr.w d0 | get group number 299 move.b E_DATA1(a0),d0 | ... in d0 300 add.w d0,d0 | ... as a word offset 301 lea _grpstat,a1 | check grpstat[grp] 302 tst.w 0(a1,d0.W) | ... 303 beq exexit | done if not enabled 304 305 lea _ins2grp,a1 | point at ins2grp[] 306 clr.w d0 | get instrument number 307 move.b E_DATA2(a0),d0 | ... in d0 308 clr.w d1 | get group number 309 move.b E_DATA1(a0),d1 | ... in d1 310 move.w d1,-(a7) | put group number on stack 311 add.w d1,d1 | make d1 a word pointer 312 move.w 0(a1,d1.W),d2 | get ins2grp[group] 313 and.w #0xFF00,d2 | mask off GTAG1..GTAG8 314 or.w d0,d2 | OR in new instrument number 315 move.w d2,0(a1,d1.W) | set ins2grp[group] 316 jsr _setv2gi | setv2gi(group) 317 tst.w (a7)+ | clean up stack 318 bra exexit | done 319 320 .page 321 322 | exdyn -- execute dynamics event 323 | ----- ---------------------- 324 exdyn: clr.w d0 | get group number 325 move.b E_DATA1(a0),d0 | ... in d0 326 add.w d0,d0 | ... as a word offset 327 lea _grpstat,a1 | check grpstat[grp] 328 tst.w 0(a1,d0.W) | ... 329 beq exexit | done if not enabled 330 331 clr.w d0 | get dynamics 332 move.b E_DATA2(a0),d0 | ... in d0 333 clr.w d1 | get group number 334 move.b E_DATA1(a0),d1 | ... in d1 335 move.w d0,-(a7) | setdyn(group, dyn) 336 move.w d1,-(a7) | ... 337 jsr _setdyn | ... 338 adda.l #4,a7 | clean up stack 339 bra exexit | done 340 341 | exlocn -- execute location event 342 | ------ ---------------------- 343 exlocn: clr.w d0 | get group number 344 move.b E_DATA1(a0),d0 | ... in d0 345 add.w d0,d0 | ... as a word offset 346 lea _grpstat,a1 | check grpstat[grp] 347 tst.w 0(a1,d0.W) | ... 348 beq exexit | done if not enabled 349 350 clr.w d0 | get location 351 move.b E_DATA2(a0),d0 | ... in d0 352 clr.w d1 | get group number 353 move.b E_DATA1(a0),d1 | ... in d1 354 move.w d0,-(a7) | setloc(group, loc) 355 move.w d1,-(a7) | ... 356 jsr _setloc | ... 357 adda.l #4,a7 | clean up stack 358 bra exexit | done 359 360 .page 361 362 | exanrs -- execute analog resolution event 363 | ------ ------------------------------- 364 exanrs: move.b E_DATA1(a0),d0 | get group number 365 andi.w #0x000F,d0 | ... in d0 366 add.w d0,d0 | ... as a word offset 367 lea _grpstat,a1 | check grpstat[grp] 368 tst.w 0(a1,d0.W) | ... 369 beq exexit | done if not enabled 370 371 clr.w d1 | get variable / group numbers 372 move.b E_DATA1(a0),d1 | ... 373 add.w d1,d1 | convert to word index 374 clr.w d0 | get resolution 375 move.b E_DATA2(a0),d0 | ... in d0 376 lea _anrs,a1 | point at resolution table base 377 move.w d0,0(a1,d1.W) | save resolution in table 378 bra exexit | done 379 380 | exanvl -- execute analog value event 381 | ------ -------------------------- 382 exanvl: move.b E_DATA1(a0),d0 | get group number 383 andi.w #0x000F,d0 | ... in d0 384 add.w d0,d0 | ... as a word offset 385 lea _grpstat,a1 | check grpstat[grp] 386 tst.w 0(a1,d0.W) | ... 387 beq exexit | done if not enabled 388 389 move.w E_DN(a0),-(a7) | put value on stack 390 clr.w d2 | get variable / group numbers 391 move.b E_DATA1(a0),d2 | ... into d2 392 move.w d2,d1 | extract group number 393 andi.w #0x000F,d1 | ... into d1 394 lsr.w #3,d2 | extract variable number 395 andi.w #0x001E,d2 | ... as a word index in d2 396 lea _var2src,a1 | point at variable map 397 move.w 0(a1,d2.W),-(a7) | put source number on stack 398 move.w d1,-(a7) | put group number on stack 399 jsr _setsv | setsv(group, src, val) 400 adda.l #6,a7 | clean up stack 401 bra exexit | done 402 403 | exnext -- next score 404 | ------ ---------- 405 exnext: move.w #1,_nxtflag | set next score flag 406 bra exexit | done 407 408 .page 409 410 | expnch -- execute punch in/out 411 | ------ -------------------- 412 expnch: tst.w _recsw | recording ? 413 beq exexit | ignore if not 414 415 tst.w E_DATA1(a0) | punch in ? 416 bne expnch5 | jump if so 417 418 | punch out 419 420 lea _grpmode,a1 | setup for group modes 421 move.w #11,d0 | ... 422 423 expnch0: cmpi.w #2,(a1) | in record mode ? 424 bne expnch1 | jump if not 425 426 clr.w (a1) | set to play mode 427 428 expnch1: addq.l #2,a1 | point at next entry 429 dbra d0,expnch0 | loop through all groups 430 431 lea _varmode,a1 | setup for variable modes 432 move.w #5,d1 | set variable count 433 434 expnch4: clr.w d0 | clear offset 435 436 expnch2: cmpi.w #2,0(a1,d0.W) | in record mode ? 437 bne expnch3 | jump if not 438 439 clr.w 0(a1,d0.W) | set to play mode 440 441 expnch3: addq.w #2,d0 | update offset 442 cmpi.w #24,d0 | check for final group 443 bne expnch2 | loop through all groups 444 445 add.l #32,a1 | point at next variable 446 dbra d1,expnch4 | loop through all variables 447 448 448 bra exexit 449 * 450 .page 451 * 452 *punch in453 * 454 expnch5: lea _grpmode,a1 *setup for group modes455 move.w #11,d0 *...456 * 457 expnch6: cmpi.w #1,(a1) *in standby mode ?458 bne expnch7 *jump if not459 * 460 move.w #2,(a1) *set to record mode461 * 462 expnch7: addq.l #2,a1 *point at next entry463 dbra d0,expnch6 *loop through all groups464 * 465 lea _varmode,a1 *setup for variable modes466 move.w #5,d1 *set variable count467 * 468 expnch10: clr.w d0 *clear offset469 * 470 expnch8: cmpi.w #1,0(a1,d0.W) *in standby mode ?471 bne expnch9 *jump if not472 * 473 move.w #2,0(a1,d0.W) *set to record mode474 * 475 expnch9: addq.w #2,d0 *update offset476 cmpi.w #24,d0 *check for final group477 bne expnch8 *loop through all groups478 * 479 adda.l #32,a1 *point at next variable480 dbra d1,expnch10 *loop through all variables481 * 449 450 .page 451 452 | punch in 453 454 expnch5: lea _grpmode,a1 | setup for group modes 455 move.w #11,d0 | ... 456 457 expnch6: cmpi.w #1,(a1) | in standby mode ? 458 bne expnch7 | jump if not 459 460 move.w #2,(a1) | set to record mode 461 462 expnch7: addq.l #2,a1 | point at next entry 463 dbra d0,expnch6 | loop through all groups 464 465 lea _varmode,a1 | setup for variable modes 466 move.w #5,d1 | set variable count 467 468 expnch10: clr.w d0 | clear offset 469 470 expnch8: cmpi.w #1,0(a1,d0.W) | in standby mode ? 471 bne expnch9 | jump if not 472 473 move.w #2,0(a1,d0.W) | set to record mode 474 475 expnch9: addq.w #2,d0 | update offset 476 cmpi.w #24,d0 | check for final group 477 bne expnch8 | loop through all groups 478 479 adda.l #32,a1 | point at next variable 480 dbra d1,expnch10 | loop through all variables 481 482 482 bra exexit 483 * 484 .page 485 * 486 *sextab -- score execution dispatch table -- MUST match score.h definitions487 *------ ----------------------------------------------------------------488 sextab: dc.l exexit *0 null489 dc.l exexit *1 score begin490 dc.l exsbgn *2 section begin491 dc.l exexit *3 section end492 dc.l exinst *4 instrument change493 dc.l exnbeg *5 note begin494 dc.l exnend *6 note end495 dc.l exstop *7 stop496 dc.l exintp *8 interpolate497 dc.l extmpo *9 tempo498 dc.l extune *10 tuning499 dc.l exexit *11 group status500 dc.l exlocn *12 location501 dc.l exdyn *13 dynamics502 dc.l exanvl *14 analog value503 dc.l exanrs *15 analog resolution504 dc.l exasgn *16 I/O assign505 dc.l extrns *17 transposition506 dc.l exexit *18 repeat507 dc.l expnch *19 punch in/out508 dc.l exexit *20 -unused- (polyphonic pressure)509 dc.l exexit *21 score end510 dc.l exexit *22 -unused- (channel pressure)511 dc.l exexit *23 bar marker512 dc.l exnext *24 next score513 * 483 484 .page 485 486 | sextab -- score execution dispatch table -- MUST match score.h definitions 487 | ------ ---------------------------------------------------------------- 488 sextab: dc.l exexit | 0 null 489 dc.l exexit | 1 score begin 490 dc.l exsbgn | 2 section begin 491 dc.l exexit | 3 section end 492 dc.l exinst | 4 instrument change 493 dc.l exnbeg | 5 note begin 494 dc.l exnend | 6 note end 495 dc.l exstop | 7 stop 496 dc.l exintp | 8 interpolate 497 dc.l extmpo | 9 tempo 498 dc.l extune | 10 tuning 499 dc.l exexit | 11 group status 500 dc.l exlocn | 12 location 501 dc.l exdyn | 13 dynamics 502 dc.l exanvl | 14 analog value 503 dc.l exanrs | 15 analog resolution 504 dc.l exasgn | 16 I/O assign 505 dc.l extrns | 17 transposition 506 dc.l exexit | 18 repeat 507 dc.l expnch | 19 punch in/out 508 dc.l exexit | 20 -unused- (polyphonic pressure) 509 dc.l exexit | 21 score end 510 dc.l exexit | 22 -unused- (channel pressure) 511 dc.l exexit | 23 bar marker 512 dc.l exnext | 24 next score 513 514 514 .bss 515 * 516 *Variable storage areas517 *----------------------518 *globals:519 *--------520 _xevent: ds.l 1 *next event pointer521 * 515 516 | Variable storage areas 517 | ---------------------- 518 | globals: 519 | -------- 520 _xevent: ds.l 1 | next event pointer 521 522 522 .end -
ram/serintr.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *serintr.s -- MIDAS-VII serial I/O subroutines3 *Version 4 -- 1988-12-13 -- D.N. Lynx Crowe4 * 5 *These subroutines replace those in bios.s in order to add support for6 *MIDAS-VII foot pedal and pulse inputs, and pulse outputs.7 * 8 *WARNING: The code below uses addresses in the bios RAM area. These addresses9 *correspond to those in PROMS dated 1988-06-20 et seq. If the bios is changed,10 *the addresses marked with <== may have to be changed.11 *------------------------------------------------------------------------------12 * 1 | ------------------------------------------------------------------------------ 2 | serintr.s -- MIDAS-VII serial I/O subroutines 3 | Version 4 -- 1988-12-13 -- D.N. Lynx Crowe 4 5 | These subroutines replace those in bios.s in order to add support for 6 | MIDAS-VII foot pedal and pulse inputs, and pulse outputs. 7 8 | WARNING: The code below uses addresses in the bios RAM area. These addresses 9 | correspond to those in PROMS dated 1988-06-20 et seq. If the bios is changed, 10 | the addresses marked with <== may have to be changed. 11 | ------------------------------------------------------------------------------ 12 13 13 .text 14 * 14 15 15 .xdef _setsio 16 * 16 17 17 .xdef _foot1 18 18 .xdef _foot2 19 19 .xdef _pulse1 20 20 .xdef _pulse2 21 * 21 22 22 .xdef serintr 23 * 23 24 24 .xdef serint 25 25 .xdef midint 26 * 26 27 27 .xdef wrapin 28 28 .xdef wrapout 29 * 29 30 30 .xdef serput 31 31 .xdef midput 32 * 32 33 33 .xdef rtschk 34 * 34 35 35 .xdef rtson 36 36 .xdef rtsoff 37 * 38 *==============================================================================39 * 40 *The following addresses, marked by <==, are bios version dependent:41 * 42 RAM .equ $00000400 *Beginning of system RAM area <==43 * 44 SR1IOREC .equ RAM+$0AB0 *Serial-1 iorec structure <==45 SR2IOREC .equ RAM+$0AD8 *Serial-2 iorec structure <==46 MC1IOREC .equ RAM+$0B00 *MIDI-1 iorec structure <==47 MC2IOREC .equ RAM+$0B28 *MIDI-2 iorec structure <==48 * 49 *End of bios version dependent addresses.50 * 51 *==============================================================================52 * 53 .page 54 * 55 SERVECT .equ $000074 *Level 5 interrupt autovector address56 * 57 IPL7 .equ $0700 *IPL 7 value for sr58 * 59 *ACIA I/O Addresses:60 *-------------------61 SR1ACIA .equ $3A8001 *Serial-1 ACIA base address62 SR2ACIA .equ $3A8009 *Serial-2 ACIA base address63 MC1ACIA .equ $3AC001 *MIDI-1 ACIA base address64 MC2ACIA .equ $3AC009 *MIDI-2 ACIA base address65 * 66 *ACIA Register offsets:67 *----------------------68 ACIA_IER .equ 0 *ACIA IER offset69 ACIA_ISR .equ 0 *ACIA ISR offset70 ACIA_CSR .equ 2 *ACIA CSR offset71 ACIA_CFR .equ 2 *ACIA CFR offset72 ACIA_TBR .equ 4 *ACIA TBR offset73 ACIA_TDR .equ 6 *ACIA TDR offset74 ACIA_RDR .equ 6 *ACIA RDR offset75 * 76 *iorec structure definitions:77 *----------------------------78 IORECLN .equ 40 *Length of an iorec structure79 * 80 ibuf .equ 0 *Input buffer base address81 ibufsize .equ 4 *Input buffer size (bytes)82 ibufhd .equ 6 *Input buffer head index83 ibuftl .equ 8 *Input buffer tail index84 ibuflow .equ 10 *Input buffer low water mark85 ibufhi .equ 12 *Input buffer high water mark86 obuf .equ 14 *Output buffer base address87 obufsize .equ 18 *Output buffer size (bytes)88 obufhd .equ 20 *Output buffer head index89 obuftl .equ 22 *Output buffer tail index90 obuflow .equ 24 *Output buffer low water mark91 obufhi .equ 26 *Output buffer high water mark92 cfr0 .equ 28 *ACIA CFR, MS bit = 093 cfr1 .equ 29 *ACIA CFR, MS bit = 194 flagxon .equ 30 *XON flag (non-zero = XOFF sent)95 flagxoff .equ 31 *XOFF flag (non-zero = active)96 linedisc .equ 32 *Line discipline flags97 erbyte .equ 33 *Last error byte98 isr .equ 34 *ACIA ISR on interrupt99 csr .equ 35 *ACIA CSR on interrupt100 errct .equ 36 *Error count (FRM/OVR/BRK)101 ibfct .equ 38 *Input buffer full count102 * 103 .page 104 * 105 *serintr -- Serial (Serial-1, Serial-2, MIDI-1, MIDI-2) interrupt handler106 *------- -------------------------------------------------------------107 serintr: movem.l d0-d3/a0-a2,-(a7) *Save registers108 lea SR1IOREC,a0 *Point at Serial-1 iorec109 lea SR1ACIA,a1 *Point at Serial-1 ACIA110 movea.l _foot1,a2 *Point at foot sw. 1 processor111 bsr serint *Go process (possible) int.112 * 113 lea SR2IOREC,a0 *Point at Serial-2 iorec114 lea SR2ACIA,a1 *Point at Serial-2 ACIA115 movea.l _foot2,a2 *Point at foot sw. 2 processor116 bsr serint *Go process (possible) int.117 * 118 lea MC1IOREC,a0 *Point at MIDI-1 iorec119 lea MC1ACIA,a1 *Point at MIDI-1 ACIA120 movea.l _pulse1,a2 *Point at pulse 1 processor121 bsr midint *Go process (possible) int.122 * 123 lea MC2IOREC,a0 *Point at MIDI-2 iorec124 lea MC2ACIA,a1 *Point at MIDI-2 ACIA125 movea.l _pulse2,a2 *Point at pulse 2 processor126 bsr midint *Go process (possible) int.127 * 128 movem.l (a7)+,d0-d3/a0-a2 *Restore registers129 rte *Return from exception130 * 131 .page 132 * 133 *serint -- Process an interrupt from Serial-1 or Serial-2134 *------ ----------------------------------------------135 serint: move.b ACIA_ISR(a1),isr(a0) *Get and save ISR136 move.b ACIA_CSR(a1),csr(a0) *Get and save CSR137 * 138 btst.b #7,isr(a0) *Was int for this device ?139 beq serintx *Jump if not140 * 141 serchk: btst.b #1,isr(a0) *FRM/OVR/BRK error ?142 bne sererr *Jump if so143 * 144 btst.b #0,isr(a0) *Receiver interrupt ?145 bne serrx *Jump if so146 * 147 sertxq: btst.b #6,isr(a0) *Transmitter interrupt ?148 bne sertx *Jump if so149 * 150 serctq: btst.b #5,isr(a0) *CTS interrupt ?151 bne sercts *Jump if so152 * 153 serintx: btst.b #4,isr(a0) *DCD interrupt ?154 bne calldcd *Jump if so155 * 156 serdone: rts *Return to caller157 * 158 calldcd: move.b csr(a0),d0 *Get CSR interrupt status159 btst.l #4,d0 *Check DCD input (0 = active)160 bne calldcd0 *Jump if line was inactive161 * 162 moveq.l #1,d0 *Set footswitch status to TRUE163 bra calldcd1 *...164 * 165 calldcd0: moveq.l #0,d0 *Set footswitch status to FALSE166 * 167 calldcd1: move.w d0,-(a7) *Call the footswitch processor168 jsr (a2) * ... (*footX)(status)169 tst.w (a7)+ *...170 rts *Return to caller171 * 172 .page 173 * 174 *Handle serial I/O port error175 * 176 sererr: addq.w #1,errct(a0) *Update error count177 move.b ACIA_RDR(a1),erbyte(a0) *Get error byte178 rts *Return to caller179 * 180 * 181 *Handle CTS interupt182 * 183 sercts: btst.b #1,linedisc(a0) *RTS/CTS mode ?184 beq serintx *Ignore if not185 * 186 btst.b #5,csr(a0) *CTS set ?187 beq serintx *Ignore if not188 * 189 sercts1: btst.b #6,isr(a0) *TDRE set ?190 beq sercts1 *Loop until it is (!)191 * 192 move.w obufhd(a0),d2 *Head index to d2193 cmp.w obuftl(a0),d2 *Compare to tail index194 beq serintx *Done if buffer empty195 * 196 bsr wrapout *Adjust pointer for wraparound197 move.l obuf(a0),a2 *Get buffer base in a2198 move.b 0(a2,d2),ACIA_TDR(a1) *Send byte on its way199 move.w d2,obufhd(a0) *Save updated head index200 bra serintx *Done201 * 202 .page 203 * 204 *Handle receiver interrupt205 * 206 serrx: btst.b #1,linedisc(a0) *RTS/CTS mode set ?207 beq serrx1 *Jump if not208 * 209 bsr rtsoff *Turn off RTS210 * 211 serrx1: move.b ACIA_RDR(a1),d0 *Read data from ACIA212 btst.b #1,linedisc(a0) *RTS/CTS mode set ?213 bne serrx3 *Jump if so214 * 215 btst.b #0,linedisc(a0) *XON/XOFF mode set ?216 beq serrx3 *Jump if not217 * 218 cmpi.b # $11,d0 *Is this an XON ?219 bne serrx2 *Jump if not220 * 221 move.b # $00,flagxoff(a0) *Clear flagxoff222 bra sertxq *Done223 * 224 serrx2: cmpi.b # $13,d0 *Is this an XOFF ?225 bne serrx3 *Jump if not226 * 227 move.b # $FF,flagxoff(a0) *Set flagxoff228 bra sertxq *Done229 * 230 serrx3: move.w ibuftl(a0),d1 *Get tail index in d1231 bsr wrapin *Adjust for wraparound232 cmp.w ibufhd(a0),d1 *Head = tail ?233 beq seribf *If so, we drop the character234 * 235 .page 236 move.l ibuf(a0),a2 *Get buffer address237 move.b d0,0(a2,d1) *Stash byte in buffer238 move.w d1,ibuftl(a0) *Save updated tail index239 move.w ibuftl(a0),d2 *Tail index to d2240 move.w ibufhd(a0),d3 *Head index to d3241 cmp.w d3,d2 *Head > Tail ?242 bhi rsi_1 *Jump if not243 * 244 add.w ibufsize(a0),d2 *Add buffer size to tail index245 * 246 rsi_1: sub.w d3,d2 *Length = (adjusted)Tail - Head247 cmp.w ibufhi(a0),d2 *Hit high water mark ?248 bne serrx4 *Jump if not249 * 250 btst.b #1,linedisc(a0) *RTS/CTS mode set ?251 bne sertxq *Done if so252 * 253 btst.b #0,linedisc(a0) *XON/XOFF mode set ?254 beq serrx4 *Jump if not255 * 256 tst.b flagxon(a0) *XOFF already sent ?257 bne serrx4 *Jump if so258 * 259 move.b # $FF,flagxon(a0) *Set the flag260 move.b # $13,d1 *Send an XOFF261 bsr serput *...262 * 263 serrx4: btst #1,linedisc(a0) *RTS/CTS mode set ?264 beq sertxq *Done if not265 * 266 bsr rtson *Turn on RTS267 bra sertxq *Done268 * 269 .page 270 * 271 *Handle transmitter interrupt272 * 273 sertx: btst.b #1,linedisc(a0) *RTS/CTS mode set ?274 bne sertx2 *If so, go check CTS275 * 276 btst.b #0,linedisc(a0) *XON/XOFF mode set ?277 beq sertx1 *Jump if not278 * 279 tst.b flagxoff(a0) *Check flagxoff280 bne serctq *Done if set281 * 282 sertx1: move.w obufhd(a0),d2 *Head index to d2283 cmp.w obuftl(a0),d2 *Compare to tail index284 beq serctq *Done if buffer empty285 * 286 bsr wrapout *Adjust pointer for wraparound287 move.l obuf(a0),a2 *Get buffer base address288 move.b 0(a2,d2),ACIA_TDR(a1) *Send byte on its way289 move.w d2,obufhd(a0) *Save updated head index290 bra serctq *Done291 * 292 sertx2: btst.b #5,csr(a0) *CTS set in csr ?293 beq serctq *If not, go check for CTS int294 * 295 bra sertx1 *CTS was set, go transmit296 * 297 seribf: move.b d0,erbyte(a0) *Log dropped character298 addq.w #1,ibfct(a0) *...299 bra sertxq *Go check Tx interrupt300 * 301 .page 302 * 303 *midint -- Process an interrupt from MIDI-1 or MIDI-2304 *------ ------------------------------------------305 midint: move.b ACIA_ISR(a1),isr(a0) *Get and save ISR306 move.b ACIA_CSR(a1),csr(a0) *Get and save CSR307 * 308 btst.b #7,isr(a0) *Was int for this device ?309 beq midintx *Jump if not310 * 311 midchk: btst.b #1,isr(a0) *FRM/OVR/BRK error ?312 bne miderr *Jump if so313 * 314 btst.b #0,isr(a0) *Receiver interrupt ?315 bne midrx *Jump if so316 * 317 midtxq: btst.b #6,isr(a0) *Transmitter interrupt ?318 bne midtx *Jump if so319 * 320 midintx: btst #4,isr(a0) *DCD interrupt ?321 bne mididcd *Jump if so322 * 323 mididone: rts *Return to caller324 * 325 mididcd: jmp (a2) *Exit through the DCD processor326 * 327 miderr: addq.w #1,errct(a0) *Update error count328 move.b ACIA_RDR(a1),erbyte(a0) *Get error byte37 38 | ============================================================================== 39 40 | The following addresses, marked by <==, are bios version dependent: 41 42 RAM = 0x00000400 | Beginning of system RAM area <== 43 44 SR1IOREC = RAM+0x0AB0 | Serial-1 iorec structure <== 45 SR2IOREC = RAM+0x0AD8 | Serial-2 iorec structure <== 46 MC1IOREC = RAM+0x0B00 | MIDI-1 iorec structure <== 47 MC2IOREC = RAM+0x0B28 | MIDI-2 iorec structure <== 48 49 | End of bios version dependent addresses. 50 51 | ============================================================================== 52 53 .page 54 55 SERVECT = 0x000074 | Level 5 interrupt autovector address 56 57 IPL7 = 0x0700 | IPL 7 value for sr 58 59 | ACIA I/O Addresses: 60 | ------------------- 61 SR1ACIA = 0x3A8001 | Serial-1 ACIA base address 62 SR2ACIA = 0x3A8009 | Serial-2 ACIA base address 63 MC1ACIA = 0x3AC001 | MIDI-1 ACIA base address 64 MC2ACIA = 0x3AC009 | MIDI-2 ACIA base address 65 66 | ACIA Register offsets: 67 | ---------------------- 68 ACIA_IER = 0 | ACIA IER offset 69 ACIA_ISR = 0 | ACIA ISR offset 70 ACIA_CSR = 2 | ACIA CSR offset 71 ACIA_CFR = 2 | ACIA CFR offset 72 ACIA_TBR = 4 | ACIA TBR offset 73 ACIA_TDR = 6 | ACIA TDR offset 74 ACIA_RDR = 6 | ACIA RDR offset 75 76 | iorec structure definitions: 77 | ---------------------------- 78 IORECLN = 40 | Length of an iorec structure 79 80 ibuf = 0 | Input buffer base address 81 ibufsize = 4 | Input buffer size (bytes) 82 ibufhd = 6 | Input buffer head index 83 ibuftl = 8 | Input buffer tail index 84 ibuflow = 10 | Input buffer low water mark 85 ibufhi = 12 | Input buffer high water mark 86 obuf = 14 | Output buffer base address 87 obufsize = 18 | Output buffer size (bytes) 88 obufhd = 20 | Output buffer head index 89 obuftl = 22 | Output buffer tail index 90 obuflow = 24 | Output buffer low water mark 91 obufhi = 26 | Output buffer high water mark 92 cfr0 = 28 | ACIA CFR, MS bit = 0 93 cfr1 = 29 | ACIA CFR, MS bit = 1 94 flagxon = 30 | XON flag (non-zero = XOFF sent) 95 flagxoff = 31 | XOFF flag (non-zero = active) 96 linedisc = 32 | Line discipline flags 97 erbyte = 33 | Last error byte 98 isr = 34 | ACIA ISR on interrupt 99 csr = 35 | ACIA CSR on interrupt 100 errct = 36 | Error count (FRM/OVR/BRK) 101 ibfct = 38 | Input buffer full count 102 103 .page 104 105 | serintr -- Serial (Serial-1, Serial-2, MIDI-1, MIDI-2) interrupt handler 106 | ------- ------------------------------------------------------------- 107 serintr: movem.l d0-d3/a0-a2,-(a7) | Save registers 108 lea SR1IOREC,a0 | Point at Serial-1 iorec 109 lea SR1ACIA,a1 | Point at Serial-1 ACIA 110 movea.l _foot1,a2 | Point at foot sw. 1 processor 111 bsr serint | Go process (possible) int. 112 113 lea SR2IOREC,a0 | Point at Serial-2 iorec 114 lea SR2ACIA,a1 | Point at Serial-2 ACIA 115 movea.l _foot2,a2 | Point at foot sw. 2 processor 116 bsr serint | Go process (possible) int. 117 118 lea MC1IOREC,a0 | Point at MIDI-1 iorec 119 lea MC1ACIA,a1 | Point at MIDI-1 ACIA 120 movea.l _pulse1,a2 | Point at pulse 1 processor 121 bsr midint | Go process (possible) int. 122 123 lea MC2IOREC,a0 | Point at MIDI-2 iorec 124 lea MC2ACIA,a1 | Point at MIDI-2 ACIA 125 movea.l _pulse2,a2 | Point at pulse 2 processor 126 bsr midint | Go process (possible) int. 127 128 movem.l (a7)+,d0-d3/a0-a2 | Restore registers 129 rte | Return from exception 130 131 .page 132 133 | serint -- Process an interrupt from Serial-1 or Serial-2 134 | ------ ---------------------------------------------- 135 serint: move.b ACIA_ISR(a1),isr(a0) | Get and save ISR 136 move.b ACIA_CSR(a1),csr(a0) | Get and save CSR 137 138 btst.b #7,isr(a0) | Was int for this device ? 139 beq serintx | Jump if not 140 141 serchk: btst.b #1,isr(a0) | FRM/OVR/BRK error ? 142 bne sererr | Jump if so 143 144 btst.b #0,isr(a0) | Receiver interrupt ? 145 bne serrx | Jump if so 146 147 sertxq: btst.b #6,isr(a0) | Transmitter interrupt ? 148 bne sertx | Jump if so 149 150 serctq: btst.b #5,isr(a0) | CTS interrupt ? 151 bne sercts | Jump if so 152 153 serintx: btst.b #4,isr(a0) | DCD interrupt ? 154 bne calldcd | Jump if so 155 156 serdone: rts | Return to caller 157 158 calldcd: move.b csr(a0),d0 | Get CSR interrupt status 159 btst.l #4,d0 | Check DCD input (0 = active) 160 bne calldcd0 | Jump if line was inactive 161 162 moveq.l #1,d0 | Set footswitch status to TRUE 163 bra calldcd1 | ... 164 165 calldcd0: moveq.l #0,d0 | Set footswitch status to FALSE 166 167 calldcd1: move.w d0,-(a7) | Call the footswitch processor 168 jsr (a2) | ... (|footX)(status) 169 tst.w (a7)+ | ... 170 rts | Return to caller 171 172 .page 173 174 | Handle serial I/O port error 175 176 sererr: addq.w #1,errct(a0) | Update error count 177 move.b ACIA_RDR(a1),erbyte(a0) | Get error byte 178 rts | Return to caller 179 180 181 | Handle CTS interupt 182 183 sercts: btst.b #1,linedisc(a0) | RTS/CTS mode ? 184 beq serintx | Ignore if not 185 186 btst.b #5,csr(a0) | CTS set ? 187 beq serintx | Ignore if not 188 189 sercts1: btst.b #6,isr(a0) | TDRE set ? 190 beq sercts1 | Loop until it is (!) 191 192 move.w obufhd(a0),d2 | Head index to d2 193 cmp.w obuftl(a0),d2 | Compare to tail index 194 beq serintx | Done if buffer empty 195 196 bsr wrapout | Adjust pointer for wraparound 197 move.l obuf(a0),a2 | Get buffer base in a2 198 move.b 0(a2,d2),ACIA_TDR(a1) | Send byte on its way 199 move.w d2,obufhd(a0) | Save updated head index 200 bra serintx | Done 201 202 .page 203 204 | Handle receiver interrupt 205 206 serrx: btst.b #1,linedisc(a0) | RTS/CTS mode set ? 207 beq serrx1 | Jump if not 208 209 bsr rtsoff | Turn off RTS 210 211 serrx1: move.b ACIA_RDR(a1),d0 | Read data from ACIA 212 btst.b #1,linedisc(a0) | RTS/CTS mode set ? 213 bne serrx3 | Jump if so 214 215 btst.b #0,linedisc(a0) | XON/XOFF mode set ? 216 beq serrx3 | Jump if not 217 218 cmpi.b #0x11,d0 | Is this an XON ? 219 bne serrx2 | Jump if not 220 221 move.b #0x00,flagxoff(a0) | Clear flagxoff 222 bra sertxq | Done 223 224 serrx2: cmpi.b #0x13,d0 | Is this an XOFF ? 225 bne serrx3 | Jump if not 226 227 move.b #0xFF,flagxoff(a0) | Set flagxoff 228 bra sertxq | Done 229 230 serrx3: move.w ibuftl(a0),d1 | Get tail index in d1 231 bsr wrapin | Adjust for wraparound 232 cmp.w ibufhd(a0),d1 | Head = tail ? 233 beq seribf | If so, we drop the character 234 235 .page 236 move.l ibuf(a0),a2 | Get buffer address 237 move.b d0,0(a2,d1) | Stash byte in buffer 238 move.w d1,ibuftl(a0) | Save updated tail index 239 move.w ibuftl(a0),d2 | Tail index to d2 240 move.w ibufhd(a0),d3 | Head index to d3 241 cmp.w d3,d2 | Head > Tail ? 242 bhi rsi_1 | Jump if not 243 244 add.w ibufsize(a0),d2 | Add buffer size to tail index 245 246 rsi_1: sub.w d3,d2 | Length = (adjusted)Tail - Head 247 cmp.w ibufhi(a0),d2 | Hit high water mark ? 248 bne serrx4 | Jump if not 249 250 btst.b #1,linedisc(a0) | RTS/CTS mode set ? 251 bne sertxq | Done if so 252 253 btst.b #0,linedisc(a0) | XON/XOFF mode set ? 254 beq serrx4 | Jump if not 255 256 tst.b flagxon(a0) | XOFF already sent ? 257 bne serrx4 | Jump if so 258 259 move.b #0xFF,flagxon(a0) | Set the flag 260 move.b #0x13,d1 | Send an XOFF 261 bsr serput | ... 262 263 serrx4: btst #1,linedisc(a0) | RTS/CTS mode set ? 264 beq sertxq | Done if not 265 266 bsr rtson | Turn on RTS 267 bra sertxq | Done 268 269 .page 270 271 | Handle transmitter interrupt 272 273 sertx: btst.b #1,linedisc(a0) | RTS/CTS mode set ? 274 bne sertx2 | If so, go check CTS 275 276 btst.b #0,linedisc(a0) | XON/XOFF mode set ? 277 beq sertx1 | Jump if not 278 279 tst.b flagxoff(a0) | Check flagxoff 280 bne serctq | Done if set 281 282 sertx1: move.w obufhd(a0),d2 | Head index to d2 283 cmp.w obuftl(a0),d2 | Compare to tail index 284 beq serctq | Done if buffer empty 285 286 bsr wrapout | Adjust pointer for wraparound 287 move.l obuf(a0),a2 | Get buffer base address 288 move.b 0(a2,d2),ACIA_TDR(a1) | Send byte on its way 289 move.w d2,obufhd(a0) | Save updated head index 290 bra serctq | Done 291 292 sertx2: btst.b #5,csr(a0) | CTS set in csr ? 293 beq serctq | If not, go check for CTS int 294 295 bra sertx1 | CTS was set, go transmit 296 297 seribf: move.b d0,erbyte(a0) | Log dropped character 298 addq.w #1,ibfct(a0) | ... 299 bra sertxq | Go check Tx interrupt 300 301 .page 302 303 | midint -- Process an interrupt from MIDI-1 or MIDI-2 304 | ------ ------------------------------------------ 305 midint: move.b ACIA_ISR(a1),isr(a0) | Get and save ISR 306 move.b ACIA_CSR(a1),csr(a0) | Get and save CSR 307 308 btst.b #7,isr(a0) | Was int for this device ? 309 beq midintx | Jump if not 310 311 midchk: btst.b #1,isr(a0) | FRM/OVR/BRK error ? 312 bne miderr | Jump if so 313 314 btst.b #0,isr(a0) | Receiver interrupt ? 315 bne midrx | Jump if so 316 317 midtxq: btst.b #6,isr(a0) | Transmitter interrupt ? 318 bne midtx | Jump if so 319 320 midintx: btst #4,isr(a0) | DCD interrupt ? 321 bne mididcd | Jump if so 322 323 mididone: rts | Return to caller 324 325 mididcd: jmp (a2) | Exit through the DCD processor 326 327 miderr: addq.w #1,errct(a0) | Update error count 328 move.b ACIA_RDR(a1),erbyte(a0) | Get error byte 329 329 rts 330 * 331 *Handle receiver interrupt332 * 333 midrx: move.b ACIA_RDR(a1),d0 *Read data from ACIA334 move.w ibuftl(a0),d1 *Get tail index in d1335 bsr wrapin *Adjust for wraparound336 cmp.w ibufhd(a0),d1 *Head = tail ?337 beq midibf *If so, we drop the character338 * 339 move.l ibuf(a0),a2 *Get buffer address340 move.b d0,0(a2,d1) *Stash byte in buffer341 move.w d1,ibuftl(a0) *Save updated tail index342 bra midtxq *Done (go check tx int)343 * 344 .page 345 * 346 *Handle transmitter interrupt347 * 348 midtx: move.w obufhd(a0),d2 *Head index to d2349 cmp.w obuftl(a0),d2 *Compare to tail index350 beq midintx *Done if buffer empty351 * 352 bsr wrapout *Adjust pointer for wraparound353 move.l obuf(a0),a2 *Get buffer base address354 move.b 0(a2,d2),ACIA_TDR(a1) *Send byte on its way355 move.w d2,obufhd(a0) *Save updated head index356 bra midintx *Done357 * 358 midibf: move.b d0,erbyte(a0) *Log dropped character359 addq.w #1,ibfct(a0) *...360 bra midtxq *Go check Tx interrupt361 * 362 .page 363 * 364 *serput -- Output a character to a serial port365 *------ -----------------------------------366 serput: move.w sr,-(a7) *Save status register367 ori.w #IPL7,sr *DISABLE INTERRUPTS368 move.b ACIA_ISR(a1),isr(a0) *Get ACIA isr369 move.b ACIA_CSR(a1),csr(a0) *Get ACIA csr370 btst #0,linedisc(a0) *XON/XOFF mode ?371 beq serpt_1 *Jump if not372 * 373 tst.b flagxoff(a0) *XON active ?374 bne serpt_2 *Jump if so375 * 376 serpt_1: btst.b #6,isr(a0) *Is ACIA still sending ?377 beq serpt_2 *Jump if so378 * 379 move.w obufhd(a0),d2 *Head index to d2380 cmp.w obuftl(a0),d2 *Compare to tail index381 bne serpt_2 *Jump if buffer not empty382 * 383 move.b d1,ACIA_TDR(a1) *Give byte to ACIA to send384 bra serpt_3 *Go deal with RTS/CTS if needed385 * 386 serpt_2: move.w obuftl(a0),d2 *Tail index to d2387 bsr wrapout *Adjust for wraparound388 cmp.w obufhd(a0),d2 *Compare to head index389 beq serpt_4 *Jump if buffer full390 * 391 move.l obuf(a0),a2 *Get buffer base address in a2392 move.b d1,0(a2,d2) *Put character in buffer393 move.w d2,obuftl(a0) *Update buffer tail index394 * 395 serpt_3: bsr serchk *Check status on our way out396 bsr rtschk *Handle RTS protocol397 move.w (a7)+,sr *RESTORE INTERRUPTS398 andi # $FFFE,sr *Clear carry flag = OK399 rts *Return to caller400 * 401 serpt_4: bsr serchk *Check status on our way out402 bsr rtschk *Handle RTS protocol403 move.w (a7)+,sr *RESTORE INTERRUPTS404 ori # $0001,sr *Set carry flag = buffer full405 rts *Return to caller406 * 407 .page 408 * 409 *midput -- Output to MIDI410 *------ --------------411 midput: move.w sr,-(a7) *Save status register412 ori.w #IPL7,sr *DISABLE INTERRUPTS413 move.b ACIA_ISR(a1),isr(a0) *Get ACIA isr414 move.b ACIA_CSR(a1),csr(a0) *Get ACIA csr415 btst.b #6,isr(a0) *Is ACIA still sending ?416 beq midpt_2 *Jump if so417 * 418 move.w obufhd(a0),d2 *Head index to d2419 cmp.w obuftl(a0),d2 *Compare to tail index420 bne midpt_2 *Jump if buffer not empty421 * 422 move.b d1,ACIA_TDR(a1) *Give byte to ACIA to send423 bra midpt_3 *Go set final status and exit424 * 425 midpt_2: move.w obuftl(a0),d2 *Tail index to d2426 bsr wrapout *Adjust for wraparound427 cmp.w obufhd(a0),d2 *Compare to head index428 beq midpt_4 *Jump if buffer full429 * 430 move.l obuf(a0),a2 *Get buffer base address in a2431 move.b d1,0(a2,d2) *Put character in buffer432 move.w d2,obuftl(a0) *Update buffer tail index433 * 434 midpt_3: bsr midchk *Check status on our way out435 move.w (a7)+,sr *RESTORE INTERRUPTS436 andi # $FFFE,sr *Clear carry flag = OK437 rts *Return to caller438 * 439 midpt_4: bsr midchk *Check status on our way out440 move.w (a7)+,sr *RESTORE INTERRUPTS441 ori # $0001,sr *Set carry flag = buffer full442 rts *Return to caller443 * 444 .page 445 * 446 *rtschk -- Check RTS mode and turn on RTS if it's enabled447 *------ ----------------------------------------------448 rtschk: btst #1,linedisc(a0) *RTS/CTS mode set ?449 beq rtsexit *Jump to exit if not450 * 451 *rtson -- Turn on RTS line452 *----- ----------------453 rtson: move.b cfr1(a0),d0 *Pick up CFR1 image454 bclr #0,d0 *Turn on RTS line (0 = on)455 bra rtscmn *Join common RTS code below456 * 457 *rtsoff -- Turn off RTS line458 *------ -----------------459 rtsoff: move.b cfr1(a0),d0 *Pick up CFR1 image460 bset #0,d0 *Turn off RTS line (1 = off)461 462 rtscmn: bset #7,d0 *Make sure MS bit is set463 move.b d0,cfr1(a0) *Update CFR1 image464 move.b d0,ACIA_CFR(a1) *Send CFR to hardware465 * 466 rtsexit: rts *Return to caller467 * 468 .page 469 * 470 *wrapin -- Check input pointer for wraparound471 *------ ----------------------------------472 wrapin: add.w #1,d1 *Head index +1473 cmp.w ibufsize(a0),d1 *= buffer size ?474 bcs wrapin1 *Jump if not475 * 476 moveq.l #0,d1 *Wraparound477 * 478 wrapin1: rts *Return to caller479 * 480 *wrapout -- Check output pointer for wraparound481 *------- -----------------------------------482 wrapout: addq.w #1,d2 *Tail index +1483 cmp.w obufsize(a0),d2 *= buffer size ?484 bcs wrapout1 *Jump if not485 * 486 moveq.l #0,d2 *Wrap around if so487 * 488 wrapout1: rts *Return to caller489 * 490 .page 491 * 492 *_setsio -- setsio() -- initialize serial I/O vectors and DCD interrupts493 *------- ------------------------------------------------------------494 _setsio: move.w sr,-(a7) *Preserve status register495 ori.w # $IPL7,sr *DISABLE INTERRUPTS496 * 497 lea nulsiox,a0 *Get null return address498 move.l a0,_foot1 *Initialize foot1 vector499 move.l a0,_foot2 *Initialize foot2 vector500 move.l a0,_pulse1 *Initialize pulse1 vector501 move.l a0,_pulse2 *Initialize pulse2 vector502 * 503 lea SR1ACIA,a1 *Point at Serial-1 ACIA504 move.b # $90,ACIA_IER(a1) *Enable DCD interrupts505 * 506 lea SR2ACIA,a1 *Point at Serial-2 ACIA507 move.b # $90,ACIA_IER(a1) *Enable DCD interrupts508 * 509 lea MC1ACIA,a1 *Point at MIDI-1 ACIA510 move.b # $90,ACIA_IER(a1) *Enable DCD interrupts511 * 512 lea MC2ACIA,a1 *Point at MIDI-2 ACIA513 move.b # $90,ACIA_IER(a1) *Enable DCD interrupts514 * 515 lea serintr,a0 *Initialize interrupt vector516 move.l a0,SERVECT *... in processor RAM517 * 518 move.w (a7)+,sr *RESTORE INTERRUPTS519 * 520 nulsiox: rts *Return to caller521 * 330 331 | Handle receiver interrupt 332 333 midrx: move.b ACIA_RDR(a1),d0 | Read data from ACIA 334 move.w ibuftl(a0),d1 | Get tail index in d1 335 bsr wrapin | Adjust for wraparound 336 cmp.w ibufhd(a0),d1 | Head = tail ? 337 beq midibf | If so, we drop the character 338 339 move.l ibuf(a0),a2 | Get buffer address 340 move.b d0,0(a2,d1) | Stash byte in buffer 341 move.w d1,ibuftl(a0) | Save updated tail index 342 bra midtxq | Done (go check tx int) 343 344 .page 345 346 | Handle transmitter interrupt 347 348 midtx: move.w obufhd(a0),d2 | Head index to d2 349 cmp.w obuftl(a0),d2 | Compare to tail index 350 beq midintx | Done if buffer empty 351 352 bsr wrapout | Adjust pointer for wraparound 353 move.l obuf(a0),a2 | Get buffer base address 354 move.b 0(a2,d2),ACIA_TDR(a1) | Send byte on its way 355 move.w d2,obufhd(a0) | Save updated head index 356 bra midintx | Done 357 358 midibf: move.b d0,erbyte(a0) | Log dropped character 359 addq.w #1,ibfct(a0) | ... 360 bra midtxq | Go check Tx interrupt 361 362 .page 363 364 | serput -- Output a character to a serial port 365 | ------ ----------------------------------- 366 serput: move.w sr,-(a7) | Save status register 367 ori.w #IPL7,sr | DISABLE INTERRUPTS 368 move.b ACIA_ISR(a1),isr(a0) | Get ACIA isr 369 move.b ACIA_CSR(a1),csr(a0) | Get ACIA csr 370 btst #0,linedisc(a0) | XON/XOFF mode ? 371 beq serpt_1 | Jump if not 372 373 tst.b flagxoff(a0) | XON active ? 374 bne serpt_2 | Jump if so 375 376 serpt_1: btst.b #6,isr(a0) | Is ACIA still sending ? 377 beq serpt_2 | Jump if so 378 379 move.w obufhd(a0),d2 | Head index to d2 380 cmp.w obuftl(a0),d2 | Compare to tail index 381 bne serpt_2 | Jump if buffer not empty 382 383 move.b d1,ACIA_TDR(a1) | Give byte to ACIA to send 384 bra serpt_3 | Go deal with RTS/CTS if needed 385 386 serpt_2: move.w obuftl(a0),d2 | Tail index to d2 387 bsr wrapout | Adjust for wraparound 388 cmp.w obufhd(a0),d2 | Compare to head index 389 beq serpt_4 | Jump if buffer full 390 391 move.l obuf(a0),a2 | Get buffer base address in a2 392 move.b d1,0(a2,d2) | Put character in buffer 393 move.w d2,obuftl(a0) | Update buffer tail index 394 395 serpt_3: bsr serchk | Check status on our way out 396 bsr rtschk | Handle RTS protocol 397 move.w (a7)+,sr | RESTORE INTERRUPTS 398 andi #0xFFFE,sr | Clear carry flag = OK 399 rts | Return to caller 400 401 serpt_4: bsr serchk | Check status on our way out 402 bsr rtschk | Handle RTS protocol 403 move.w (a7)+,sr | RESTORE INTERRUPTS 404 ori #0x0001,sr | Set carry flag = buffer full 405 rts | Return to caller 406 407 .page 408 409 | midput -- Output to MIDI 410 | ------ -------------- 411 midput: move.w sr,-(a7) | Save status register 412 ori.w #IPL7,sr | DISABLE INTERRUPTS 413 move.b ACIA_ISR(a1),isr(a0) | Get ACIA isr 414 move.b ACIA_CSR(a1),csr(a0) | Get ACIA csr 415 btst.b #6,isr(a0) | Is ACIA still sending ? 416 beq midpt_2 | Jump if so 417 418 move.w obufhd(a0),d2 | Head index to d2 419 cmp.w obuftl(a0),d2 | Compare to tail index 420 bne midpt_2 | Jump if buffer not empty 421 422 move.b d1,ACIA_TDR(a1) | Give byte to ACIA to send 423 bra midpt_3 | Go set final status and exit 424 425 midpt_2: move.w obuftl(a0),d2 | Tail index to d2 426 bsr wrapout | Adjust for wraparound 427 cmp.w obufhd(a0),d2 | Compare to head index 428 beq midpt_4 | Jump if buffer full 429 430 move.l obuf(a0),a2 | Get buffer base address in a2 431 move.b d1,0(a2,d2) | Put character in buffer 432 move.w d2,obuftl(a0) | Update buffer tail index 433 434 midpt_3: bsr midchk | Check status on our way out 435 move.w (a7)+,sr | RESTORE INTERRUPTS 436 andi #0xFFFE,sr | Clear carry flag = OK 437 rts | Return to caller 438 439 midpt_4: bsr midchk | Check status on our way out 440 move.w (a7)+,sr | RESTORE INTERRUPTS 441 ori #0x0001,sr | Set carry flag = buffer full 442 rts | Return to caller 443 444 .page 445 446 | rtschk -- Check RTS mode and turn on RTS if it's enabled 447 | ------ ---------------------------------------------- 448 rtschk: btst #1,linedisc(a0) | RTS/CTS mode set ? 449 beq rtsexit | Jump to exit if not 450 451 | rtson -- Turn on RTS line 452 | ----- ---------------- 453 rtson: move.b cfr1(a0),d0 | Pick up CFR1 image 454 bclr #0,d0 | Turn on RTS line (0 = on) 455 bra rtscmn | Join common RTS code below 456 457 | rtsoff -- Turn off RTS line 458 | ------ ----------------- 459 rtsoff: move.b cfr1(a0),d0 | Pick up CFR1 image 460 bset #0,d0 | Turn off RTS line (1 = off) 461 462 rtscmn: bset #7,d0 | Make sure MS bit is set 463 move.b d0,cfr1(a0) | Update CFR1 image 464 move.b d0,ACIA_CFR(a1) | Send CFR to hardware 465 466 rtsexit: rts | Return to caller 467 468 .page 469 470 | wrapin -- Check input pointer for wraparound 471 | ------ ---------------------------------- 472 wrapin: add.w #1,d1 | Head index +1 473 cmp.w ibufsize(a0),d1 | = buffer size ? 474 bcs wrapin1 | Jump if not 475 476 moveq.l #0,d1 | Wraparound 477 478 wrapin1: rts | Return to caller 479 480 | wrapout -- Check output pointer for wraparound 481 | ------- ----------------------------------- 482 wrapout: addq.w #1,d2 | Tail index +1 483 cmp.w obufsize(a0),d2 | = buffer size ? 484 bcs wrapout1 | Jump if not 485 486 moveq.l #0,d2 | Wrap around if so 487 488 wrapout1: rts | Return to caller 489 490 .page 491 492 | _setsio -- setsio() -- initialize serial I/O vectors and DCD interrupts 493 | ------- ------------------------------------------------------------ 494 _setsio: move.w sr,-(a7) | Preserve status register 495 ori.w #IPL7,sr | DISABLE INTERRUPTS 496 497 lea nulsiox,a0 | Get null return address 498 move.l a0,_foot1 | Initialize foot1 vector 499 move.l a0,_foot2 | Initialize foot2 vector 500 move.l a0,_pulse1 | Initialize pulse1 vector 501 move.l a0,_pulse2 | Initialize pulse2 vector 502 503 lea SR1ACIA,a1 | Point at Serial-1 ACIA 504 move.b #0x90,ACIA_IER(a1) | Enable DCD interrupts 505 506 lea SR2ACIA,a1 | Point at Serial-2 ACIA 507 move.b #0x90,ACIA_IER(a1) | Enable DCD interrupts 508 509 lea MC1ACIA,a1 | Point at MIDI-1 ACIA 510 move.b #0x90,ACIA_IER(a1) | Enable DCD interrupts 511 512 lea MC2ACIA,a1 | Point at MIDI-2 ACIA 513 move.b #0x90,ACIA_IER(a1) | Enable DCD interrupts 514 515 lea serintr,a0 | Initialize interrupt vector 516 move.l a0,SERVECT | ... in processor RAM 517 518 move.w (a7)+,sr | RESTORE INTERRUPTS 519 520 nulsiox: rts | Return to caller 521 522 522 .bss 523 * 524 *DCD interrupt processor vectors525 *-------------------------------526 _foot1: .ds.l 1 * short (*foot1)();527 _foot2: .ds.l 1 * short (*foot2)();528 _pulse1: .ds.l 1 * short (*pulse1)();529 _pulse2: .ds.l 1 * short (*pulse2)();530 * 523 524 | DCD interrupt processor vectors 525 | ------------------------------- 526 _foot1: .ds.l 1 | short (|foot1)(); 527 _foot2: .ds.l 1 | short (|foot2)(); 528 _pulse1: .ds.l 1 | short (|pulse1)(); 529 _pulse2: .ds.l 1 | short (|pulse2)(); 530 531 531 .end -
ram/sreset.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *sreset.s -- reset score highlighting3 *Version 14 -- 1988-07-28 -- D.N. Lynx Crowe4 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | sreset.s -- reset score highlighting 3 | Version 14 -- 1988-07-28 -- D.N. Lynx Crowe 4 | ------------------------------------------------------------------------------ 5 5 .text 6 * 7 .xdef _sreset *sreset()8 * 9 .xref _vputa *vputa(sbase, row, col, attrib)10 * 11 .xref _ndisp *WORD - display number12 .xref _obj8 *LONG - object base address13 .xref _vrbw08 *WORD - detail word for bit 814 .xref _vrbw09 *WORD - detail word for bit 915 .xref _vrbw10 *WORD - detail word for bit 1016 .xref _vrbw11 *WORD - detail word for bit 1117 .xref _vrbw12 *WORD - detail word for bit 1218 .xref _vrbw13 *WORD - detail word for bit 1319 .xref _vrbw14 *WORD - detail word for bit 1420 .xref _vrbw15 *WORD - detail word for bit 1521 .xref _vrcw *WORD - video reset control word22 * 23 ROW .equ424 COL .equ625 ATR .equ826 * 27 AT01 .equ $001428 AT04 .equ $001329 AT05 .equ $001430 AT06 .equ $001331 AT07 .equ $001432 AT08 .equ $001333 AT09 .equ $001434 AT10 .equ $001335 AT11 .equ $001236 AT12 .equ $001237 * 38 .page 39 * 40 *sreset() -- reset highlighting41 *-------- ------------------42 _sreset: link a6,#0 *link stack frame43 cmp.w #2,_ndisp *see if we should update display44 bne srsexit *jump if not45 * 46 move.w _vrcw,d0 *get and check vrcw47 bne srs0 *jump if something to do48 * 49 srsexit: unlk a6 *unlink stack frame50 rts *return to caller51 * 52 srs0: move.w sr,d1 *<<<<< disable interrupts >>>>>53 ori.w # $0700,sr *...54 * 55 move.w _vrcw,vrcw *make local copies of control variables56 clr.w _vrcw *... and clear them for the next pass57 move.w _vrbw08,vrbw08 *...58 clr.w _vrbw08 *...59 move.w _vrbw09,vrbw09 *...60 clr.w _vrbw09 *...61 move.w _vrbw10,vrbw10 *...62 clr.w _vrbw10 *...63 move.w _vrbw11,vrbw11 *...64 clr.w _vrbw11 *...65 move.w _vrbw12,vrbw12 *...66 clr.w _vrbw12 *...67 move.w _vrbw13,vrbw13 *...68 clr.w _vrbw13 *...69 move.w _vrbw14,vrbw14 *...70 clr.w _vrbw14 *...71 move.w _vrbw15,vrbw15 *...72 clr.w _vrbw15 *...73 * 74 move.w d1,sr *<<<<< restore interrupts >>>>>75 * 76 *Setup STACK for subsequent calls to vputa(sbase, row, col, atr):77 * 78 *0(a7) sbase79 * 80 *4(a7) row ROW81 *6(a7) col COL82 *8(a7) atr ATR83 * 84 clr.w -(a7) *put dummy attribute on stack85 clr.w -(a7) *put dummy column on stack86 clr.w -(a7) *put dummy row on stack87 move.l _obj8,-(a7) *put sbase on stack88 * 89 .page 90 * 91 *assignment92 *----------93 btst #0,d0 *assignment ?94 beq srs1 *jump if not95 * 96 move.w #AT04,ATR(a7) *put attribute on stack97 move.w #1,ROW(a7) *put row on stack98 move.w #11,COL(a7) *put 1st column on stack99 jsr _vputa *reset first column100 move.w #12,COL(a7) *put 2nd column on stack101 jsr _vputa *reset second column102 move.w vrcw,d0 *restore vrcw to d0103 * 104 *tuning105 *------106 srs1: btst #1,d0 *tuning ?107 beq srs2 *jump if not108 * 109 move.w #AT05,ATR(a7) *put attribute on stack110 move.w #1,ROW(a7) *put row on stack111 move.w #19,COL(a7) *put column on stack112 jsr _vputa *reset column113 move.w vrcw,d0 *restore vrcw to d0114 * 115 *tempo116 *-----117 srs2: btst #2,d0 *tempo ?118 beq srs3 *jump if not119 * 120 move.w #AT06,ATR(a7) *put attribute on stack121 move.w #1,ROW(a7) *put row on stack122 move.w #27,COL(a7) *put 1st column on stack123 jsr _vputa *reset first column124 move.w #28,COL(a7) *put 2nd column on stack125 jsr _vputa *reset second column126 move.w #29,COL(a7) *put 3rd column on stack127 jsr _vputa *reset third column128 move.w vrcw,d0 *restore vrcw to d0129 * 130 .page 131 * 132 *interpolate133 *-----------134 srs3: btst #3,d0 *interpolate ?135 beq srs4 *jump if not136 * 137 move.w #AT07,ATR(a7) *put attribute on stack138 move.w #1,ROW(a7) *put row on stack139 move.w #35,COL(a7) *put 1st column on stack140 jsr _vputa *reset first column141 move.w #36,COL(a7) *put 2nd column on stack142 jsr _vputa *reset second column143 move.w #37,COL(a7) *put 3rd column on stack144 jsr _vputa *reset third column145 move.w #38,COL(a7) *put 4th column on stack146 jsr _vputa *reset fourth column147 move.w vrcw,d0 *restore vrcw to d0148 * 149 *section begin150 *-------------151 srs4: btst #4,d0 *section begin ?152 beq srs5 *jump if not153 * 154 move.w #AT01,ATR(a7) *put attribute on stack155 move.w #0,ROW(a7) *put row on stack156 move.w #6,COL(a7) *put 1st column on stack157 jsr _vputa *reset first column158 move.w #7,COL(a7) *put 2nd column on stack159 jsr _vputa *reset second column160 * 161 .page 162 * 163 *punch in164 *--------165 srs5: btst #5,d0 *punch in ?166 beq srs6 *jump if not167 * 168 move.w #AT09,ATR(a7) *put attribute on stack169 move.w #1,ROW(a7) *put row on stack170 move.w #50,COL(a7) *put 1st column on stack171 jsr _vputa *reset first column172 move.w #51,COL(a7) *put 2nd column on stack173 jsr _vputa *reset second column174 move.w vrcw,d0 *restore vrcw to d0175 * 176 *punch out177 *---------178 srs6: btst #6,d0 *punch out ?179 beq srs7 *jump if not180 * 181 move.w #AT09,ATR(a7) *put attribute on stack182 move.w #1,ROW(a7) *put row on stack183 move.w #53,COL(a7) *put 1st column on stack184 jsr _vputa *reset first column185 move.w #54,COL(a7) *put 2nd column on stack186 jsr _vputa *reset second column187 move.w #55,COL(a7) *put 3rd column on stack188 jsr _vputa *reset third column189 move.w vrcw,d0 *restore vrcw to d0190 * 191 *Output192 *------193 srs7: btst #7,d0 *output ?194 beq srs8 *jump if not195 * 196 move.w #AT10,ATR(a7) *put attribute on stack197 move.w #1,ROW(a7) *put row on stack198 move.w #57,COL(a7) *put 1st column on stack199 jsr _vputa *reset first column200 move.w #58,COL(a7) *put 2nd column on stack201 jsr _vputa *reset second column202 move.w #59,COL(a7) *put 3rd column on stack203 jsr _vputa *reset third column204 move.w #60,COL(a7) *put 4th column on stack205 jsr _vputa *reset fourth column206 move.w #61,COL(a7) *put 5th column on stack207 jsr _vputa *reset fifth column208 move.w #62,COL(a7) *put 6th column on stack209 jsr _vputa *reset sixth column210 move.w vrcw,d0 *restore vrcw to d0211 * 212 .page 213 * 214 *instrument215 *----------216 srs8: btst #8,d0 *instrument ?217 beq srs9 *jump if not218 * 219 move.w #2,ROW(a7) *put row on stack220 move.w #AT11,ATR(a7) *put attribute on stack221 btst #0,vrbw08+1 *group 1 ?222 beq srs8a *jump if not223 * 224 move.w #7,COL(a7) *put 1st column on stack225 jsr _vputa *reset first column226 move.w #8,COL(a7) *put 2nd column on stack227 jsr _vputa *reset second column228 * 229 srs8a: btst #1,vrbw08+1 *group 2 ?230 beq srs8b *jump if not231 * 232 move.w #12,COL(a7) *put 1st column on stack233 jsr _vputa *reset first character234 move.w #13,COL(a7) *put 2nd column on stack235 jsr _vputa *reset second character236 * 237 srs8b: btst #2,vrbw08+1 *group 3 ?238 beq srs8c *jump if not239 * 240 move.w #17,COL(a7) *put 1st column on stack241 jsr _vputa *reset first character242 move.w #18,COL(a7) *put 2nd column on stack243 jsr _vputa *reset second character244 * 245 srs8c: btst #3,vrbw08+1 *group 4 ?246 beq srs8d *jump if not247 * 248 move.w #22,COL(a7) *put 1st column on stack249 jsr _vputa *reset first character250 move.w #23,COL(a7) *put 2nd column on stack251 jsr _vputa *reset second character252 * 253 .page 254 * 255 srs8d: btst #4,vrbw08+1 *group 5 ?256 beq srs8e *jump if not257 * 258 move.w #27,COL(a7) *put 1st column on stack259 jsr _vputa *reset first character260 move.w #28,COL(a7) *put 2nd column on stack261 jsr _vputa *reset second character262 * 263 srs8e: btst #5,vrbw08+1 *group 6 ?264 beq srs8f *jump if not265 * 266 move.w #32,COL(a7) *put 1st column on stack267 jsr _vputa *reset first character268 move.w #33,COL(a7) *put 2nd column on stack269 jsr _vputa *reset second character270 * 271 srs8f: btst #6,vrbw08+1 *group 7 ?272 beq srs8g *jump if not273 * 274 move.w #37,COL(a7) *put 1st column on stack275 jsr _vputa *reset first character276 move.w #38,COL(a7) *put 2nd column on stack277 jsr _vputa *reset second character278 * 279 srs8g: btst #7,vrbw08+1 *group 8 ?280 beq srs8h *jump if not281 * 282 move.w #42,COL(a7) *put 1st column on stack283 jsr _vputa *reset first character284 move.w #43,COL(a7) *put 2nd column on stack285 jsr _vputa *reset second character286 * 287 .page 288 * 289 srs8h: btst #0,vrbw08 *group 9290 beq srs8j *jump if not291 * 292 move.w #47,COL(a7) *put 1st column on stack293 jsr _vputa *reset first character294 move.w #48,COL(a7) *put 2nd column on stack295 jsr _vputa *reset second character296 * 297 srs8j: btst #1,vrbw08 *group 10298 beq srs8k *jump if not299 * 300 move.w #52,COL(a7) *put 1st column on stack301 jsr _vputa *reset first character302 move.w #53,COL(a7) *put 2nd column on stack303 jsr _vputa *reset second character304 * 305 srs8k: btst #2,vrbw08 *group 11306 beq srs8m *jump if not307 * 308 move.w #57,COL(a7) *put 1st column on stack309 jsr _vputa *reset first character310 move.w #58,COL(a7) *put 2nd column on stack311 jsr _vputa *reset second character312 * 313 srs8m: btst #3,vrbw08 *group 12314 beq srs8x *jump if not315 * 316 move.w #62,COL(a7) *put 1st column on stack317 jsr _vputa *reset first character318 move.w #63,COL(a7) *put 2nd column on stack319 jsr _vputa *reset second character320 * 321 srs8x: move.w vrcw,d0 *restore vrcw to d0322 * 323 .page 324 * 325 *transpose326 *---------327 srs9: btst #9,d0 *transpose ?328 beq srs10 *jump if not329 * 330 move.w #AT11,ATR(a7) *put attribute on stack331 move.w #3,ROW(a7) *put row on stack332 btst #0,vrbw09+1 *group 1 ?333 beq srs9a *jump if not334 * 335 move.w #5,COL(a7) *put 1st column on stack336 jsr _vputa *reset first column337 move.w #6,COL(a7) *put 2nd column on stack338 jsr _vputa *reset second column339 move.w #7,COL(a7) *put 3rd column on stack340 jsr _vputa *reset third column341 move.w #8,COL(a7) *put 4th column on stack342 jsr _vputa *reset fourth column343 * 344 srs9a: btst #1,vrbw09+1 *group 2 ?345 beq srs9b *jump if not346 * 347 move.w #10,COL(a7) *put 1st column on stack348 jsr _vputa *reset first column349 move.w #11,COL(a7) *put 2nd column on stack350 jsr _vputa *reset second column351 move.w #12,COL(a7) *put 3rd column on stack352 jsr _vputa *reset third column353 move.w #13,COL(a7) *put 4th column on stack354 jsr _vputa *reset fourth column355 * 356 srs9b: btst #2,vrbw09+1 *group 3 ?357 beq srs9c *jump if not358 * 359 move.w #15,COL(a7) *put 1st column on stack360 jsr _vputa *reset first column361 move.w #16,COL(a7) *put 2nd column on stack362 jsr _vputa *reset second column363 move.w #17,COL(a7) *put 3rd column on stack364 jsr _vputa *reset third column365 move.w #18,COL(a7) *put 4th column on stack366 jsr _vputa *reset fourth column367 * 368 .page 369 * 370 srs9c: btst #3,vrbw09+1 *group 4 ?371 beq srs9d *jump if not372 * 373 move.w #20,COL(a7) *put 1st column on stack374 jsr _vputa *reset first column375 move.w #21,COL(a7) *put 2nd column on stack376 jsr _vputa *reset second column377 move.w #22,COL(a7) *put 3rd column on stack378 jsr _vputa *reset third column379 move.w #23,COL(a7) *put 4th column on stack380 jsr _vputa *reset fourth column381 * 382 srs9d: btst #4,vrbw09+1 *group 5 ?383 beq srs9e *jump if not384 * 385 move.w #25,COL(a7) *put 1st column on stack386 jsr _vputa *reset first column387 move.w #26,COL(a7) *put 2nd column on stack388 jsr _vputa *reset second column389 move.w #27,COL(a7) *put 3rd column on stack390 jsr _vputa *reset third column391 move.w #28,COL(a7) *put 4th column on stack392 jsr _vputa *reset fourth column393 * 394 srs9e: btst #5,vrbw09+1 *group 6 ?395 beq srs9f *jump if not396 * 397 move.w #30,COL(a7) *put 1st column on stack398 jsr _vputa *reset first column399 move.w #31,COL(a7) *put 2nd column on stack400 jsr _vputa *reset second column401 move.w #32,COL(a7) *put 3rd column on stack402 jsr _vputa *reset third column403 move.w #33,COL(a7) *put 4th column on stack404 jsr _vputa *reset fourth column405 * 406 .page 407 * 408 srs9f: btst #6,vrbw09+1 *group 7 ?409 beq srs9g *jump if not410 * 411 move.w #35,COL(a7) *put 1st column on stack412 jsr _vputa *reset first column413 move.w #36,COL(a7) *put 2nd column on stack414 jsr _vputa *reset second column415 move.w #37,COL(a7) *put 3rd column on stack416 jsr _vputa *reset third column417 move.w #38,COL(a7) *put 4th column on stack418 jsr _vputa *reset fourth column419 * 420 srs9g: btst #7,vrbw09+1 *group 8 ?421 beq srs9h *jump if not422 * 423 move.w #40,COL(a7) *put 1st column on stack424 jsr _vputa *reset first column425 move.w #41,COL(a7) *put 2nd column on stack426 jsr _vputa *reset second column427 move.w #42,COL(a7) *put 3rd column on stack428 jsr _vputa *reset third column429 move.w #43,COL(a7) *put 4th column on stack430 jsr _vputa *reset fourth column431 * 432 srs9h: btst #0,vrbw09 *group 9433 beq srs9j *jump if not434 * 435 move.w #45,COL(a7) *put 1st column on stack436 jsr _vputa *reset first column437 move.w #46,COL(a7) *put 2nd column on stack438 jsr _vputa *reset second column439 move.w #47,COL(a7) *put 3rd column on stack440 jsr _vputa *reset third column441 move.w #48,COL(a7) *put 4th column on stack442 jsr _vputa *reset fourth column443 * 444 .page 445 * 446 srs9j: btst #1,vrbw09 *group 10447 beq srs9k *jump if not448 * 449 move.w #50,COL(a7) *put 1st column on stack450 jsr _vputa *reset first column451 move.w #51,COL(a7) *put 2nd column on stack452 jsr _vputa *reset second column453 move.w #52,COL(a7) *put 3rd column on stack454 jsr _vputa *reset third column455 move.w #53,COL(a7) *put 4th column on stack456 jsr _vputa *reset fourth column457 * 458 srs9k: btst #2,vrbw09 *group 11459 beq srs9m *jump if not460 * 461 move.w #55,COL(a7) *put 1st column on stack462 jsr _vputa *reset first column463 move.w #56,COL(a7) *put 2nd column on stack464 jsr _vputa *reset second column465 move.w #57,COL(a7) *put 3rd column on stack466 jsr _vputa *reset third column467 move.w #58,COL(a7) *put 4th column on stack468 jsr _vputa *reset fourth column469 * 470 srs9m: btst #3,vrbw09 *group 12471 beq srs9x *jump if not472 * 473 move.w #60,COL(a7) *put 1st column on stack474 jsr _vputa *reset first column475 move.w #61,COL(a7) *put 2nd column on stack476 jsr _vputa *reset second column477 move.w #62,COL(a7) *put 3rd column on stack478 jsr _vputa *reset third column479 move.w #63,COL(a7) *put 4th column on stack480 jsr _vputa *reset fourth column481 * 482 srs9x: move.w vrcw,d0 *restore vrcw to d0483 * 484 .page 485 * 486 *dynamics487 *--------488 srs10: btst #10,d0 *dynamics ?489 beq srs11 *jump if not490 * 491 move.w #AT11,ATR(a7) *put attribute on stack492 move.w #4,ROW(a7) *put row on stack493 btst #0,vrbw10+1 *group 1 ?494 beq srs10a *jump if not495 * 496 move.w #6,COL(a7) *put column on stack497 jsr _vputa *reset column498 * 499 srs10a: btst #1,vrbw10+1 *group 2 ?500 beq srs10b *jump if not501 * 502 move.w #11,COL(a7) *put column on stack503 jsr _vputa *reset column504 * 505 srs10b: btst #2,vrbw10+1 *group 3 ?506 beq srs10c *jump if not507 * 508 move.w #16,COL(a7) *put column on stack509 jsr _vputa *reset column510 * 511 srs10c: btst #3,vrbw10+1 *group 4 ?512 beq srs10d *jump if not513 * 514 move.w #21,COL(a7) *put column on stack515 jsr _vputa *reset column516 * 517 .page 518 * 519 srs10d: btst #4,vrbw10+1 *group 5 ?520 beq srs10e *jump if not521 * 522 move.w #26,COL(a7) *put column on stack523 jsr _vputa *reset column524 * 525 srs10e: btst #5,vrbw10+1 *group 6 ?526 beq srs10f *jump if not527 * 528 move.w #31,COL(a7) *put column on stack529 jsr _vputa *reset column530 * 531 srs10f: btst #6,vrbw10+1 *group 7 ?532 beq srs10g *jump if not533 * 534 move.w #36,COL(a7) *put column on stack535 jsr _vputa *reset column536 * 537 srs10g: btst #7,vrbw10+1 *group 8 ?538 beq srs10h *jump if not539 * 540 move.w #41,COL(a7) *put column on stack541 jsr _vputa *reset column542 * 543 .page 544 * 545 srs10h: btst #0,vrbw10 *group 9546 beq srs10j *jump if not547 * 548 move.w #46,COL(a7) *put column on stack549 jsr _vputa *reset column550 * 551 srs10j: btst #1,vrbw10 *group 10552 beq srs10k *jump if not553 * 554 move.w #51,COL(a7) *put column on stack555 jsr _vputa *reset column556 * 557 srs10k: btst #2,vrbw10 *group 11558 beq srs10m *jump if not559 * 560 move.w #56,COL(a7) *put column on stack561 jsr _vputa *reset column562 * 563 srs10m: btst #3,vrbw10 *group 12564 beq srs10x *jump if not565 * 566 move.w #61,COL(a7) *put column on stack567 jsr _vputa *reset column568 * 569 srs10x: move.w vrcw,d0 *restore vrcw to d0570 * 571 .page 572 * 573 *location574 *--------575 srs11: btst #11,d0 *location ?576 beq srs12 *jump if not577 * 578 move.w #AT11,ATR(a7) *put attribute on stack579 move.w #4,ROW(a7) *put row on stack580 btst #0,vrbw11+1 *group 1 ?581 beq srs11a *jump if not582 * 583 move.w #8,COL(a7) *put column on stack584 jsr _vputa *reset column585 * 586 srs11a: btst #1,vrbw11+1 *group 2 ?587 beq srs11b *jump if not588 * 589 move.w #13,COL(a7) *put column on stack590 jsr _vputa *reset column591 * 592 srs11b: btst #2,vrbw11+1 *group 3 ?593 beq srs11c *jump if not594 * 595 move.w #18,COL(a7) *put column on stack596 jsr _vputa *reset column597 * 598 srs11c: btst #3,vrbw11+1 *group 4 ?599 beq srs11d *jump if not600 * 601 move.w #23,COL(a7) *put column on stack602 jsr _vputa *reset column603 * 604 .page 605 * 606 srs11d: btst #4,vrbw11+1 *group 5 ?607 beq srs11e *jump if not608 * 609 move.w #28,COL(a7) *put column on stack610 jsr _vputa *reset column611 * 612 srs11e: btst #5,vrbw11+1 *group 6 ?613 beq srs11f *jump if not614 * 615 move.w #33,COL(a7) *put column on stack616 jsr _vputa *reset column617 * 618 srs11f: btst #6,vrbw11+1 *group 7 ?619 beq srs11g *jump if not620 * 621 move.w #38,COL(a7) *put column on stack622 jsr _vputa *reset column623 * 624 srs11g: btst #7,vrbw11+1 *group 8 ?625 beq srs11h *jump if not626 * 627 move.w #43,COL(a7) *put column on stack628 jsr _vputa *reset column629 * 630 .page 631 * 632 srs11h: btst #0,vrbw11 *group 9633 beq srs11j *jump if not634 * 635 move.w #48,COL(a7) *put column on stack636 jsr _vputa *reset column637 * 638 srs11j: btst #1,vrbw11 *group 10639 beq srs11k *jump if not640 * 641 move.w #53,COL(a7) *put column on stack642 jsr _vputa *reset column643 * 644 srs11k: btst #2,vrbw11 *group 11645 beq srs11m *jump if not646 * 647 move.w #58,COL(a7) *put column on stack648 jsr _vputa *reset column649 * 650 srs11m: btst #3,vrbw11 *group 12651 beq srs11x *jump if not652 * 653 move.w #63,COL(a7) *put column on stack654 jsr _vputa *reset column655 * 656 srs11x: move.w vrcw,d0 *restore vrcw to d0657 * 658 .page 659 * 660 *velocity661 *--------662 srs12: btst #12,d0 *velocity ?663 beq srs13 *jump if not664 * 665 move.w #AT11,ATR(a7) *put attribute on stack666 move.w #5,ROW(a7) *put row on stack667 btst #0,vrbw12+1 *group 1 ?668 beq srs12a *jump if not669 * 670 move.w #6,COL(a7) *put 1st column on stack671 jsr _vputa *reset first column672 move.w #7,COL(a7) *put 2nd column on stack673 jsr _vputa *reset second column674 move.w #8,COL(a7) *put 3rd column on stack675 jsr _vputa *reset third column676 * 677 srs12a: btst #1,vrbw12+1 *group 2 ?678 beq srs12b *jump if not679 * 680 move.w #11,COL(a7) *put 1st column on stack681 jsr _vputa *reset first column682 move.w #12,COL(a7) *put 2nd column on stack683 jsr _vputa *reset second column684 move.w #13,COL(a7) *put 3rd column on stack685 jsr _vputa *reset third column686 * 687 srs12b: btst #2,vrbw12+1 *group 3 ?688 beq srs12c *jump if not689 * 690 move.w #16,COL(a7) *put 1st column on stack691 jsr _vputa *reset first column692 move.w #17,COL(a7) *put 2nd column on stack693 jsr _vputa *reset second column694 move.w #18,COL(a7) *put 3rd column on stack695 jsr _vputa *reset third column696 * 697 .page 698 * 699 srs12c: btst #3,vrbw12+1 *group 4 ?700 beq srs12d *jump if not701 * 702 move.w #21,COL(a7) *put 1st column on stack703 jsr _vputa *reset first column704 move.w #22,COL(a7) *put 2nd column on stack705 jsr _vputa *reset second column706 move.w #23,COL(a7) *put 3rd column on stack707 jsr _vputa *reset third column708 * 709 srs12d: btst #4,vrbw12+1 *group 5 ?710 beq srs12e *jump if not711 * 712 move.w #26,COL(a7) *put 1st column on stack713 jsr _vputa *reset first column714 move.w #27,COL(a7) *put 2nd column on stack715 jsr _vputa *reset second column716 move.w #28,COL(a7) *put 3rd column on stack717 jsr _vputa *reset third column718 * 719 srs12e: btst #5,vrbw12+1 *group 6 ?720 beq srs12f *jump if not721 * 722 move.w #31,COL(a7) *put 1st column on stack723 jsr _vputa *reset first column724 move.w #32,COL(a7) *put 2nd column on stack725 jsr _vputa *reset second column726 move.w #33,COL(a7) *put 3rd column on stack727 jsr _vputa *reset third column728 * 729 .page 730 * 731 srs12f: btst #6,vrbw12+1 *group 7 ?732 beq srs12g *jump if not733 * 734 move.w #36,COL(a7) *put 1st column on stack735 jsr _vputa *reset first column736 move.w #37,COL(a7) *put 2nd column on stack737 jsr _vputa *reset second column738 move.w #38,COL(a7) *put 3rd column on stack739 jsr _vputa *reset third column740 * 741 srs12g: btst #7,vrbw12+1 *group 8 ?742 beq srs12h *jump if not743 * 744 move.w #41,COL(a7) *put 1st column on stack745 jsr _vputa *reset first column746 move.w #42,COL(a7) *put 2nd column on stack747 jsr _vputa *reset second column748 move.w #43,COL(a7) *put 3rd column on stack749 jsr _vputa *reset third column750 * 751 srs12h: btst #0,vrbw12 *group 9752 beq srs12j *jump if not753 * 754 move.w #46,COL(a7) *put 1st column on stack755 jsr _vputa *reset first column756 move.w #47,COL(a7) *put 2nd column on stack757 jsr _vputa *reset second column758 move.w #48,COL(a7) *put 3rd column on stack759 jsr _vputa *reset third column760 * 761 .page 762 * 763 srs12j: btst #1,vrbw12 *group 10764 beq srs12k *jump if not765 * 766 move.w #51,COL(a7) *put 1st column on stack767 jsr _vputa *reset first column768 move.w #52,COL(a7) *put 2nd column on stack769 jsr _vputa *reset second column770 move.w #53,COL(a7) *put 3rd column on stack771 jsr _vputa *reset third column772 * 773 srs12k: btst #2,vrbw12 *group 11774 beq srs12m *jump if not775 * 776 move.w #56,COL(a7) *put 1st column on stack777 jsr _vputa *reset first column778 move.w #57,COL(a7) *put 2nd column on stack779 jsr _vputa *reset second column780 move.w #58,COL(a7) *put 3rd column on stack781 jsr _vputa *reset third column782 * 783 srs12m: btst #3,vrbw12 *group 12784 beq srs12x *jump if not785 * 786 move.w #61,COL(a7) *put 1st column on stack787 jsr _vputa *reset first column788 move.w #62,COL(a7) *put 2nd column on stack789 jsr _vputa *reset second column790 move.w #63,COL(a7) *put 3rd column on stack791 jsr _vputa *reset third column792 * 793 srs12x: move.w vrcw,d0 *restore vrcw to d0794 * 795 .page 796 * 797 *resolution798 *----------799 srs13: btst #13,d0 *resolution ?800 beq srs14 *jump if not801 * 802 move.w #AT12,ATR(a7) *put attribute on stack803 move.w #7,ROW(a7) *put row on stack804 btst #0,vrbw13+1 *variable 1 ?805 beq srs13a *jump if not806 * 807 move.w #6,COL(a7) *put column on stack808 jsr _vputa *reset column809 * 810 srs13a: btst #1,vrbw13+1 *variable 2 ?811 beq srs13b *jump if not812 * 813 move.w #15,COL(a7) *put column on stack814 jsr _vputa *reset column815 * 816 srs13b: btst #2,vrbw13+1 *variable 3 ?817 beq srs13c *jump if not818 * 819 move.w #24,COL(a7) *put column on stack820 jsr _vputa *reset column821 * 822 srs13c: btst #3,vrbw13+1 *variable 4 ?823 beq srs13d *jump if not824 * 825 move.w #33,COL(a7) *put column on stack826 jsr _vputa *reset column827 * 828 srs13d: btst #4,vrbw13+1 *variable 5 ?829 beq srs13e *jump if not830 * 831 move.w #42,COL(a7) *put column on stack832 jsr _vputa *reset column833 * 834 srs13e: btst #5,vrbw13+1 *variable 6 ?835 beq srs13x *jump if not836 * 837 move.w #51,COL(a7) *put column on stack838 jsr _vputa *reset column839 * 840 srs13x: move.w vrcw,d0 *restore vrcw to d0841 * 842 .page 843 * 844 *analog value845 *------------846 srs14: btst #14,d0 *analog value ?847 beq srs15 *jump if not848 * 849 move.w #AT12,ATR(a7) *put attribute on stack850 move.w #7,ROW(a7) *put row on stack851 btst #0,vrbw14+1 *variable 1 ?852 beq srs14a *jump if not853 * 854 move.w #8,COL(a7) *put 1st column on stack855 jsr _vputa *reset first column856 move.w #9,COL(a7) *put 2nd column on stack857 jsr _vputa *reset second column858 move.w #10,COL(a7) *put 3rd column on stack859 jsr _vputa *reset third column860 move.w #11,COL(a7) *put 4th column on stack861 jsr _vputa *reset fourth column862 move.w #12,COL(a7) *put 5th column on stack863 jsr _vputa *reset fifth column864 * 865 srs14a: btst #1,vrbw14+1 *variable 2 ?866 beq srs14b *jump if not867 * 868 move.w #17,COL(a7) *put 1st column on stack869 jsr _vputa *reset first column870 move.w #18,COL(a7) *put 2nd column on stack871 jsr _vputa *reset second column872 move.w #19,COL(a7) *put 3rd column on stack873 jsr _vputa *reset third column874 move.w #20,COL(a7) *put 4th column on stack875 jsr _vputa *reset fourth column876 move.w #21,COL(a7) *put 5th column on stack877 jsr _vputa *reset fifth column878 * 879 .page 880 * 881 srs14b: btst #2,vrbw14+1 *variable 3 ?882 beq srs14c *jump if not883 * 884 move.w #26,COL(a7) *put 1st column on stack885 jsr _vputa *reset first column886 move.w #27,COL(a7) *put 2nd column on stack887 jsr _vputa *reset second column888 move.w #28,COL(a7) *put 3rd column on stack889 jsr _vputa *reset third column890 move.w #29,COL(a7) *put 4th column on stack891 jsr _vputa *reset fourth column892 move.w #30,COL(a7) *put 5th column on stack893 jsr _vputa *reset fifth column894 * 895 srs14c: btst #3,vrbw14+1 *variable 4 ?896 beq srs14d *jump if not897 * 898 move.w #35,COL(a7) *put 1st column on stack899 jsr _vputa *reset first column900 move.w #36,COL(a7) *put 2nd column on stack901 jsr _vputa *reset second column902 move.w #37,COL(a7) *put 3rd column on stack903 jsr _vputa *reset third column904 move.w #38,COL(a7) *put 4th column on stack905 jsr _vputa *reset fourth column906 move.w #39,COL(a7) *put 5th column on stack907 jsr _vputa *reset fifth column908 * 909 .page 910 * 911 srs14d: btst #4,vrbw14+1 *variable 5 ?912 beq srs14e *jump if not913 * 914 move.w #44,COL(a7) *put 1st column on stack915 jsr _vputa *reset first column916 move.w #45,COL(a7) *put 2nd column on stack917 jsr _vputa *reset second column918 move.w #46,COL(a7) *put 3rd column on stack919 jsr _vputa *reset third column920 move.w #47,COL(a7) *put 4th column on stack921 jsr _vputa *reset fourth column922 move.w #48,COL(a7) *put 5th column on stack923 jsr _vputa *reset fifth column924 * 925 srs14e: btst #5,vrbw14+1 *variable 6 ?926 beq srs14x *jump if not927 * 928 move.w #53,COL(a7) *put 1st column on stack929 jsr _vputa *reset first column930 move.w #54,COL(a7) *put 2nd column on stack931 jsr _vputa *reset second column932 move.w #55,COL(a7) *put 3rd column on stack933 jsr _vputa *reset third column934 move.w #56,COL(a7) *put 4th column on stack935 jsr _vputa *reset fourth column936 move.w #57,COL(a7) *put 5th column on stack937 jsr _vputa *reset fifth column938 * 939 srs14x: move.w vrcw,d0 *restore vrcw to d0940 * 941 .page 942 * 943 *stop/next944 *---------945 srs15: btst #15,d0 *stop/next ?946 beq srs16 *jump if not947 * 948 btst #0,vrbw15 *stop ?949 beq srs15a *jump if not950 * 951 move.w #AT08,ATR(a7) *put attribute on stack952 move.w #1,ROW(a7) *put row on stack953 move.w #40,COL(a7) *put 1st column on stack954 jsr _vputa *reset first column955 move.w #41,COL(a7) *put 2nd column on stack956 jsr _vputa *reset second column957 move.w #42,COL(a7) *put 3rd column on stack958 jsr _vputa *reset third column959 move.w #43,COL(a7) *put 4th column on stack960 jsr _vputa *reset fourth column961 * 962 srs15a: btst #1,vrbw15 *next ?963 beq srs16 *jump if not964 * 965 move.w #AT08,ATR(a7) *put attribute on stack966 move.w #1,ROW(a7) *put row on stack967 move.w #45,COL(a7) *put 1st column on stack968 jsr _vputa *reset first column969 move.w #46,COL(a7) *put 2nd column on stack970 jsr _vputa *reset second column971 move.w #47,COL(a7) *put 3rd column on stack972 jsr _vputa *reset third column973 move.w #48,COL(a7) *put 4th column on stack974 jsr _vputa *reset fourth column975 * 976 srs16: add.l #10,a7 *clean up stack977 bra srsexit *done978 * 979 .page 980 * 6 7 .xdef _sreset | sreset() 8 9 .xref _vputa | vputa(sbase, row, col, attrib) 10 11 .xref _ndisp | WORD - display number 12 .xref _obj8 | LONG - object base address 13 .xref _vrbw08 | WORD - detail word for bit 8 14 .xref _vrbw09 | WORD - detail word for bit 9 15 .xref _vrbw10 | WORD - detail word for bit 10 16 .xref _vrbw11 | WORD - detail word for bit 11 17 .xref _vrbw12 | WORD - detail word for bit 12 18 .xref _vrbw13 | WORD - detail word for bit 13 19 .xref _vrbw14 | WORD - detail word for bit 14 20 .xref _vrbw15 | WORD - detail word for bit 15 21 .xref _vrcw | WORD - video reset control word 22 23 ROW = 4 24 COL = 6 25 ATR = 8 26 27 AT01 = 0x0014 28 AT04 = 0x0013 29 AT05 = 0x0014 30 AT06 = 0x0013 31 AT07 = 0x0014 32 AT08 = 0x0013 33 AT09 = 0x0014 34 AT10 = 0x0013 35 AT11 = 0x0012 36 AT12 = 0x0012 37 38 .page 39 40 | sreset() -- reset highlighting 41 | -------- ------------------ 42 _sreset: link a6,#0 | link stack frame 43 cmp.w #2,_ndisp | see if we should update display 44 bne srsexit | jump if not 45 46 move.w _vrcw,d0 | get and check vrcw 47 bne srs0 | jump if something to do 48 49 srsexit: unlk a6 | unlink stack frame 50 rts | return to caller 51 52 srs0: move.w sr,d1 | <<<<< disable interrupts >>>>> 53 ori.w #0x0700,sr | ... 54 55 move.w _vrcw,vrcw | make local copies of control variables 56 clr.w _vrcw | ... and clear them for the next pass 57 move.w _vrbw08,vrbw08 | ... 58 clr.w _vrbw08 | ... 59 move.w _vrbw09,vrbw09 | ... 60 clr.w _vrbw09 | ... 61 move.w _vrbw10,vrbw10 | ... 62 clr.w _vrbw10 | ... 63 move.w _vrbw11,vrbw11 | ... 64 clr.w _vrbw11 | ... 65 move.w _vrbw12,vrbw12 | ... 66 clr.w _vrbw12 | ... 67 move.w _vrbw13,vrbw13 | ... 68 clr.w _vrbw13 | ... 69 move.w _vrbw14,vrbw14 | ... 70 clr.w _vrbw14 | ... 71 move.w _vrbw15,vrbw15 | ... 72 clr.w _vrbw15 | ... 73 74 move.w d1,sr | <<<<< restore interrupts >>>>> 75 76 | Setup STACK for subsequent calls to vputa(sbase, row, col, atr): 77 78 | 0(a7) sbase 79 80 | 4(a7) row ROW 81 | 6(a7) col COL 82 | 8(a7) atr ATR 83 84 clr.w -(a7) | put dummy attribute on stack 85 clr.w -(a7) | put dummy column on stack 86 clr.w -(a7) | put dummy row on stack 87 move.l _obj8,-(a7) | put sbase on stack 88 89 .page 90 91 | assignment 92 | ---------- 93 btst #0,d0 | assignment ? 94 beq srs1 | jump if not 95 96 move.w #AT04,ATR(a7) | put attribute on stack 97 move.w #1,ROW(a7) | put row on stack 98 move.w #11,COL(a7) | put 1st column on stack 99 jsr _vputa | reset first column 100 move.w #12,COL(a7) | put 2nd column on stack 101 jsr _vputa | reset second column 102 move.w vrcw,d0 | restore vrcw to d0 103 104 | tuning 105 | ------ 106 srs1: btst #1,d0 | tuning ? 107 beq srs2 | jump if not 108 109 move.w #AT05,ATR(a7) | put attribute on stack 110 move.w #1,ROW(a7) | put row on stack 111 move.w #19,COL(a7) | put column on stack 112 jsr _vputa | reset column 113 move.w vrcw,d0 | restore vrcw to d0 114 115 | tempo 116 | ----- 117 srs2: btst #2,d0 | tempo ? 118 beq srs3 | jump if not 119 120 move.w #AT06,ATR(a7) | put attribute on stack 121 move.w #1,ROW(a7) | put row on stack 122 move.w #27,COL(a7) | put 1st column on stack 123 jsr _vputa | reset first column 124 move.w #28,COL(a7) | put 2nd column on stack 125 jsr _vputa | reset second column 126 move.w #29,COL(a7) | put 3rd column on stack 127 jsr _vputa | reset third column 128 move.w vrcw,d0 | restore vrcw to d0 129 130 .page 131 132 | interpolate 133 | ----------- 134 srs3: btst #3,d0 | interpolate ? 135 beq srs4 | jump if not 136 137 move.w #AT07,ATR(a7) | put attribute on stack 138 move.w #1,ROW(a7) | put row on stack 139 move.w #35,COL(a7) | put 1st column on stack 140 jsr _vputa | reset first column 141 move.w #36,COL(a7) | put 2nd column on stack 142 jsr _vputa | reset second column 143 move.w #37,COL(a7) | put 3rd column on stack 144 jsr _vputa | reset third column 145 move.w #38,COL(a7) | put 4th column on stack 146 jsr _vputa | reset fourth column 147 move.w vrcw,d0 | restore vrcw to d0 148 149 | section begin 150 | ------------- 151 srs4: btst #4,d0 | section begin ? 152 beq srs5 | jump if not 153 154 move.w #AT01,ATR(a7) | put attribute on stack 155 move.w #0,ROW(a7) | put row on stack 156 move.w #6,COL(a7) | put 1st column on stack 157 jsr _vputa | reset first column 158 move.w #7,COL(a7) | put 2nd column on stack 159 jsr _vputa | reset second column 160 161 .page 162 163 | punch in 164 | -------- 165 srs5: btst #5,d0 | punch in ? 166 beq srs6 | jump if not 167 168 move.w #AT09,ATR(a7) | put attribute on stack 169 move.w #1,ROW(a7) | put row on stack 170 move.w #50,COL(a7) | put 1st column on stack 171 jsr _vputa | reset first column 172 move.w #51,COL(a7) | put 2nd column on stack 173 jsr _vputa | reset second column 174 move.w vrcw,d0 | restore vrcw to d0 175 176 | punch out 177 | --------- 178 srs6: btst #6,d0 | punch out ? 179 beq srs7 | jump if not 180 181 move.w #AT09,ATR(a7) | put attribute on stack 182 move.w #1,ROW(a7) | put row on stack 183 move.w #53,COL(a7) | put 1st column on stack 184 jsr _vputa | reset first column 185 move.w #54,COL(a7) | put 2nd column on stack 186 jsr _vputa | reset second column 187 move.w #55,COL(a7) | put 3rd column on stack 188 jsr _vputa | reset third column 189 move.w vrcw,d0 | restore vrcw to d0 190 191 | Output 192 | ------ 193 srs7: btst #7,d0 | output ? 194 beq srs8 | jump if not 195 196 move.w #AT10,ATR(a7) | put attribute on stack 197 move.w #1,ROW(a7) | put row on stack 198 move.w #57,COL(a7) | put 1st column on stack 199 jsr _vputa | reset first column 200 move.w #58,COL(a7) | put 2nd column on stack 201 jsr _vputa | reset second column 202 move.w #59,COL(a7) | put 3rd column on stack 203 jsr _vputa | reset third column 204 move.w #60,COL(a7) | put 4th column on stack 205 jsr _vputa | reset fourth column 206 move.w #61,COL(a7) | put 5th column on stack 207 jsr _vputa | reset fifth column 208 move.w #62,COL(a7) | put 6th column on stack 209 jsr _vputa | reset sixth column 210 move.w vrcw,d0 | restore vrcw to d0 211 212 .page 213 214 | instrument 215 | ---------- 216 srs8: btst #8,d0 | instrument ? 217 beq srs9 | jump if not 218 219 move.w #2,ROW(a7) | put row on stack 220 move.w #AT11,ATR(a7) | put attribute on stack 221 btst #0,vrbw08+1 | group 1 ? 222 beq srs8a | jump if not 223 224 move.w #7,COL(a7) | put 1st column on stack 225 jsr _vputa | reset first column 226 move.w #8,COL(a7) | put 2nd column on stack 227 jsr _vputa | reset second column 228 229 srs8a: btst #1,vrbw08+1 | group 2 ? 230 beq srs8b | jump if not 231 232 move.w #12,COL(a7) | put 1st column on stack 233 jsr _vputa | reset first character 234 move.w #13,COL(a7) | put 2nd column on stack 235 jsr _vputa | reset second character 236 237 srs8b: btst #2,vrbw08+1 | group 3 ? 238 beq srs8c | jump if not 239 240 move.w #17,COL(a7) | put 1st column on stack 241 jsr _vputa | reset first character 242 move.w #18,COL(a7) | put 2nd column on stack 243 jsr _vputa | reset second character 244 245 srs8c: btst #3,vrbw08+1 | group 4 ? 246 beq srs8d | jump if not 247 248 move.w #22,COL(a7) | put 1st column on stack 249 jsr _vputa | reset first character 250 move.w #23,COL(a7) | put 2nd column on stack 251 jsr _vputa | reset second character 252 253 .page 254 255 srs8d: btst #4,vrbw08+1 | group 5 ? 256 beq srs8e | jump if not 257 258 move.w #27,COL(a7) | put 1st column on stack 259 jsr _vputa | reset first character 260 move.w #28,COL(a7) | put 2nd column on stack 261 jsr _vputa | reset second character 262 263 srs8e: btst #5,vrbw08+1 | group 6 ? 264 beq srs8f | jump if not 265 266 move.w #32,COL(a7) | put 1st column on stack 267 jsr _vputa | reset first character 268 move.w #33,COL(a7) | put 2nd column on stack 269 jsr _vputa | reset second character 270 271 srs8f: btst #6,vrbw08+1 | group 7 ? 272 beq srs8g | jump if not 273 274 move.w #37,COL(a7) | put 1st column on stack 275 jsr _vputa | reset first character 276 move.w #38,COL(a7) | put 2nd column on stack 277 jsr _vputa | reset second character 278 279 srs8g: btst #7,vrbw08+1 | group 8 ? 280 beq srs8h | jump if not 281 282 move.w #42,COL(a7) | put 1st column on stack 283 jsr _vputa | reset first character 284 move.w #43,COL(a7) | put 2nd column on stack 285 jsr _vputa | reset second character 286 287 .page 288 289 srs8h: btst #0,vrbw08 | group 9 290 beq srs8j | jump if not 291 292 move.w #47,COL(a7) | put 1st column on stack 293 jsr _vputa | reset first character 294 move.w #48,COL(a7) | put 2nd column on stack 295 jsr _vputa | reset second character 296 297 srs8j: btst #1,vrbw08 | group 10 298 beq srs8k | jump if not 299 300 move.w #52,COL(a7) | put 1st column on stack 301 jsr _vputa | reset first character 302 move.w #53,COL(a7) | put 2nd column on stack 303 jsr _vputa | reset second character 304 305 srs8k: btst #2,vrbw08 | group 11 306 beq srs8m | jump if not 307 308 move.w #57,COL(a7) | put 1st column on stack 309 jsr _vputa | reset first character 310 move.w #58,COL(a7) | put 2nd column on stack 311 jsr _vputa | reset second character 312 313 srs8m: btst #3,vrbw08 | group 12 314 beq srs8x | jump if not 315 316 move.w #62,COL(a7) | put 1st column on stack 317 jsr _vputa | reset first character 318 move.w #63,COL(a7) | put 2nd column on stack 319 jsr _vputa | reset second character 320 321 srs8x: move.w vrcw,d0 | restore vrcw to d0 322 323 .page 324 325 | transpose 326 | --------- 327 srs9: btst #9,d0 | transpose ? 328 beq srs10 | jump if not 329 330 move.w #AT11,ATR(a7) | put attribute on stack 331 move.w #3,ROW(a7) | put row on stack 332 btst #0,vrbw09+1 | group 1 ? 333 beq srs9a | jump if not 334 335 move.w #5,COL(a7) | put 1st column on stack 336 jsr _vputa | reset first column 337 move.w #6,COL(a7) | put 2nd column on stack 338 jsr _vputa | reset second column 339 move.w #7,COL(a7) | put 3rd column on stack 340 jsr _vputa | reset third column 341 move.w #8,COL(a7) | put 4th column on stack 342 jsr _vputa | reset fourth column 343 344 srs9a: btst #1,vrbw09+1 | group 2 ? 345 beq srs9b | jump if not 346 347 move.w #10,COL(a7) | put 1st column on stack 348 jsr _vputa | reset first column 349 move.w #11,COL(a7) | put 2nd column on stack 350 jsr _vputa | reset second column 351 move.w #12,COL(a7) | put 3rd column on stack 352 jsr _vputa | reset third column 353 move.w #13,COL(a7) | put 4th column on stack 354 jsr _vputa | reset fourth column 355 356 srs9b: btst #2,vrbw09+1 | group 3 ? 357 beq srs9c | jump if not 358 359 move.w #15,COL(a7) | put 1st column on stack 360 jsr _vputa | reset first column 361 move.w #16,COL(a7) | put 2nd column on stack 362 jsr _vputa | reset second column 363 move.w #17,COL(a7) | put 3rd column on stack 364 jsr _vputa | reset third column 365 move.w #18,COL(a7) | put 4th column on stack 366 jsr _vputa | reset fourth column 367 368 .page 369 370 srs9c: btst #3,vrbw09+1 | group 4 ? 371 beq srs9d | jump if not 372 373 move.w #20,COL(a7) | put 1st column on stack 374 jsr _vputa | reset first column 375 move.w #21,COL(a7) | put 2nd column on stack 376 jsr _vputa | reset second column 377 move.w #22,COL(a7) | put 3rd column on stack 378 jsr _vputa | reset third column 379 move.w #23,COL(a7) | put 4th column on stack 380 jsr _vputa | reset fourth column 381 382 srs9d: btst #4,vrbw09+1 | group 5 ? 383 beq srs9e | jump if not 384 385 move.w #25,COL(a7) | put 1st column on stack 386 jsr _vputa | reset first column 387 move.w #26,COL(a7) | put 2nd column on stack 388 jsr _vputa | reset second column 389 move.w #27,COL(a7) | put 3rd column on stack 390 jsr _vputa | reset third column 391 move.w #28,COL(a7) | put 4th column on stack 392 jsr _vputa | reset fourth column 393 394 srs9e: btst #5,vrbw09+1 | group 6 ? 395 beq srs9f | jump if not 396 397 move.w #30,COL(a7) | put 1st column on stack 398 jsr _vputa | reset first column 399 move.w #31,COL(a7) | put 2nd column on stack 400 jsr _vputa | reset second column 401 move.w #32,COL(a7) | put 3rd column on stack 402 jsr _vputa | reset third column 403 move.w #33,COL(a7) | put 4th column on stack 404 jsr _vputa | reset fourth column 405 406 .page 407 408 srs9f: btst #6,vrbw09+1 | group 7 ? 409 beq srs9g | jump if not 410 411 move.w #35,COL(a7) | put 1st column on stack 412 jsr _vputa | reset first column 413 move.w #36,COL(a7) | put 2nd column on stack 414 jsr _vputa | reset second column 415 move.w #37,COL(a7) | put 3rd column on stack 416 jsr _vputa | reset third column 417 move.w #38,COL(a7) | put 4th column on stack 418 jsr _vputa | reset fourth column 419 420 srs9g: btst #7,vrbw09+1 | group 8 ? 421 beq srs9h | jump if not 422 423 move.w #40,COL(a7) | put 1st column on stack 424 jsr _vputa | reset first column 425 move.w #41,COL(a7) | put 2nd column on stack 426 jsr _vputa | reset second column 427 move.w #42,COL(a7) | put 3rd column on stack 428 jsr _vputa | reset third column 429 move.w #43,COL(a7) | put 4th column on stack 430 jsr _vputa | reset fourth column 431 432 srs9h: btst #0,vrbw09 | group 9 433 beq srs9j | jump if not 434 435 move.w #45,COL(a7) | put 1st column on stack 436 jsr _vputa | reset first column 437 move.w #46,COL(a7) | put 2nd column on stack 438 jsr _vputa | reset second column 439 move.w #47,COL(a7) | put 3rd column on stack 440 jsr _vputa | reset third column 441 move.w #48,COL(a7) | put 4th column on stack 442 jsr _vputa | reset fourth column 443 444 .page 445 446 srs9j: btst #1,vrbw09 | group 10 447 beq srs9k | jump if not 448 449 move.w #50,COL(a7) | put 1st column on stack 450 jsr _vputa | reset first column 451 move.w #51,COL(a7) | put 2nd column on stack 452 jsr _vputa | reset second column 453 move.w #52,COL(a7) | put 3rd column on stack 454 jsr _vputa | reset third column 455 move.w #53,COL(a7) | put 4th column on stack 456 jsr _vputa | reset fourth column 457 458 srs9k: btst #2,vrbw09 | group 11 459 beq srs9m | jump if not 460 461 move.w #55,COL(a7) | put 1st column on stack 462 jsr _vputa | reset first column 463 move.w #56,COL(a7) | put 2nd column on stack 464 jsr _vputa | reset second column 465 move.w #57,COL(a7) | put 3rd column on stack 466 jsr _vputa | reset third column 467 move.w #58,COL(a7) | put 4th column on stack 468 jsr _vputa | reset fourth column 469 470 srs9m: btst #3,vrbw09 | group 12 471 beq srs9x | jump if not 472 473 move.w #60,COL(a7) | put 1st column on stack 474 jsr _vputa | reset first column 475 move.w #61,COL(a7) | put 2nd column on stack 476 jsr _vputa | reset second column 477 move.w #62,COL(a7) | put 3rd column on stack 478 jsr _vputa | reset third column 479 move.w #63,COL(a7) | put 4th column on stack 480 jsr _vputa | reset fourth column 481 482 srs9x: move.w vrcw,d0 | restore vrcw to d0 483 484 .page 485 486 | dynamics 487 | -------- 488 srs10: btst #10,d0 | dynamics ? 489 beq srs11 | jump if not 490 491 move.w #AT11,ATR(a7) | put attribute on stack 492 move.w #4,ROW(a7) | put row on stack 493 btst #0,vrbw10+1 | group 1 ? 494 beq srs10a | jump if not 495 496 move.w #6,COL(a7) | put column on stack 497 jsr _vputa | reset column 498 499 srs10a: btst #1,vrbw10+1 | group 2 ? 500 beq srs10b | jump if not 501 502 move.w #11,COL(a7) | put column on stack 503 jsr _vputa | reset column 504 505 srs10b: btst #2,vrbw10+1 | group 3 ? 506 beq srs10c | jump if not 507 508 move.w #16,COL(a7) | put column on stack 509 jsr _vputa | reset column 510 511 srs10c: btst #3,vrbw10+1 | group 4 ? 512 beq srs10d | jump if not 513 514 move.w #21,COL(a7) | put column on stack 515 jsr _vputa | reset column 516 517 .page 518 519 srs10d: btst #4,vrbw10+1 | group 5 ? 520 beq srs10e | jump if not 521 522 move.w #26,COL(a7) | put column on stack 523 jsr _vputa | reset column 524 525 srs10e: btst #5,vrbw10+1 | group 6 ? 526 beq srs10f | jump if not 527 528 move.w #31,COL(a7) | put column on stack 529 jsr _vputa | reset column 530 531 srs10f: btst #6,vrbw10+1 | group 7 ? 532 beq srs10g | jump if not 533 534 move.w #36,COL(a7) | put column on stack 535 jsr _vputa | reset column 536 537 srs10g: btst #7,vrbw10+1 | group 8 ? 538 beq srs10h | jump if not 539 540 move.w #41,COL(a7) | put column on stack 541 jsr _vputa | reset column 542 543 .page 544 545 srs10h: btst #0,vrbw10 | group 9 546 beq srs10j | jump if not 547 548 move.w #46,COL(a7) | put column on stack 549 jsr _vputa | reset column 550 551 srs10j: btst #1,vrbw10 | group 10 552 beq srs10k | jump if not 553 554 move.w #51,COL(a7) | put column on stack 555 jsr _vputa | reset column 556 557 srs10k: btst #2,vrbw10 | group 11 558 beq srs10m | jump if not 559 560 move.w #56,COL(a7) | put column on stack 561 jsr _vputa | reset column 562 563 srs10m: btst #3,vrbw10 | group 12 564 beq srs10x | jump if not 565 566 move.w #61,COL(a7) | put column on stack 567 jsr _vputa | reset column 568 569 srs10x: move.w vrcw,d0 | restore vrcw to d0 570 571 .page 572 573 | location 574 | -------- 575 srs11: btst #11,d0 | location ? 576 beq srs12 | jump if not 577 578 move.w #AT11,ATR(a7) | put attribute on stack 579 move.w #4,ROW(a7) | put row on stack 580 btst #0,vrbw11+1 | group 1 ? 581 beq srs11a | jump if not 582 583 move.w #8,COL(a7) | put column on stack 584 jsr _vputa | reset column 585 586 srs11a: btst #1,vrbw11+1 | group 2 ? 587 beq srs11b | jump if not 588 589 move.w #13,COL(a7) | put column on stack 590 jsr _vputa | reset column 591 592 srs11b: btst #2,vrbw11+1 | group 3 ? 593 beq srs11c | jump if not 594 595 move.w #18,COL(a7) | put column on stack 596 jsr _vputa | reset column 597 598 srs11c: btst #3,vrbw11+1 | group 4 ? 599 beq srs11d | jump if not 600 601 move.w #23,COL(a7) | put column on stack 602 jsr _vputa | reset column 603 604 .page 605 606 srs11d: btst #4,vrbw11+1 | group 5 ? 607 beq srs11e | jump if not 608 609 move.w #28,COL(a7) | put column on stack 610 jsr _vputa | reset column 611 612 srs11e: btst #5,vrbw11+1 | group 6 ? 613 beq srs11f | jump if not 614 615 move.w #33,COL(a7) | put column on stack 616 jsr _vputa | reset column 617 618 srs11f: btst #6,vrbw11+1 | group 7 ? 619 beq srs11g | jump if not 620 621 move.w #38,COL(a7) | put column on stack 622 jsr _vputa | reset column 623 624 srs11g: btst #7,vrbw11+1 | group 8 ? 625 beq srs11h | jump if not 626 627 move.w #43,COL(a7) | put column on stack 628 jsr _vputa | reset column 629 630 .page 631 632 srs11h: btst #0,vrbw11 | group 9 633 beq srs11j | jump if not 634 635 move.w #48,COL(a7) | put column on stack 636 jsr _vputa | reset column 637 638 srs11j: btst #1,vrbw11 | group 10 639 beq srs11k | jump if not 640 641 move.w #53,COL(a7) | put column on stack 642 jsr _vputa | reset column 643 644 srs11k: btst #2,vrbw11 | group 11 645 beq srs11m | jump if not 646 647 move.w #58,COL(a7) | put column on stack 648 jsr _vputa | reset column 649 650 srs11m: btst #3,vrbw11 | group 12 651 beq srs11x | jump if not 652 653 move.w #63,COL(a7) | put column on stack 654 jsr _vputa | reset column 655 656 srs11x: move.w vrcw,d0 | restore vrcw to d0 657 658 .page 659 660 | velocity 661 | -------- 662 srs12: btst #12,d0 | velocity ? 663 beq srs13 | jump if not 664 665 move.w #AT11,ATR(a7) | put attribute on stack 666 move.w #5,ROW(a7) | put row on stack 667 btst #0,vrbw12+1 | group 1 ? 668 beq srs12a | jump if not 669 670 move.w #6,COL(a7) | put 1st column on stack 671 jsr _vputa | reset first column 672 move.w #7,COL(a7) | put 2nd column on stack 673 jsr _vputa | reset second column 674 move.w #8,COL(a7) | put 3rd column on stack 675 jsr _vputa | reset third column 676 677 srs12a: btst #1,vrbw12+1 | group 2 ? 678 beq srs12b | jump if not 679 680 move.w #11,COL(a7) | put 1st column on stack 681 jsr _vputa | reset first column 682 move.w #12,COL(a7) | put 2nd column on stack 683 jsr _vputa | reset second column 684 move.w #13,COL(a7) | put 3rd column on stack 685 jsr _vputa | reset third column 686 687 srs12b: btst #2,vrbw12+1 | group 3 ? 688 beq srs12c | jump if not 689 690 move.w #16,COL(a7) | put 1st column on stack 691 jsr _vputa | reset first column 692 move.w #17,COL(a7) | put 2nd column on stack 693 jsr _vputa | reset second column 694 move.w #18,COL(a7) | put 3rd column on stack 695 jsr _vputa | reset third column 696 697 .page 698 699 srs12c: btst #3,vrbw12+1 | group 4 ? 700 beq srs12d | jump if not 701 702 move.w #21,COL(a7) | put 1st column on stack 703 jsr _vputa | reset first column 704 move.w #22,COL(a7) | put 2nd column on stack 705 jsr _vputa | reset second column 706 move.w #23,COL(a7) | put 3rd column on stack 707 jsr _vputa | reset third column 708 709 srs12d: btst #4,vrbw12+1 | group 5 ? 710 beq srs12e | jump if not 711 712 move.w #26,COL(a7) | put 1st column on stack 713 jsr _vputa | reset first column 714 move.w #27,COL(a7) | put 2nd column on stack 715 jsr _vputa | reset second column 716 move.w #28,COL(a7) | put 3rd column on stack 717 jsr _vputa | reset third column 718 719 srs12e: btst #5,vrbw12+1 | group 6 ? 720 beq srs12f | jump if not 721 722 move.w #31,COL(a7) | put 1st column on stack 723 jsr _vputa | reset first column 724 move.w #32,COL(a7) | put 2nd column on stack 725 jsr _vputa | reset second column 726 move.w #33,COL(a7) | put 3rd column on stack 727 jsr _vputa | reset third column 728 729 .page 730 731 srs12f: btst #6,vrbw12+1 | group 7 ? 732 beq srs12g | jump if not 733 734 move.w #36,COL(a7) | put 1st column on stack 735 jsr _vputa | reset first column 736 move.w #37,COL(a7) | put 2nd column on stack 737 jsr _vputa | reset second column 738 move.w #38,COL(a7) | put 3rd column on stack 739 jsr _vputa | reset third column 740 741 srs12g: btst #7,vrbw12+1 | group 8 ? 742 beq srs12h | jump if not 743 744 move.w #41,COL(a7) | put 1st column on stack 745 jsr _vputa | reset first column 746 move.w #42,COL(a7) | put 2nd column on stack 747 jsr _vputa | reset second column 748 move.w #43,COL(a7) | put 3rd column on stack 749 jsr _vputa | reset third column 750 751 srs12h: btst #0,vrbw12 | group 9 752 beq srs12j | jump if not 753 754 move.w #46,COL(a7) | put 1st column on stack 755 jsr _vputa | reset first column 756 move.w #47,COL(a7) | put 2nd column on stack 757 jsr _vputa | reset second column 758 move.w #48,COL(a7) | put 3rd column on stack 759 jsr _vputa | reset third column 760 761 .page 762 763 srs12j: btst #1,vrbw12 | group 10 764 beq srs12k | jump if not 765 766 move.w #51,COL(a7) | put 1st column on stack 767 jsr _vputa | reset first column 768 move.w #52,COL(a7) | put 2nd column on stack 769 jsr _vputa | reset second column 770 move.w #53,COL(a7) | put 3rd column on stack 771 jsr _vputa | reset third column 772 773 srs12k: btst #2,vrbw12 | group 11 774 beq srs12m | jump if not 775 776 move.w #56,COL(a7) | put 1st column on stack 777 jsr _vputa | reset first column 778 move.w #57,COL(a7) | put 2nd column on stack 779 jsr _vputa | reset second column 780 move.w #58,COL(a7) | put 3rd column on stack 781 jsr _vputa | reset third column 782 783 srs12m: btst #3,vrbw12 | group 12 784 beq srs12x | jump if not 785 786 move.w #61,COL(a7) | put 1st column on stack 787 jsr _vputa | reset first column 788 move.w #62,COL(a7) | put 2nd column on stack 789 jsr _vputa | reset second column 790 move.w #63,COL(a7) | put 3rd column on stack 791 jsr _vputa | reset third column 792 793 srs12x: move.w vrcw,d0 | restore vrcw to d0 794 795 .page 796 797 | resolution 798 | ---------- 799 srs13: btst #13,d0 | resolution ? 800 beq srs14 | jump if not 801 802 move.w #AT12,ATR(a7) | put attribute on stack 803 move.w #7,ROW(a7) | put row on stack 804 btst #0,vrbw13+1 | variable 1 ? 805 beq srs13a | jump if not 806 807 move.w #6,COL(a7) | put column on stack 808 jsr _vputa | reset column 809 810 srs13a: btst #1,vrbw13+1 | variable 2 ? 811 beq srs13b | jump if not 812 813 move.w #15,COL(a7) | put column on stack 814 jsr _vputa | reset column 815 816 srs13b: btst #2,vrbw13+1 | variable 3 ? 817 beq srs13c | jump if not 818 819 move.w #24,COL(a7) | put column on stack 820 jsr _vputa | reset column 821 822 srs13c: btst #3,vrbw13+1 | variable 4 ? 823 beq srs13d | jump if not 824 825 move.w #33,COL(a7) | put column on stack 826 jsr _vputa | reset column 827 828 srs13d: btst #4,vrbw13+1 | variable 5 ? 829 beq srs13e | jump if not 830 831 move.w #42,COL(a7) | put column on stack 832 jsr _vputa | reset column 833 834 srs13e: btst #5,vrbw13+1 | variable 6 ? 835 beq srs13x | jump if not 836 837 move.w #51,COL(a7) | put column on stack 838 jsr _vputa | reset column 839 840 srs13x: move.w vrcw,d0 | restore vrcw to d0 841 842 .page 843 844 | analog value 845 | ------------ 846 srs14: btst #14,d0 | analog value ? 847 beq srs15 | jump if not 848 849 move.w #AT12,ATR(a7) | put attribute on stack 850 move.w #7,ROW(a7) | put row on stack 851 btst #0,vrbw14+1 | variable 1 ? 852 beq srs14a | jump if not 853 854 move.w #8,COL(a7) | put 1st column on stack 855 jsr _vputa | reset first column 856 move.w #9,COL(a7) | put 2nd column on stack 857 jsr _vputa | reset second column 858 move.w #10,COL(a7) | put 3rd column on stack 859 jsr _vputa | reset third column 860 move.w #11,COL(a7) | put 4th column on stack 861 jsr _vputa | reset fourth column 862 move.w #12,COL(a7) | put 5th column on stack 863 jsr _vputa | reset fifth column 864 865 srs14a: btst #1,vrbw14+1 | variable 2 ? 866 beq srs14b | jump if not 867 868 move.w #17,COL(a7) | put 1st column on stack 869 jsr _vputa | reset first column 870 move.w #18,COL(a7) | put 2nd column on stack 871 jsr _vputa | reset second column 872 move.w #19,COL(a7) | put 3rd column on stack 873 jsr _vputa | reset third column 874 move.w #20,COL(a7) | put 4th column on stack 875 jsr _vputa | reset fourth column 876 move.w #21,COL(a7) | put 5th column on stack 877 jsr _vputa | reset fifth column 878 879 .page 880 881 srs14b: btst #2,vrbw14+1 | variable 3 ? 882 beq srs14c | jump if not 883 884 move.w #26,COL(a7) | put 1st column on stack 885 jsr _vputa | reset first column 886 move.w #27,COL(a7) | put 2nd column on stack 887 jsr _vputa | reset second column 888 move.w #28,COL(a7) | put 3rd column on stack 889 jsr _vputa | reset third column 890 move.w #29,COL(a7) | put 4th column on stack 891 jsr _vputa | reset fourth column 892 move.w #30,COL(a7) | put 5th column on stack 893 jsr _vputa | reset fifth column 894 895 srs14c: btst #3,vrbw14+1 | variable 4 ? 896 beq srs14d | jump if not 897 898 move.w #35,COL(a7) | put 1st column on stack 899 jsr _vputa | reset first column 900 move.w #36,COL(a7) | put 2nd column on stack 901 jsr _vputa | reset second column 902 move.w #37,COL(a7) | put 3rd column on stack 903 jsr _vputa | reset third column 904 move.w #38,COL(a7) | put 4th column on stack 905 jsr _vputa | reset fourth column 906 move.w #39,COL(a7) | put 5th column on stack 907 jsr _vputa | reset fifth column 908 909 .page 910 911 srs14d: btst #4,vrbw14+1 | variable 5 ? 912 beq srs14e | jump if not 913 914 move.w #44,COL(a7) | put 1st column on stack 915 jsr _vputa | reset first column 916 move.w #45,COL(a7) | put 2nd column on stack 917 jsr _vputa | reset second column 918 move.w #46,COL(a7) | put 3rd column on stack 919 jsr _vputa | reset third column 920 move.w #47,COL(a7) | put 4th column on stack 921 jsr _vputa | reset fourth column 922 move.w #48,COL(a7) | put 5th column on stack 923 jsr _vputa | reset fifth column 924 925 srs14e: btst #5,vrbw14+1 | variable 6 ? 926 beq srs14x | jump if not 927 928 move.w #53,COL(a7) | put 1st column on stack 929 jsr _vputa | reset first column 930 move.w #54,COL(a7) | put 2nd column on stack 931 jsr _vputa | reset second column 932 move.w #55,COL(a7) | put 3rd column on stack 933 jsr _vputa | reset third column 934 move.w #56,COL(a7) | put 4th column on stack 935 jsr _vputa | reset fourth column 936 move.w #57,COL(a7) | put 5th column on stack 937 jsr _vputa | reset fifth column 938 939 srs14x: move.w vrcw,d0 | restore vrcw to d0 940 941 .page 942 943 | stop/next 944 | --------- 945 srs15: btst #15,d0 | stop/next ? 946 beq srs16 | jump if not 947 948 btst #0,vrbw15 | stop ? 949 beq srs15a | jump if not 950 951 move.w #AT08,ATR(a7) | put attribute on stack 952 move.w #1,ROW(a7) | put row on stack 953 move.w #40,COL(a7) | put 1st column on stack 954 jsr _vputa | reset first column 955 move.w #41,COL(a7) | put 2nd column on stack 956 jsr _vputa | reset second column 957 move.w #42,COL(a7) | put 3rd column on stack 958 jsr _vputa | reset third column 959 move.w #43,COL(a7) | put 4th column on stack 960 jsr _vputa | reset fourth column 961 962 srs15a: btst #1,vrbw15 | next ? 963 beq srs16 | jump if not 964 965 move.w #AT08,ATR(a7) | put attribute on stack 966 move.w #1,ROW(a7) | put row on stack 967 move.w #45,COL(a7) | put 1st column on stack 968 jsr _vputa | reset first column 969 move.w #46,COL(a7) | put 2nd column on stack 970 jsr _vputa | reset second column 971 move.w #47,COL(a7) | put 3rd column on stack 972 jsr _vputa | reset third column 973 move.w #48,COL(a7) | put 4th column on stack 974 jsr _vputa | reset fourth column 975 976 srs16: add.l #10,a7 | clean up stack 977 bra srsexit | done 978 979 .page 980 981 981 .bss 982 * 983 *local copies of _vrcw, _vrbw08.._vrbw15984 * 982 983 | local copies of _vrcw, _vrbw08.._vrbw15 984 985 985 vrcw: .ds.w 1 986 986 vrbw08: .ds.w 1 … … 992 992 vrbw14: .ds.w 1 993 993 vrbw15: .ds.w 1 994 * 994 995 995 .end -
ram/timeint.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *timeint.s -- MIDAS-VII timer interrupt handler3 *Version 15 -- 1989-07-20 -- D.N. Lynx Crowe4 *------------------------------------------------------------------------------5 * 6 *This code replaces the interrupt handler in bios.s, which is known to7 *have a bug in it, and adds support for the VSDD and an array of programable8 *timers with 1 Ms resolution.9 * 10 *WARNING: There are equates to addresses in the bios EPROM which may change11 *when the bios is reassembled. If the bios is reassembled be sure to update12 *the equates flagged by "<<<=====".13 * 14 *The addresses currently in the equates are for EPROMs dated 1988-04-18 or15 *1988-06-20 ONLY.16 * 17 *------------------------------------------------------------------------------18 *Hardware timer usage:19 *---------------------20 *Timer 1 PLL divider for score clock -- fixed at 6421 *Timer 2 PLL divider for score clock -- nominally 320022 *Timer 3 1 Ms Real Time Clock23 * 24 *------------------------------------------------------------------------------25 * 1 | ------------------------------------------------------------------------------ 2 | timeint.s -- MIDAS-VII timer interrupt handler 3 | Version 15 -- 1989-07-20 -- D.N. Lynx Crowe 4 | ------------------------------------------------------------------------------ 5 6 | This code replaces the interrupt handler in bios.s, which is known to 7 | have a bug in it, and adds support for the VSDD and an array of programable 8 | timers with 1 Ms resolution. 9 10 | WARNING: There are equates to addresses in the bios EPROM which may change 11 | when the bios is reassembled. If the bios is reassembled be sure to update 12 | the equates flagged by "<<<=====". 13 14 | The addresses currently in the equates are for EPROMs dated 1988-04-18 or 15 | 1988-06-20 ONLY. 16 17 | ------------------------------------------------------------------------------ 18 | Hardware timer usage: 19 | --------------------- 20 | Timer 1 PLL divider for score clock -- fixed at 64 21 | Timer 2 PLL divider for score clock -- nominally 3200 22 | Timer 3 1 Ms Real Time Clock 23 24 | ------------------------------------------------------------------------------ 25 26 26 .text 27 * 28 .xdef _tsetup *tsetup() -- timer setup function29 .xdef timeint *timer interrupt handler30 * 31 .xdef _M1IoRec * MIDI channel 1 IoRec32 .xdef _M2IoRec * MIDI channel 2 IoRec33 .xdef _S1IoRec * RS232 channel 1 IoRec34 .xdef _S2IoRec * RS232 channel 2 IoRec35 .xdef _timers *timer array -- short timers[NTIMERS]36 .xdef _vi_clk *VSDD scroll delay timer37 .xdef _vi_tag *VSDD VI tag38 * 39 .xref lclsadr *score object base address40 .xref lclscrl *score object scroll offset41 .xref _v_odtab *VSDD object descriptor table42 * 43 .page 44 *==============================================================================45 * 46 FRAMES .equ 0 *set non-zero to enable frame pulses47 * 48 *Equates to variables in bios.s:49 *-------------------------------50 *These variables are permanently assigned.51 * 52 TIMEVEC .equ $00000400 *LONG - System timer trap vector53 * 54 FC_SW .equ $00000420 *WORD - Frame clock switch55 FC_VAL .equ $00000422 *LONG - Frame clock value56 * 57 HZ_1K .equ $0000049A *LONG - 1000 Hz clock58 HZ_200 .equ $0000049E *LONG - 200 Hz clock59 FRCLOCK .equ $000004A2 *LONG - 50 Hz clock60 * 61 T3COUNT .equ $000004AA *WORD - Timer 3 count62 * 63 *------------------------------------------------------------------------------64 * 65 *WARNING: The address of "FLOCK" depends on the version of the bios EPROM.66 *The address below is for EPROMs dated 1988-04-18 or 1988-06-20 ONLY.67 * 68 FLOCK .equ $00000E0C *WORD - Floppy semaphore <<<=====69 * 70 *==============================================================================71 * 72 *Equates to routines in bios.s:73 *------------------------------74 * 75 *WARNING: The address of "FLOPVBL" depends on the version of the bios EPROM.76 *The address below is for EPROMs dated 1988-04-18 or 1988-06-20 ONLY.77 * 78 FLOPVBL .equ $001015EE *floppy VI handler address <<<=====79 * 80 *==============================================================================81 * 82 .page 83 * 84 *Hardware address equates:85 *-------------------------86 TI_VEC .equ $00000070 *Timer interrupt autovector87 * 88 TIMER .equ $003A0001 *Timer base address89 M1_ACIA .equ $003AC001 *MIDI ACIA channel 1 base address90 * 91 *------------------------------------------------------------------------------92 * 93 *Timer register equates:94 *-----------------------95 TIME_CRX .equ TIMER *Control register 1 or 396 TIME_CR2 .equ TIMER+2 *Control register 297 TIME_T1H .equ TIMER+4 *Timer 1 high byte98 TIME_T1L .equ TIMER+6 *Timer 1 low byte99 TIME_T2H .equ TIMER+8 *Timer 2 high byte100 TIME_T2L .equ TIMER+10 *Timer 2 low byte101 TIME_T3H .equ TIMER+12 *Timer 3 high byte102 TIME_T3L .equ TIMER+14 *Timer 3 low byte103 * 104 *Serial I/O equates:105 *-------------------106 ACIA_CFR .equ 2 *CFR offset from ACIA base107 DTR_BIT .equ 1 *DTR bit in ACIA CFR1108 * 109 IO_CFR1 .equ 29 *cfr1 offset in M1IoRec110 * 111 *==============================================================================112 * 113 *Miscellaneous equates:114 *----------------------115 IPL7 .equ $0700 *IPL mask for interrupt disable116 * 117 FCMAX .equ $00FFFFFF *Maximum frame counter value118 FCMIN .equ $00000000 *Minimum frame counter value119 * 120 NTIMERS .equ 8 *Number of timers in the timer array121 * 122 XBIOS .equ 14 *XBIOS TRAP number123 X_PIOREC .equ 0 *X_PIOREC code124 SR1_DEV .equ 0 *RS232 ACIA channel 1125 SR2_DEV .equ 1 *RS232 ACIA channel 2126 MC1_DEV .equ 3 *MIDI ACIA channel 1127 MC2_DEV .equ 4 *MIDI ACIA channel 2128 *==============================================================================129 * 130 .page 131 *==============================================================================132 *_tsetup -- tsetup() -- timer setup function133 *==============================================================================134 * 135 _tsetup: move.w sr,-(a7) *Save old interrupt mask136 ori.w #IPL7,sr *Disable interrupts137 * 138 move.w #SR1_DEV,-(a7) *Establish S1IoRec139 move.w #X_PIOREC,-(a7) *...140 trap #XBIOS *...141 add.l #4,a7 *...142 move.l d0,_S1IoRec *...143 * 144 move.w #SR2_DEV,-(a7) *Establish S2IoRec145 move.w #X_PIOREC,-(a7) *...146 trap #XBIOS *...147 add.l #4,a7 *...148 move.l d0,_S2IoRec *...149 * 150 move.w #MC1_DEV,-(a7) *Establish M1IoRec151 move.w #X_PIOREC,-(a7) *...152 trap #XBIOS *...153 add.l #4,a7 *...154 move.l d0,_M1IoRec *...155 * 156 move.w #MC2_DEV,-(a7) *Establish M2IoRec157 move.w #X_PIOREC,-(a7) *...158 trap #XBIOS *...159 add.l #4,a7 *...160 move.l d0,_M2IoRec *...161 * 162 .page 163 * 164 clr.w FC_SW *Stop the frame clock165 clr.l FC_VAL *... and reset it166 clr.w _vi_tag *Clear VSDD VI tag167 clr.w _vi_clk *Clear VSDD delay timer168 clr.w lclsadr *Clear score scroll address169 clr.w lclscrl *Clear score scroll offset170 * 171 lea _timers,a0 *Point at timer array172 move.w #NTIMERS-1,d0 *Setup to clear timer array173 * 174 tclr: clr.w (a0)+ *Clear a timer array entry175 dbra d0,tclr *Loop until done176 * 177 move.l #nullrts,TIMEVEC *Set timer interrupt vector178 move.l #timeint,TI_VEC *Set timer trap vector179 * 180 move.b # $00,TIME_T1H *Setup timer 1 (PLL)181 move.b # $1F,TIME_T1L *... for divide by 64182 move.b # $0C,TIME_T2H *Setup timer 2 (FC)183 move.b # $7F,TIME_T2L *... for divide by 3200184 move.b # $03,TIME_T3H *Setup timer 3 (RTC)185 move.b # $20,TIME_T3L *... for 1Ms interval186 move.b # $42,TIME_CRX *Setup CR3187 move.b # $41,TIME_CR2 *Setup CR2188 move.b # $81,TIME_CRX *Setup CR1189 move.b # $80,TIME_CRX *Start the timers190 * 191 move.w (a7)+,sr *Restore interrupts192 * 193 nullrts: rts *Return to caller194 * 195 .page 196 *==============================================================================197 *timeint -- timer interrupt handler198 *==============================================================================199 * 200 timeint: movem.l d0-d7/a0-a6,-(a7) *Save registers201 move.b TIME_CR2,d0 *Get timer interrupt status202 *------------------------------------------------------------------------------203 *process 1 MS timer204 *------------------------------------------------------------------------------205 btst.l #2,d0 *Check timer 3 status206 beq tmi02 *Jump if not active207 * 208 move.b TIME_T3H,d1 *Read timer 3 count209 lsl.w #8,d1 *...210 move.b TIME_T3L,d1 *...211 move.w d1,T3COUNT *... and save it212 * 213 addq.l #1,HZ_1K *Update 1ms clock (1 KHz)214 * 215 move.l d0,-(a7) *Preserve D0216 *------------------------------------------------------------------------------217 *process VSDD timer218 *------------------------------------------------------------------------------219 tst.w _vi_tag *Does the VSDD need service ?220 beq updtime *Jump if not221 * 222 move.w _vi_clk,d0 *Get VSDD scroll delay timer223 subq.w #1,d0 *Decrement timer224 move.w d0,_vi_clk *Update timer225 bne updtime *Jump if it's not zero yet226 * 227 move.w lclsadr,_v_odtab+12 *Update scroll address228 move.w lclscrl,_v_odtab+10 *Update scroll offset229 clr.w _vi_tag *Reset the tag230 * 231 .page 232 * 233 *------------------------------------------------------------------------------234 *process programable timers235 *------------------------------------------------------------------------------236 * 237 updtime: move.w #NTIMERS-1,d0 *Setup timer array counter238 lea _timers,a0 *Point at timer array239 * 240 tdcr: move.w (a0),d1 *Get timer array entry241 beq tdcr1 *Jump if already 0242 * 243 subq.w #1,d1 *Decrement timer244 * 245 tdcr1: move.w d1,(a0)+ *Store updated timer value246 dbra d0,tdcr *Loop until done247 * 248 *------------------------------------------------------------------------------249 *process timer hook vector250 *------------------------------------------------------------------------------251 movea.l TIMEVEC,a0 *Get RTC vector252 move.w #1,-(a7) *Pass 1 msec on stack253 jsr (a0) *Process RTC vector254 addq.l #2,a7 *Clean up stack255 * 256 move.l (a7)+,d0 *Restore D0257 * 258 .page 259 *------------------------------------------------------------------------------260 *process 5 Ms clock261 *------------------------------------------------------------------------------262 move.w tdiv1,d1 *Update divider263 addq.w #1,d1 *...264 move.w d1,tdiv1 *...265 * 266 cmpi.w #5,d1 *Do we need to update HZ_200 ?267 blt tmi02 *Jump if not268 * 269 addq.l #1,HZ_200 *Update 5ms clock (200 Hz)270 *------------------------------------------------------------------------------271 *process 20 Ms floppy clock272 *------------------------------------------------------------------------------273 move.w tdiv2,d1 *Update divider274 addq.w #1,d1 *...275 move.w d1,tdiv2 *...276 * 277 cmpi.w #4,d1 *Do we need to update FRCLOCK ?278 blt tmi01 *Jump if not279 * 280 addq.l #1,FRCLOCK *Update 20 Ms clock (50 Hz)281 tst.w FLOCK *See if floppy is active282 bne tmi00 *Don't call FLOPVBL if so283 * 284 jsr FLOPVBL *Check on the floppy285 * 286 tmi00: move.w #0,tdiv2 *Reset tdiv2287 * 288 tmi01: move.w #0,tdiv1 *Reset tdiv1289 * 290 .page 291 *------------------------------------------------------------------------------292 *process PLL timers293 *------------------------------------------------------------------------------294 * 295 tmi02: btst.l #0,d0 *Check timer 1 int296 beq tmi03 *Jump if not set297 * 298 move.b TIME_T1H,d1 *Read timer 1 to clear int.299 move.b TIME_T1L,d1 *...300 * 301 tmi03: btst.l #1,d0 *Check for timer 2 int.302 beq tmi04 *Jump if not set303 * 304 move.b TIME_T2H,d1 *Read timer 2 to clear int.305 move.b TIME_T2L,d1 *...306 * 307 .page 308 *------------------------------------------------------------------------------309 *update score frame counter310 *------------------------------------------------------------------------------311 tst.w FC_SW *Should we update the frame ?312 beq tmi04 *Jump if not313 * 314 bmi tmi05 *Jump if we count down315 * 316 move.l FC_VAL,d0 *Get the frame count317 cmp.l #FCMAX,d0 *See it we've topped out318 bge tmi06 *Jump if limit was hit319 * 320 addq.l #1,d0 *Count up 1 frame321 move.l d0,FC_VAL *Store updated frame count322 * 27 28 .xdef _tsetup | tsetup() -- timer setup function 29 .xdef timeint | timer interrupt handler 30 31 .xdef _M1IoRec | MIDI channel 1 IoRec 32 .xdef _M2IoRec | MIDI channel 2 IoRec 33 .xdef _S1IoRec | RS232 channel 1 IoRec 34 .xdef _S2IoRec | RS232 channel 2 IoRec 35 .xdef _timers | timer array -- short timers[NTIMERS] 36 .xdef _vi_clk | VSDD scroll delay timer 37 .xdef _vi_tag | VSDD VI tag 38 39 .xref lclsadr | score object base address 40 .xref lclscrl | score object scroll offset 41 .xref _v_odtab | VSDD object descriptor table 42 43 .page 44 | ============================================================================== 45 46 FRAMES = 0 | set non-zero to enable frame pulses 47 48 | Equates to variables in bios.s: 49 | ------------------------------- 50 | These variables are permanently assigned. 51 52 TIMEVEC = 0x00000400 | LONG - System timer trap vector 53 54 FC_SW = 0x00000420 | WORD - Frame clock switch 55 FC_VAL = 0x00000422 | LONG - Frame clock value 56 57 HZ_1K = 0x0000049A | LONG - 1000 Hz clock 58 HZ_200 = 0x0000049E | LONG - 200 Hz clock 59 FRCLOCK = 0x000004A2 | LONG - 50 Hz clock 60 61 T3COUNT = 0x000004AA | WORD - Timer 3 count 62 63 | ------------------------------------------------------------------------------ 64 65 | WARNING: The address of "FLOCK" depends on the version of the bios EPROM. 66 | The address below is for EPROMs dated 1988-04-18 or 1988-06-20 ONLY. 67 68 FLOCK = 0x00000E0C | WORD - Floppy semaphore <<<===== 69 70 | ============================================================================== 71 72 | Equates to routines in bios.s: 73 | ------------------------------ 74 75 | WARNING: The address of "FLOPVBL" depends on the version of the bios EPROM. 76 | The address below is for EPROMs dated 1988-04-18 or 1988-06-20 ONLY. 77 78 FLOPVBL = 0x001015EE | floppy VI handler address <<<===== 79 80 | ============================================================================== 81 82 .page 83 84 | Hardware address equates: 85 | ------------------------- 86 TI_VEC = 0x00000070 | Timer interrupt autovector 87 88 TIMER = 0x003A0001 | Timer base address 89 M1_ACIA = 0x003AC001 | MIDI ACIA channel 1 base address 90 91 | ------------------------------------------------------------------------------ 92 93 | Timer register equates: 94 | ----------------------- 95 TIME_CRX = TIMER | Control register 1 or 3 96 TIME_CR2 = TIMER+2 | Control register 2 97 TIME_T1H = TIMER+4 | Timer 1 high byte 98 TIME_T1L = TIMER+6 | Timer 1 low byte 99 TIME_T2H = TIMER+8 | Timer 2 high byte 100 TIME_T2L = TIMER+10 | Timer 2 low byte 101 TIME_T3H = TIMER+12 | Timer 3 high byte 102 TIME_T3L = TIMER+14 | Timer 3 low byte 103 104 | Serial I/O equates: 105 | ------------------- 106 ACIA_CFR = 2 | CFR offset from ACIA base 107 DTR_BIT = 1 | DTR bit in ACIA CFR1 108 109 IO_CFR1 = 29 | cfr1 offset in M1IoRec 110 111 | ============================================================================== 112 113 | Miscellaneous equates: 114 | ---------------------- 115 IPL7 = 0x0700 | IPL mask for interrupt disable 116 117 FCMAX = 0x00FFFFFF | Maximum frame counter value 118 FCMIN = 0x00000000 | Minimum frame counter value 119 120 NTIMERS = 8 | Number of timers in the timer array 121 122 XBIOS = 14 | XBIOS TRAP number 123 X_PIOREC = 0 | X_PIOREC code 124 SR1_DEV = 0 | RS232 ACIA channel 1 125 SR2_DEV = 1 | RS232 ACIA channel 2 126 MC1_DEV = 3 | MIDI ACIA channel 1 127 MC2_DEV = 4 | MIDI ACIA channel 2 128 | ============================================================================== 129 130 .page 131 | ============================================================================== 132 | _tsetup -- tsetup() -- timer setup function 133 | ============================================================================== 134 135 _tsetup: move.w sr,-(a7) | Save old interrupt mask 136 ori.w #IPL7,sr | Disable interrupts 137 138 move.w #SR1_DEV,-(a7) | Establish S1IoRec 139 move.w #X_PIOREC,-(a7) | ... 140 trap #XBIOS | ... 141 add.l #4,a7 | ... 142 move.l d0,_S1IoRec | ... 143 144 move.w #SR2_DEV,-(a7) | Establish S2IoRec 145 move.w #X_PIOREC,-(a7) | ... 146 trap #XBIOS | ... 147 add.l #4,a7 | ... 148 move.l d0,_S2IoRec | ... 149 150 move.w #MC1_DEV,-(a7) | Establish M1IoRec 151 move.w #X_PIOREC,-(a7) | ... 152 trap #XBIOS | ... 153 add.l #4,a7 | ... 154 move.l d0,_M1IoRec | ... 155 156 move.w #MC2_DEV,-(a7) | Establish M2IoRec 157 move.w #X_PIOREC,-(a7) | ... 158 trap #XBIOS | ... 159 add.l #4,a7 | ... 160 move.l d0,_M2IoRec | ... 161 162 .page 163 164 clr.w FC_SW | Stop the frame clock 165 clr.l FC_VAL | ... and reset it 166 clr.w _vi_tag | Clear VSDD VI tag 167 clr.w _vi_clk | Clear VSDD delay timer 168 clr.w lclsadr | Clear score scroll address 169 clr.w lclscrl | Clear score scroll offset 170 171 lea _timers,a0 | Point at timer array 172 move.w #NTIMERS-1,d0 | Setup to clear timer array 173 174 tclr: clr.w (a0)+ | Clear a timer array entry 175 dbra d0,tclr | Loop until done 176 177 move.l #nullrts,TIMEVEC | Set timer interrupt vector 178 move.l #timeint,TI_VEC | Set timer trap vector 179 180 move.b #0x00,TIME_T1H | Setup timer 1 (PLL) 181 move.b #0x1F,TIME_T1L | ... for divide by 64 182 move.b #0x0C,TIME_T2H | Setup timer 2 (FC) 183 move.b #0x7F,TIME_T2L | ... for divide by 3200 184 move.b #0x03,TIME_T3H | Setup timer 3 (RTC) 185 move.b #0x20,TIME_T3L | ... for 1Ms interval 186 move.b #0x42,TIME_CRX | Setup CR3 187 move.b #0x41,TIME_CR2 | Setup CR2 188 move.b #0x81,TIME_CRX | Setup CR1 189 move.b #0x80,TIME_CRX | Start the timers 190 191 move.w (a7)+,sr | Restore interrupts 192 193 nullrts: rts | Return to caller 194 195 .page 196 | ============================================================================== 197 | timeint -- timer interrupt handler 198 | ============================================================================== 199 200 timeint: movem.l d0-d7/a0-a6,-(a7) | Save registers 201 move.b TIME_CR2,d0 | Get timer interrupt status 202 | ------------------------------------------------------------------------------ 203 | process 1 MS timer 204 | ------------------------------------------------------------------------------ 205 btst.l #2,d0 | Check timer 3 status 206 beq tmi02 | Jump if not active 207 208 move.b TIME_T3H,d1 | Read timer 3 count 209 lsl.w #8,d1 | ... 210 move.b TIME_T3L,d1 | ... 211 move.w d1,T3COUNT | ... and save it 212 213 addq.l #1,HZ_1K | Update 1ms clock (1 KHz) 214 215 move.l d0,-(a7) | Preserve D0 216 | ------------------------------------------------------------------------------ 217 | process VSDD timer 218 | ------------------------------------------------------------------------------ 219 tst.w _vi_tag | Does the VSDD need service ? 220 beq updtime | Jump if not 221 222 move.w _vi_clk,d0 | Get VSDD scroll delay timer 223 subq.w #1,d0 | Decrement timer 224 move.w d0,_vi_clk | Update timer 225 bne updtime | Jump if it's not zero yet 226 227 move.w lclsadr,_v_odtab+12 | Update scroll address 228 move.w lclscrl,_v_odtab+10 | Update scroll offset 229 clr.w _vi_tag | Reset the tag 230 231 .page 232 233 | ------------------------------------------------------------------------------ 234 | process programable timers 235 | ------------------------------------------------------------------------------ 236 237 updtime: move.w #NTIMERS-1,d0 | Setup timer array counter 238 lea _timers,a0 | Point at timer array 239 240 tdcr: move.w (a0),d1 | Get timer array entry 241 beq tdcr1 | Jump if already 0 242 243 subq.w #1,d1 | Decrement timer 244 245 tdcr1: move.w d1,(a0)+ | Store updated timer value 246 dbra d0,tdcr | Loop until done 247 248 | ------------------------------------------------------------------------------ 249 | process timer hook vector 250 | ------------------------------------------------------------------------------ 251 movea.l TIMEVEC,a0 | Get RTC vector 252 move.w #1,-(a7) | Pass 1 msec on stack 253 jsr (a0) | Process RTC vector 254 addq.l #2,a7 | Clean up stack 255 256 move.l (a7)+,d0 | Restore D0 257 258 .page 259 | ------------------------------------------------------------------------------ 260 | process 5 Ms clock 261 | ------------------------------------------------------------------------------ 262 move.w tdiv1,d1 | Update divider 263 addq.w #1,d1 | ... 264 move.w d1,tdiv1 | ... 265 266 cmpi.w #5,d1 | Do we need to update HZ_200 ? 267 blt tmi02 | Jump if not 268 269 addq.l #1,HZ_200 | Update 5ms clock (200 Hz) 270 | ------------------------------------------------------------------------------ 271 | process 20 Ms floppy clock 272 | ------------------------------------------------------------------------------ 273 move.w tdiv2,d1 | Update divider 274 addq.w #1,d1 | ... 275 move.w d1,tdiv2 | ... 276 277 cmpi.w #4,d1 | Do we need to update FRCLOCK ? 278 blt tmi01 | Jump if not 279 280 addq.l #1,FRCLOCK | Update 20 Ms clock (50 Hz) 281 tst.w FLOCK | See if floppy is active 282 bne tmi00 | Don't call FLOPVBL if so 283 284 jsr FLOPVBL | Check on the floppy 285 286 tmi00: move.w #0,tdiv2 | Reset tdiv2 287 288 tmi01: move.w #0,tdiv1 | Reset tdiv1 289 290 .page 291 | ------------------------------------------------------------------------------ 292 | process PLL timers 293 | ------------------------------------------------------------------------------ 294 295 tmi02: btst.l #0,d0 | Check timer 1 int 296 beq tmi03 | Jump if not set 297 298 move.b TIME_T1H,d1 | Read timer 1 to clear int. 299 move.b TIME_T1L,d1 | ... 300 301 tmi03: btst.l #1,d0 | Check for timer 2 int. 302 beq tmi04 | Jump if not set 303 304 move.b TIME_T2H,d1 | Read timer 2 to clear int. 305 move.b TIME_T2L,d1 | ... 306 307 .page 308 | ------------------------------------------------------------------------------ 309 | update score frame counter 310 | ------------------------------------------------------------------------------ 311 tst.w FC_SW | Should we update the frame ? 312 beq tmi04 | Jump if not 313 314 bmi tmi05 | Jump if we count down 315 316 move.l FC_VAL,d0 | Get the frame count 317 cmp.l #FCMAX,d0 | See it we've topped out 318 bge tmi06 | Jump if limit was hit 319 320 addq.l #1,d0 | Count up 1 frame 321 move.l d0,FC_VAL | Store updated frame count 322 323 323 .ifne FRAMES 324 move.w sr,d1 *Preserve interrupt status325 ori.w # $0700,sr *Disable interrupts326 * 327 movea.l _M1IoRec,a0 *Point at M1IoRec328 move.b IO_CFR1(a0),d0 *Get MIDI-1 CFR1 value329 or.b # $80,d0 *Force MSB = 1 for CFR1 output330 movea.l #M1_ACIA,a0 *Point at MIDI-1 ACIA channel331 bchg.l #DTR_BIT,d0 *Toggle DTR for output332 move.b d0,ACIA_CFR(a0) *Output toggled DTR333 bchg.l #DTR_BIT,d0 *Toggle DTR for output334 move.b d0,ACIA_CFR(a0) *Output toggled DTR335 move.w d1,sr *Restore interrupts324 move.w sr,d1 | Preserve interrupt status 325 ori.w #0x0700,sr | Disable interrupts 326 327 movea.l _M1IoRec,a0 | Point at M1IoRec 328 move.b IO_CFR1(a0),d0 | Get MIDI-1 CFR1 value 329 or.b #0x80,d0 | Force MSB = 1 for CFR1 output 330 movea.l #M1_ACIA,a0 | Point at MIDI-1 ACIA channel 331 bchg.l #DTR_BIT,d0 | Toggle DTR for output 332 move.b d0,ACIA_CFR(a0) | Output toggled DTR 333 bchg.l #DTR_BIT,d0 | Toggle DTR for output 334 move.b d0,ACIA_CFR(a0) | Output toggled DTR 335 move.w d1,sr | Restore interrupts 336 336 .endc 337 * 338 bra tmi04 *Done339 * 340 tmi07: move.l #FCMIN,FC_VAL *Force hard limit, just in case341 bra tmi04 *Done342 * 343 tmi06: move.l #FCMAX,FC_VAL *Force hard limit, just in case344 bra tmi04 *Done345 * 346 tmi05: move.l FC_VAL,d0 *Get the frame count347 ble tmi07 *Done if already counted down348 * 349 subq.l #1,d0 *Count down 1 frame350 move.l d0,FC_VAL *Store udpated frame count351 bra tmi04 *Done352 * 353 nop *Filler to force equal paths354 * 355 tmi04: movem.l (a7)+,d0-d7/a0-a6 *Restore registers356 rte *Return to interrupted code357 * 358 .page 359 *==============================================================================337 338 bra tmi04 | Done 339 340 tmi07: move.l #FCMIN,FC_VAL | Force hard limit, just in case 341 bra tmi04 | Done 342 343 tmi06: move.l #FCMAX,FC_VAL | Force hard limit, just in case 344 bra tmi04 | Done 345 346 tmi05: move.l FC_VAL,d0 | Get the frame count 347 ble tmi07 | Done if already counted down 348 349 subq.l #1,d0 | Count down 1 frame 350 move.l d0,FC_VAL | Store udpated frame count 351 bra tmi04 | Done 352 353 nop | Filler to force equal paths 354 355 tmi04: movem.l (a7)+,d0-d7/a0-a6 | Restore registers 356 rte | Return to interrupted code 357 358 .page 359 | ============================================================================== 360 360 .bss 361 *==============================================================================362 * 363 *A note on tdiv1 and tdiv2:364 *--------------------------365 * 366 *tdiv1 and tdiv2 are actually defined in the bios, but since they could move367 *we define them here and ignore the ones in the bios.368 * 369 tdiv1: ds.w 1 *Timer divider 1 (divides HZ_1K)370 tdiv2: ds.w 1 *Timer divider 2 (divides HZ_200)371 * 372 *------------------------------------------------------------------------------373 * 374 _timers: ds.w NTIMERS *Timer array -- short timers[NTIMERS];375 * 376 _vi_clk: ds.w 1 *VSDD scroll delay timer377 _vi_tag: ds.w 1 *VSDD VI 'needs service' tag378 * 379 _S1IoRec: ds.l 1 *address of RS232 channel 1 IoRec380 _S2IoRec: ds.l 1 *address of RS232 channel 2 IoRec381 _M1IoRec: ds.l 1 *address of MIDI channel 1 IoRec382 _M2IoRec: ds.l 1 *address of MIDI channel 2 IoRec383 *==============================================================================384 * 361 | ============================================================================== 362 363 | A note on tdiv1 and tdiv2: 364 | -------------------------- 365 366 | tdiv1 and tdiv2 are actually defined in the bios, but since they could move 367 | we define them here and ignore the ones in the bios. 368 369 tdiv1: ds.w 1 | Timer divider 1 (divides HZ_1K) 370 tdiv2: ds.w 1 | Timer divider 2 (divides HZ_200) 371 372 | ------------------------------------------------------------------------------ 373 374 _timers: ds.w NTIMERS | Timer array -- short timers[NTIMERS]; 375 376 _vi_clk: ds.w 1 | VSDD scroll delay timer 377 _vi_tag: ds.w 1 | VSDD VI 'needs service' tag 378 379 _S1IoRec: ds.l 1 | address of RS232 channel 1 IoRec 380 _S2IoRec: ds.l 1 | address of RS232 channel 2 IoRec 381 _M1IoRec: ds.l 1 | address of MIDI channel 1 IoRec 382 _M2IoRec: ds.l 1 | address of MIDI channel 2 IoRec 383 | ============================================================================== 384 385 385 .end -
ram/tofpu.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *tofpu.s -- convert between millisecond time interval and FPU increment formats3 *Version 9 -- 1987-12-21 -- D.N. Lynx Crowe4 * 5 *unsigned short6 *tofpu(time)7 *unsigned short time;8 * 9 *Converts 'time' in milliseconds to FPU format.10 * 11 *unsigned short12 *fromfpu(fputime)13 *unsigned short fputime;14 * 15 *Converts 'fputime' from FPU format to milliseconds.16 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | tofpu.s -- convert between millisecond time interval and FPU increment formats 3 | Version 9 -- 1987-12-21 -- D.N. Lynx Crowe 4 5 | unsigned short 6 | tofpu(time) 7 | unsigned short time; 8 9 | Converts 'time' in milliseconds to FPU format. 10 11 | unsigned short 12 | fromfpu(fputime) 13 | unsigned short fputime; 14 15 | Converts 'fputime' from FPU format to milliseconds. 16 | ------------------------------------------------------------------------------ 17 17 .text 18 * 18 19 19 .xdef _tofpu 20 20 .xdef _fromfpu 21 * 22 TIME .equ 8 *WORD - time argument (either format)23 * 24 TCYCL .equ $3B000000 *LONG - scaled FPU cycle time (.4608)25 * 21 22 TIME = 8 | WORD - time argument (either format) 23 24 TCYCL = 0x3B000000 | LONG - scaled FPU cycle time (.4608) 25 26 26 .page 27 _tofpu: link a6,#0 *link stack frames28 move.w TIME(a6),d1 *get time interval29 beq notime *jump if zero time30 * 31 clr.w d2 *clear shift count32 * 33 sloop: btst #15,d1 *see if MSB is set yet34 bne gotexp *jump if so35 * 36 lsl.w d1 *shift time left a bit37 addq.w #1,d2 *increment the shift count38 cmpi.w #15,d2 *see if we've hit the maximum39 bne sloop *try again if not40 * 41 gotexp: move.l #TCYCL,d0 *divide FPU cycle time by shifted value42 divu d1,d0 *...43 andi.w # $FFF0,d0 *mask result44 or.w d2,d0 *set the exponent45 * 46 finis: unlk a6 *unlink stack frames47 rts *return to caller48 * 49 notime: clr.w d0 *zero time is zero ...50 bra finis *return value for zero time51 * 27 _tofpu: link a6,#0 | link stack frames 28 move.w TIME(a6),d1 | get time interval 29 beq notime | jump if zero time 30 31 clr.w d2 | clear shift count 32 33 sloop: btst #15,d1 | see if MSB is set yet 34 bne gotexp | jump if so 35 36 lsl.w #1,d1 | shift time left a bit 37 addq.w #1,d2 | increment the shift count 38 cmpi.w #15,d2 | see if we've hit the maximum 39 bne sloop | try again if not 40 41 gotexp: move.l #TCYCL,d0 | divide FPU cycle time by shifted value 42 divu d1,d0 | ... 43 andi.w #0xFFF0,d0 | mask result 44 or.w d2,d0 | set the exponent 45 46 finis: unlk a6 | unlink stack frames 47 rts | return to caller 48 49 notime: clr.w d0 | zero time is zero ... 50 bra finis | return value for zero time 51 52 52 .page 53 _fromfpu: link a6,#0 *link stack frames54 move.w TIME(a6),d1 *get FPU formatted time55 beq zerotime *done if it's zero56 * 57 move.w d1,d2 *extract shift count58 andi.w # $000F,d2 *...59 andi.w # $FFF0,d1 *extract mantissa60 beq zerotime *... just in case it's zero (an error)61 * 62 move.l #TCYCL,d0 *get FPU cycle time63 divu d1,d0 *divide by mantissa64 bvc divok *jump if divide ok65 * 66 move.w # $FFFF,d0 *jam maximum value for overflow67 * 68 divok: lsr.w d2,d0 *shift result into position69 * 70 byebye: unlk a6 *unlink stack frames71 rts *return to caller72 * 73 zerotime: clr.l d0 *return a zero result74 bra byebye *...75 * 53 _fromfpu: link a6,#0 | link stack frames 54 move.w TIME(a6),d1 | get FPU formatted time 55 beq zerotime | done if it's zero 56 57 move.w d1,d2 | extract shift count 58 andi.w #0x000F,d2 | ... 59 andi.w #0xFFF0,d1 | extract mantissa 60 beq zerotime | ... just in case it's zero (an error) 61 62 move.l #TCYCL,d0 | get FPU cycle time 63 divu d1,d0 | divide by mantissa 64 bvc divok | jump if divide ok 65 66 move.w #0xFFFF,d0 | jam maximum value for overflow 67 68 divok: lsr.w d2,d0 | shift result into position 69 70 byebye: unlk a6 | unlink stack frames 71 rts | return to caller 72 73 zerotime: clr.l d0 | return a zero result 74 bra byebye | ... 75 76 76 .end -
rom/bios.s
rf40a309 r4f508e6 1 ******************************************************************************** 2 * * 3 * bios.s -- BIOS for the Buchla 700 and NASA 3D Helmet Display * 4 * ------ -------------------------------------------------- * 5 * * 6 * See VM1,VM2 and VDATE for version and date * 7 * Written by D.N. Lynx Crowe * 8 * * 9 * Very loosely based on ideas from: * 10 * * 11 * "Atari ST Internals", by Abacus Software, * 12 * "A Hitchhiker's Guide to the BIOS", by Atari, * 13 * "DOS Technical Reference", by IBM, * 14 *"DOS/360", by IBM,15 * "CP/M" , by Digital Research, and, of course, * 16 * "Unix (tm)", by AT&T, et al. * 17 * * 18 * After all, Why re-invent the wheel? * 19 * * 20 * Some of the functions are the same as Ataris, but quite a few are different, * 21 * and our I/O configuration is much different, so BEWARE! Make no * 22 * assumptions, and read the documentation and comments very carefully. * 23 * * 24 * Especially watch out for the extended BIOS functions. Most of them * 25 * are nothing at all like the Atari / GEMDOS extended bios functions, * 26 * and even the ones that are similar have different numbers. * 27 ******************************************************************************** 28 * 1 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 2 | | 3 | bios.s -- BIOS for the Buchla 700 and NASA 3D Helmet Display | 4 | ------ -------------------------------------------------- | 5 | | 6 | See VM1,VM2 and VDATE for version and date | 7 | Written by D.N. Lynx Crowe | 8 | | 9 | Very loosely based on ideas from: | 10 | | 11 | "Atari ST Internals", by Abacus Software, | 12 | "A Hitchhiker's Guide to the BIOS", by Atari, | 13 | "DOS Technical Reference", by IBM, | 14 | "DOS/360", by IBM, 15 | "CP/M" , by Digital Research, and, of course, | 16 | "Unix (tm)", by AT&T, et al. | 17 | | 18 | After all, Why re-invent the wheel? | 19 | | 20 | Some of the functions are the same as Ataris, but quite a few are different, | 21 | and our I/O configuration is much different, so BEWARE! Make no | 22 | assumptions, and read the documentation and comments very carefully. | 23 | | 24 | Especially watch out for the extended BIOS functions. Most of them | 25 | are nothing at all like the Atari / GEMDOS extended bios functions, | 26 | and even the ones that are similar have different numbers. | 27 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 28 29 29 .text 30 * 31 *Version and date32 *----------------33 VM1 .equ 18 *First part of version number34 VM2 .equ 0 *Second part of version number35 VDATE .equ $19880620 *Version date36 * 37 BUCHLA .equ 1 *Non-Zero for Buchla 700, 0 for NASA38 NASASIO .equ 0 *Non-zero for NASA, 0 for Buchla addr.39 * 40 FL_SKR .equ $00 *Seek rate (WD1772, 6Ms/step)41 ************************************************************************* 42 * 43 .page 44 * 45 .xref start_ *Where ROMP starts46 .xref _errno *Start of ROMP bss space47 * 48 .xdef basepage *Pseudo base page for romp49 .xdef _rsflag *Register save area overflow flag50 * 30 31 | Version and date 32 | ---------------- 33 VM1 = 18 | First part of version number 34 VM2 = 0 | Second part of version number 35 VDATE = 0x19880620 | Version date 36 37 BUCHLA = 1 | Non-Zero for Buchla 700, 0 for NASA 38 NASASIO = 0 | Non-zero for NASA, 0 for Buchla addr. 39 40 FL_SKR = 0x00 | Seek rate (WD1772, 6Ms/step) 41 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 42 43 .page 44 45 .xref start_ | Where ROMP starts 46 .xref _errno | Start of ROMP bss space 47 48 .xdef basepage | Pseudo base page for romp 49 .xdef _rsflag | Register save area overflow flag 50 51 51 .ifne BUCHLA 52 * 53 .xdef _hdvini *Disk init54 * 55 .endc 56 * 57 .xdef _wzcrsh *ROMP crash flag58 .xdef _crshvc *Crash vector59 .xdef _crshsr *Crash SR60 .xdef _crshpc *Crash PC61 .xdef _crshsp *Crash SP62 .xdef _crshus *Crash USP63 .xdef _crshrg *Crash SP registers64 .xdef _crshst *Crash top of stack65 * 66 .page 67 * 52 53 .xdef _hdvini | Disk init 54 55 .endc 56 57 .xdef _wzcrsh | ROMP crash flag 58 .xdef _crshvc | Crash vector 59 .xdef _crshsr | Crash SR 60 .xdef _crshpc | Crash PC 61 .xdef _crshsp | Crash SP 62 .xdef _crshus | Crash USP 63 .xdef _crshrg | Crash SP registers 64 .xdef _crshst | Crash top of stack 65 66 .page 67 68 68 .ifne BUCHLA 69 * 69 70 70 .xdef _hz_1k 71 71 .xdef _hz_200 … … 74 74 .xdef t2count 75 75 .xdef t3count 76 * 76 77 77 .xdef nflops 78 78 .xdef disknum … … 81 81 .xdef flock 82 82 .xdef fverify 83 * 83 84 84 .xdef retrycnt 85 85 .xdef wpstatus 86 86 .xdef wplatch 87 87 .xdef bootdev 88 * 88 89 89 .xdef cdev 90 90 .xdef ctrack … … 92 92 .xdef cside 93 93 .xdef ccount 94 * 94 95 95 .xdef cdma 96 96 .xdef edma 97 97 .xdef tmpdma 98 98 .xdef rseed 99 * 99 100 100 .xdef savptr 101 * 101 102 102 .xdef flpsrsv 103 103 .xdef flpregs 104 * 104 105 105 .xdef dsb0 106 106 .xdef dsb1 107 * 107 108 108 .xdef dskmode 109 109 .xdef dskerrs 110 110 .xdef drvbpbs 111 * 112 .endc 113 * 111 112 .endc 113 114 114 .xdef biostop 115 * 116 .page 117 * 118 *Some critical equates:119 *----------------------120 *Interrupt masks121 *---------------122 IPL3 .equ $0300 *IPL 3 value for sr123 IPL4 .equ $0400 *IPL 4 value for sr124 IPL7 .equ $0700 *IPL 7 value for sr (4 for debug)125 * 115 116 .page 117 118 | Some critical equates: 119 | ---------------------- 120 | Interrupt masks 121 | --------------- 122 IPL3 = 0x0300 | IPL 3 value for sr 123 IPL4 = 0x0400 | IPL 4 value for sr 124 IPL7 = 0x0700 | IPL 7 value for sr (4 for debug) 125 126 126 .ifne BUCHLA 127 * 128 INITIPL .equ IPL3+$2000 *Initial Internal Priority Level129 * 130 .endc 131 * 127 128 INITIPL = IPL3+0x2000 | Initial Internal Priority Level 129 130 .endc 131 132 132 .ifeq BUCHLA 133 * 134 INITIPL .equ IPL4+$2000 *Initial Internal Priority Level135 * 136 .endc 137 * 138 *Memory allocation139 *-----------------133 134 INITIPL = IPL4+0x2000 | Initial Internal Priority Level 135 136 .endc 137 138 | Memory allocation 139 | ----------------- 140 140 .ifeq BUCHLA 141 * 142 TPA .equ $008000 *Put TPA 32K up from the bottom143 * 144 .endc 145 * 141 142 TPA = 0x008000 | Put TPA 32K up from the bottom 143 144 .endc 145 146 146 .ifne BUCHLA 147 * 148 TPA .equ $010000 *Put TPA 64K up from the bottom149 * 150 .endc 151 * 152 SSTACK .equ TPA *Put system stack just below TPA153 * 154 p_bbase .equ $0018 *Basepage offset to bss base155 p_blen .equ $001C *Basepage offset to bss length156 * 157 *It's magic ...158 *--------------159 FMAGIC .equ $87654321 *Magic for formatting160 RETRYIT .equ $10000 *Magic for re-try from criter161 RSMAGIC .equ $78563412 *Magic for register save area OK162 * 163 *Miscellaneous constants164 *-----------------------165 FCMAX .equ $00FFFFFF *Maximum frame counter value (24 bits)166 * 167 .page 168 * 169 *CFR0 Baud Rates:170 *----------------171 BR_300 .equ $04172 BR_600 .equ $05173 BR_1200 .equ $06174 BR_1800 .equ $07175 BR_2400 .equ $08176 BR_3600 .equ $09177 BR_4800 .equ $0A178 BR_7200 .equ $0B179 BR_9600 .equ $0C180 BR_19K2 .equ $0D181 BR_EXT .equ $0F182 * 183 *CFR0 Stop bits (includes TBR select bit):184 *-----------------------------------------185 NSB_1 .equ $40186 NSB_2 .equ $60187 * 188 *CFR1 Number of Data Bits (includes MSB):189 *----------------------------------------190 NDB_5 .equ $80191 NDB_6 .equ $A0192 NDB_7 .equ $C0193 NDB_8 .equ $E0194 * 195 *CFR1 Parity Selection:196 *----------------------197 P_ODD .equ $04198 P_EVEN .equ $0C199 P_MARK .equ $14200 P_SPACE .equ $1C201 * 202 P_NONE .equ $00203 * 204 *Line Discipline:205 *----------------206 L_NUL .equ $00 *No protocol207 L_XON .equ $01 *XON/XOFF208 L_RTS .equ $02 *RTS/CTS209 * 210 .page 211 * 212 *I/O Buffer Sizes:213 *-----------------214 SR1IBS .equ256215 SR1OBS .equ256216 SR2IBS .equ256217 SR2OBS .equ256218 * 147 148 TPA = 0x010000 | Put TPA 64K up from the bottom 149 150 .endc 151 152 SSTACK = TPA | Put system stack just below TPA 153 154 p_bbase = 0x0018 | Basepage offset to bss base 155 p_blen = 0x001C | Basepage offset to bss length 156 157 | It's magic ... 158 | -------------- 159 FMAGIC = 0x87654321 | Magic for formatting 160 RETRYIT = 0x10000 | Magic for re-try from criter 161 RSMAGIC = 0x78563412 | Magic for register save area OK 162 163 | Miscellaneous constants 164 | ----------------------- 165 FCMAX = 0x00FFFFFF | Maximum frame counter value (24 bits) 166 167 .page 168 169 | CFR0 Baud Rates: 170 | ---------------- 171 BR_300 = 0x04 172 BR_600 = 0x05 173 BR_1200 = 0x06 174 BR_1800 = 0x07 175 BR_2400 = 0x08 176 BR_3600 = 0x09 177 BR_4800 = 0x0A 178 BR_7200 = 0x0B 179 BR_9600 = 0x0C 180 BR_19K2 = 0x0D 181 BR_EXT = 0x0F 182 183 | CFR0 Stop bits (includes TBR select bit): 184 | ----------------------------------------- 185 NSB_1 = 0x40 186 NSB_2 = 0x60 187 188 | CFR1 Number of Data Bits (includes MSB): 189 | ---------------------------------------- 190 NDB_5 = 0x80 191 NDB_6 = 0xA0 192 NDB_7 = 0xC0 193 NDB_8 = 0xE0 194 195 | CFR1 Parity Selection: 196 | ---------------------- 197 P_ODD = 0x04 198 P_EVEN = 0x0C 199 P_MARK = 0x14 200 P_SPACE = 0x1C 201 202 P_NONE = 0x00 203 204 | Line Discipline: 205 | ---------------- 206 L_NUL = 0x00 | No protocol 207 L_XON = 0x01 | XON/XOFF 208 L_RTS = 0x02 | RTS/CTS 209 210 .page 211 212 | I/O Buffer Sizes: 213 | ----------------- 214 SR1IBS = 256 215 SR1OBS = 256 216 SR2IBS = 256 217 SR2OBS = 256 218 219 219 .ifne BUCHLA 220 * 221 MC1IBS .equ512222 MC1OBS .equ256223 MC2IBS .equ512224 MC2OBS .equ256225 * 226 .endc 227 * 228 *Line Disciplines:229 *-----------------230 SR1DISC .equL_XON231 SR2DISC .equL_XON232 * 220 221 MC1IBS = 512 222 MC1OBS = 256 223 MC2IBS = 512 224 MC2OBS = 256 225 226 .endc 227 228 | Line Disciplines: 229 | ----------------- 230 SR1DISC = L_XON 231 SR2DISC = L_XON 232 233 233 .ifne BUCHLA 234 * 235 MC1DISC .equL_NUL236 MC2DISC .equL_NUL237 * 238 .endc 239 * 240 *CFR Setings:241 *------------242 SR1CFR0 .equBR_9600+NSB_1243 SR1CFR1 .equNDB_8+P_NONE244 SR2CFR0 .equBR_9600+NSB_1245 SR2CFR1 .equNDB_8+P_NONE246 * 234 235 MC1DISC = L_NUL 236 MC2DISC = L_NUL 237 238 .endc 239 240 | CFR Setings: 241 | ------------ 242 SR1CFR0 = BR_9600+NSB_1 243 SR1CFR1 = NDB_8+P_NONE 244 SR2CFR0 = BR_9600+NSB_1 245 SR2CFR1 = NDB_8+P_NONE 246 247 247 .ifne BUCHLA 248 * 249 MC1CFR0 .equBR_EXT+NSB_1250 MC1CFR1 .equNDB_8+P_NONE251 MC2CFR0 .equBR_EXT+NSB_1252 MC2CFR1 .equNDB_8+P_NONE253 * 254 .endc 255 * 256 .page 257 * 258 *I/O Addresses:259 *--------------260 VSDDINIT .equ $200400 *VSDD initial register base address261 VSDDDATA .equ $200000 *VSDD data segment base address262 * 248 249 MC1CFR0 = BR_EXT+NSB_1 250 MC1CFR1 = NDB_8+P_NONE 251 MC2CFR0 = BR_EXT+NSB_1 252 MC2CFR1 = NDB_8+P_NONE 253 254 .endc 255 256 .page 257 258 | I/O Addresses: 259 | -------------- 260 VSDDINIT = 0x200400 | VSDD initial register base address 261 VSDDDATA = 0x200000 | VSDD data segment base address 262 263 263 .ifeq BUCHLA 264 * 264 265 265 .ifeq NASASIO 266 * 267 SR1ACIA .equ $3A8001 *Serial-1 ACIA base address (BUCHLA)268 SR2ACIA .equ $3A8009 *Serial-2 ACIA base address269 * 270 .endc 271 * 266 267 SR1ACIA = 0x3A8001 | Serial-1 ACIA base address (BUCHLA) 268 SR2ACIA = 0x3A8009 | Serial-2 ACIA base address 269 270 .endc 271 272 272 .ifne NASASIO 273 * 274 SR1ACIA .equ $398001 *Serial-1 ACIA base address (NASA)275 SR2ACIA .equ $398009 *Serial-2 ACIA base address276 * 277 .endc 278 * 279 .endc 280 * 273 274 SR1ACIA = 0x398001 | Serial-1 ACIA base address (NASA) 275 SR2ACIA = 0x398009 | Serial-2 ACIA base address 276 277 .endc 278 279 .endc 280 281 281 .ifne BUCHLA 282 * 283 FPUBASE .equ $180000 *FPU base address284 TIMER .equ $3A0001 *Timer base address285 LCD .equ $3A4001 *LCD driver base address286 SR1ACIA .equ $3A8001 *Serial-1 ACIA base address (BUCHLA)287 SR2ACIA .equ $3A8009 *Serial-2 ACIA base address288 MC1ACIA .equ $3AC001 *MIDI-1 ACIA base address289 MC2ACIA .equ $3AC009 *MIDI-2 ACIA base address290 FLOPPY .equ $3B0001 *Floppy controller base address291 PSG .equ $3B4001 *Sound chip base address292 LEDS .equ $3B8001 *LED driver base address293 ANALOG .equ $3BC001 *Analog processor base address294 * 295 *FPU address offsets and misc. values296 * 297 FPU_CTL .equ $4000 *FPU control298 * 299 FPU_IN .equ $4000 *FPU input address300 FPU_CLR .equ $6000 *FPU interrupt reset address301 * 302 FPU_RST .equ $0015 *FPU reset value303 * 304 *PSG address offsets305 * 306 PSG_RD .equ PSG *Read PSG data307 PSG_WL .equ PSG *Write PSG address latch308 PSG_WD .equ PSG+2 *Write PSG data309 * 310 .endc 311 * 312 *VSDD data structure offsets313 * 314 VSDD_REG .equ VSDDDATA *Registers315 VSDD_AT .equ VSDDDATA+$0100 *Access Table316 * 282 283 FPUBASE = 0x180000 | FPU base address 284 TIMER = 0x3A0001 | Timer base address 285 LCD = 0x3A4001 | LCD driver base address 286 SR1ACIA = 0x3A8001 | Serial-1 ACIA base address (BUCHLA) 287 SR2ACIA = 0x3A8009 | Serial-2 ACIA base address 288 MC1ACIA = 0x3AC001 | MIDI-1 ACIA base address 289 MC2ACIA = 0x3AC009 | MIDI-2 ACIA base address 290 FLOPPY = 0x3B0001 | Floppy controller base address 291 PSG = 0x3B4001 | Sound chip base address 292 LEDS = 0x3B8001 | LED driver base address 293 ANALOG = 0x3BC001 | Analog processor base address 294 295 | FPU address offsets and misc. values 296 297 FPU_CTL = 0x4000 | FPU control 298 299 FPU_IN = 0x4000 | FPU input address 300 FPU_CLR = 0x6000 | FPU interrupt reset address 301 302 FPU_RST = 0x0015 | FPU reset value 303 304 | PSG address offsets 305 306 PSG_RD = PSG | Read PSG data 307 PSG_WL = PSG | Write PSG address latch 308 PSG_WD = PSG+2 | Write PSG data 309 310 .endc 311 312 | VSDD data structure offsets 313 314 VSDD_REG = VSDDDATA | Registers 315 VSDD_AT = VSDDDATA+0x0100 | Access Table 316 317 317 .ifne BUCHLA 318 * 319 *Timer registers320 * 321 TIME_CRX .equ TIMER *Control register 1 or 3322 TIME_CR2 .equ TIMER+2 *Control register 2323 TIME_T1H .equ TIMER+4 *Timer 1 high byte324 TIME_T1L .equ TIMER+6 *Timer 1 low byte325 TIME_T2H .equ TIMER+8 *Tiemr 2 high byte326 TIME_T2L .equ TIMER+10 *Timer 2 low byte327 TIME_T3H .equ TIMER+12 *Timer 3 high byte328 TIME_T3L .equ TIMER+14 *Timer 3 low byte329 * 330 .endc 331 * 332 *ACIA Register offsets:333 *----------------------334 ACIA_IER .equ 0 *ACIA IER offset335 ACIA_ISR .equ 0 *ACIA ISR offset336 ACIA_CSR .equ 2 *ACIA CSR offset337 ACIA_CFR .equ 2 *ACIA CFR offset338 ACIA_TBR .equ 4 *ACIA TBR offset339 ACIA_TDR .equ 6 *ACIA TDR offset340 ACIA_RDR .equ 6 *ACIA RDR offset341 * 342 .page 343 * 318 319 | Timer registers 320 321 TIME_CRX = TIMER | Control register 1 or 3 322 TIME_CR2 = TIMER+2 | Control register 2 323 TIME_T1H = TIMER+4 | Timer 1 high byte 324 TIME_T1L = TIMER+6 | Timer 1 low byte 325 TIME_T2H = TIMER+8 | Tiemr 2 high byte 326 TIME_T2L = TIMER+10 | Timer 2 low byte 327 TIME_T3H = TIMER+12 | Timer 3 high byte 328 TIME_T3L = TIMER+14 | Timer 3 low byte 329 330 .endc 331 332 | ACIA Register offsets: 333 | ---------------------- 334 ACIA_IER = 0 | ACIA IER offset 335 ACIA_ISR = 0 | ACIA ISR offset 336 ACIA_CSR = 2 | ACIA CSR offset 337 ACIA_CFR = 2 | ACIA CFR offset 338 ACIA_TBR = 4 | ACIA TBR offset 339 ACIA_TDR = 6 | ACIA TDR offset 340 ACIA_RDR = 6 | ACIA RDR offset 341 342 .page 343 344 344 .ifne BUCHLA 345 * 346 *Floppy register offsets:347 *------------------------348 DSKCMD .equ 0 *Command / status349 DSKTRK .equ 2 *Track350 DSKSEC .equ 4 *Sector351 DSKDAT .equ 6 *Data352 * 353 *Miscellaneous equates:354 *----------------------355 FL_NC .equ $02 *Non-compensated R/W/F bit356 * 357 APISIZE .equ 256 *Analog processor buffer size358 * 359 *Floppy commands:360 *----------------361 FL_RS .equ $80 *Read sector362 FL_RM .equ $90 *Read multiple363 FL_WS .equ $A0 *Write sector364 FL_WT .equ $F0 *Write track (format)365 FL_FR .equ $D0 *Force reset366 FL_SK .equ $10 *Seek367 FL_SV .equ $14 *Seek w/verify368 * 369 .endc 370 * 371 .page 372 * 373 *iorec structure definitions:374 *----------------------------375 IORECLN .equ 40 *Length of an iorec structure376 * 377 ibuf .equ 0 *Input buffer base address378 ibufsize .equ 4 *Input buffer size (bytes)379 ibufhd .equ 6 *Input buffer head index380 ibuftl .equ 8 *Input buffer tail index381 ibuflow .equ 10 *Input buffer low water mark382 ibufhi .equ 12 *Input buffer high water mark383 obuf .equ 14 *Output buffer base address384 obufsize .equ 18 *Output buffer size (bytes)385 obufhd .equ 20 *Output buffer head index386 obuftl .equ 22 *Output buffer tail index387 obuflow .equ 24 *Output buffer low water mark388 obufhi .equ 26 *Output buffer high water mark389 cfr0 .equ 28 *ACIA CFR, MS bit = 0390 cfr1 .equ 29 *ACIA CFR, MS bit = 1391 flagxon .equ 30 *XON flag (non-zero = XOFF sent)392 flagxoff .equ 31 *XOFF flag (non-zero = active)393 linedisc .equ 32 *Line discipline flags394 erbyte .equ 33 *Last error byte395 isr .equ 34 *ACIA ISR on interrupt396 csr .equ 35 *ACIA CSR on interrupt397 errct .equ 36 *Error count (FRM/OVR/BRK)398 ibfct .equ 38 *Input buffer full count399 * 400 .page 401 * 402 *Error codes:403 *------------404 ERR01 .equ -1 *All purpose error405 ERR02 .equ -2 *Drive not ready406 ERR03 .equ -3 *Unknown command407 ERR04 .equ -4 *CRC Error408 ERR05 .equ -5 *Invalid request409 ERR06 .equ -6 *Seek error410 ERR07 .equ -7 *Unknown media411 ERR08 .equ -8 *Sector not found412 ERR09 .equ -9 *End of media (out of paper)413 ERR10 .equ -10 *Write fault414 ERR11 .equ -11 *Read fault415 ERR12 .equ -12 *General mishap416 ERR13 .equ -13 *Write protected417 ERR14 .equ -14 *Media changed418 ERR15 .equ -15 *Unknown device419 ERR16 .equ -16 *Bad sectors420 ERR17 .equ -17 *Insert disk421 * 422 .page 423 * 424 *In the Beginning...425 *-------------------426 * 427 *Low PROM -- Contains the initial sp (unused), and the initial pc,428 *as well as some version and creation date stuff and a copyright message,429 *just to be thorough about it.430 * 431 begin: bra.s biosinit *Jump to bios init432 * 433 vermsg: dc.b VM1,VM2 *Version number434 * 435 dc.l biosinit *Reset address (bios init)436 * 437 created: dc.l VDATE *Creation date438 * 439 copyrite: dc.b '{Copyright 1988 by ' *Copyright message440 dc.b 'D.N. Lynx Crowe}',0441 * 442 dc.l 0 *Some padding443 * 345 346 | Floppy register offsets: 347 | ------------------------ 348 DSKCMD = 0 | Command / status 349 DSKTRK = 2 | Track 350 DSKSEC = 4 | Sector 351 DSKDAT = 6 | Data 352 353 | Miscellaneous equates: 354 | ---------------------- 355 FL_NC = 0x02 | Non-compensated R/W/F bit 356 357 APISIZE = 256 | Analog processor buffer size 358 359 | Floppy commands: 360 | ---------------- 361 FL_RS = 0x80 | Read sector 362 FL_RM = 0x90 | Read multiple 363 FL_WS = 0xA0 | Write sector 364 FL_WT = 0xF0 | Write track (format) 365 FL_FR = 0xD0 | Force reset 366 FL_SK = 0x10 | Seek 367 FL_SV = 0x14 | Seek w/verify 368 369 .endc 370 371 .page 372 373 | iorec structure definitions: 374 | ---------------------------- 375 IORECLN = 40 | Length of an iorec structure 376 377 ibuf = 0 | Input buffer base address 378 ibufsize = 4 | Input buffer size (bytes) 379 ibufhd = 6 | Input buffer head index 380 ibuftl = 8 | Input buffer tail index 381 ibuflow = 10 | Input buffer low water mark 382 ibufhi = 12 | Input buffer high water mark 383 obuf = 14 | Output buffer base address 384 obufsize = 18 | Output buffer size (bytes) 385 obufhd = 20 | Output buffer head index 386 obuftl = 22 | Output buffer tail index 387 obuflow = 24 | Output buffer low water mark 388 obufhi = 26 | Output buffer high water mark 389 cfr0 = 28 | ACIA CFR, MS bit = 0 390 cfr1 = 29 | ACIA CFR, MS bit = 1 391 flagxon = 30 | XON flag (non-zero = XOFF sent) 392 flagxoff = 31 | XOFF flag (non-zero = active) 393 linedisc = 32 | Line discipline flags 394 erbyte = 33 | Last error byte 395 isr = 34 | ACIA ISR on interrupt 396 csr = 35 | ACIA CSR on interrupt 397 errct = 36 | Error count (FRM/OVR/BRK) 398 ibfct = 38 | Input buffer full count 399 400 .page 401 402 | Error codes: 403 | ------------ 404 ERR01 = -1 | All purpose error 405 ERR02 = -2 | Drive not ready 406 ERR03 = -3 | Unknown command 407 ERR04 = -4 | CRC Error 408 ERR05 = -5 | Invalid request 409 ERR06 = -6 | Seek error 410 ERR07 = -7 | Unknown media 411 ERR08 = -8 | Sector not found 412 ERR09 = -9 | End of media (out of paper) 413 ERR10 = -10 | Write fault 414 ERR11 = -11 | Read fault 415 ERR12 = -12 | General mishap 416 ERR13 = -13 | Write protected 417 ERR14 = -14 | Media changed 418 ERR15 = -15 | Unknown device 419 ERR16 = -16 | Bad sectors 420 ERR17 = -17 | Insert disk 421 422 .page 423 424 | In the Beginning... 425 | ------------------- 426 427 | Low PROM -- Contains the initial sp (unused), and the initial pc, 428 | as well as some version and creation date stuff and a copyright message, 429 | just to be thorough about it. 430 431 begin: bra.s biosinit | Jump to bios init 432 433 vermsg: dc.b VM1,VM2 | Version number 434 435 dc.l biosinit | Reset address (bios init) 436 437 created: dc.l VDATE | Creation date 438 439 copyrite: dc.b "{Copyright 1988 by " | Copyright message 440 dc.b "D.N. Lynx Crowe}",0 441 442 dc.l 0 | Some padding 443 444 444 .page 445 445 .even 446 * 447 *biosinit -- Setup the defaults for the BIOS448 *-------- -------------------------------449 biosinit: move.w # $2700,sr *Set sup mode, no interrupts450 move.l #SSTACK,a7 *Setup supervisor stack pointer451 * 452 lea badtrap,a1 *Set default trap vector453 adda.l # $02000000,a1 *... with trap # in 31..24454 lea 8,a0 *... for traps 2..255446 447 | biosinit -- Setup the defaults for the BIOS 448 | -------- ------------------------------- 449 biosinit: move.w #0x2700,sr | Set sup mode, no interrupts 450 move.l #SSTACK,a7 | Setup supervisor stack pointer 451 452 lea badtrap,a1 | Set default trap vector 453 adda.l #0x02000000,a1 | ... with trap # in 31..24 454 lea 8,a0 | ... for traps 2..255 455 455 move.l #253,d1 456 * 457 binit1: move.l a1,(a0)+ *Store trap vector458 adda.l # $01000000,a1 *Increment trap #459 dbf d1,binit1 *Loop until done460 * 461 lea biosram,a0 *Clear BIOS ram ...462 lea SSTACK-2,a1 *... from biosram to SSTACK-1463 * 464 binit2: move.w #0,(a0)+ *Zero a word465 cmpa.l a0,a1 *Last one ?466 bne binit2 *Loop if not467 * 468 move.l #rsarea,savptr *Setup pointer to register area469 move.l #RSMAGIC,_rsflag *Set magic in _rsflag470 * 471 move.l #nullrts,timevec *Set timer interrupt vector472 move.l #nullrts,critvec *Set critical error vector473 move.l #nullrts,termvec *Set process terminate vector474 move.l #nullrts,resvec3 *Set software vector 3475 move.l #nullrts,resvec4 *Set software vector 4476 move.l #nullrts,resvec5 *Set software vector 5477 move.l #nullrts,resvec6 *Set software vector 6478 move.l #nullrts,resvec7 *Set software vector 7479 * 480 move.l #hardhlt, $0008 *Set bus error vector481 move.l #nullrte, $0014 *Set divide error vector482 move.l #nullrte, $0018 *Set CHK vector483 move.l #nullrte, $001C *Set TRAPV vector484 move.l #nullrte, $0024 *Set trace vector485 * 486 move.l #nullrte, $0030 *Set reserved vector 12487 move.l #nullrte, $0034 *Set reserved vector 13488 move.l #nullrte, $0038 *Set reserved vector 14489 * 490 move.l #nullrte, $003C *Set uninitialized int. vector491 * 492 move.l #nullrte, $0040 *Set reserved vector 16493 move.l #nullrte, $0044 *Set reserved vector 17494 move.l #nullrte, $0048 *Set reserved vector 18495 move.l #nullrte, $004C *Set reserved vector 19496 move.l #nullrte, $0050 *Set reserved vector 20497 move.l #nullrte, $0054 *Set reserved vector 21498 move.l #nullrte, $0058 *Set reserved vector 22499 move.l #nullrte, $005C *Set reserved vector 23500 * 501 move.l #nullrte, $0060 *Set spurious int. vector502 * 503 move.l #serintr, $0074 *Set ACIA interrupt vector504 move.l #nullrte, $0078 *Set level 6 vector505 move.l #nullrte, $007C *Set level 7 vector506 * 507 move.l #trap13, $00B4 *Set trap13 vector508 move.l #trap14, $00B8 *Set trap14 vector509 * 510 .page 511 * 456 457 binit1: move.l a1,(a0)+ | Store trap vector 458 adda.l #0x01000000,a1 | Increment trap # 459 dbf d1,binit1 | Loop until done 460 461 lea biosram,a0 | Clear BIOS ram ... 462 lea SSTACK-2,a1 | ... from biosram to SSTACK-1 463 464 binit2: move.w #0,(a0)+ | Zero a word 465 cmpa.l a0,a1 | Last one ? 466 bne binit2 | Loop if not 467 468 move.l #rsarea,savptr | Setup pointer to register area 469 move.l #RSMAGIC,_rsflag | Set magic in _rsflag 470 471 move.l #nullrts,timevec | Set timer interrupt vector 472 move.l #nullrts,critvec | Set critical error vector 473 move.l #nullrts,termvec | Set process terminate vector 474 move.l #nullrts,resvec3 | Set software vector 3 475 move.l #nullrts,resvec4 | Set software vector 4 476 move.l #nullrts,resvec5 | Set software vector 5 477 move.l #nullrts,resvec6 | Set software vector 6 478 move.l #nullrts,resvec7 | Set software vector 7 479 480 move.l #hardhlt,0x0008 | Set bus error vector 481 move.l #nullrte,0x0014 | Set divide error vector 482 move.l #nullrte,0x0018 | Set CHK vector 483 move.l #nullrte,0x001C | Set TRAPV vector 484 move.l #nullrte,0x0024 | Set trace vector 485 486 move.l #nullrte,0x0030 | Set reserved vector 12 487 move.l #nullrte,0x0034 | Set reserved vector 13 488 move.l #nullrte,0x0038 | Set reserved vector 14 489 490 move.l #nullrte,0x003C | Set uninitialized int. vector 491 492 move.l #nullrte,0x0040 | Set reserved vector 16 493 move.l #nullrte,0x0044 | Set reserved vector 17 494 move.l #nullrte,0x0048 | Set reserved vector 18 495 move.l #nullrte,0x004C | Set reserved vector 19 496 move.l #nullrte,0x0050 | Set reserved vector 20 497 move.l #nullrte,0x0054 | Set reserved vector 21 498 move.l #nullrte,0x0058 | Set reserved vector 22 499 move.l #nullrte,0x005C | Set reserved vector 23 500 501 move.l #nullrte,0x0060 | Set spurious int. vector 502 503 move.l #serintr,0x0074 | Set ACIA interrupt vector 504 move.l #nullrte,0x0078 | Set level 6 vector 505 move.l #nullrte,0x007C | Set level 7 vector 506 507 move.l #trap13,0x00B4 | Set trap13 vector 508 move.l #trap14,0x00B8 | Set trap14 vector 509 510 .page 511 512 512 .ifne BUCHLA 513 * 514 move.l #nullfpu, $0068 *Set FPU interrupt vector515 move.l #api_int, $006C *Set analog trap vector516 move.l #timeint, $0070 *Set timer trap vector517 * 518 move.l #_hdvini,hdv_init *Set disk init vector519 move.l #getbpb,hdv_bpb *Set get BPB vector520 move.l #rwabs,hdv_rw *Set disk I/O vector521 move.l #bootload,hdv_boot *Setup boot load vector522 move.l #mediach,hdv_mchg *Setup media change vector523 * 524 move.w # $FFFF,fverify *Set read after write flag525 move.w #FL_SKR,seekrate *Set default seek rate526 move.w # $FFFF,booted *Say we're not booted yet527 move.l #buffer,dskbufp *Setup default disk buffer528 * 529 .page 530 * 531 move.b #7,PSG_WL *Select PSG R7532 move.b # $80,PSG_WD * Write $80 (port B = output)533 move.b #15,PSG_WL *Select PSG R15534 move.b # $00,PSG_WD * Write $00 (sync enable)535 * 536 move.b # $00,TIME_T1H *Setup timer 1 (PLL)537 move.b # $1F,TIME_T1L *... for divide by 64538 move.b # $0C,TIME_T2H *Setup timer 2 (FC)539 move.b # $7F,TIME_T2L *... for divide by 3200540 move.b # $03,TIME_T3H *Setup timer 3 (RTC)541 move.b # $20,TIME_T3L *... for 1Ms interval542 move.b # $42,TIME_CRX *Setup CR3543 move.b # $41,TIME_CR2 *Setup CR2544 move.b # $81,TIME_CRX *Setup CR1545 move.b # $80,TIME_CRX *Start the timers546 * 547 .endc 548 * 549 lea sr1iorec,a0 *Serial-1 iorec address to a0550 lea SR1ACIA,a1 *Serial-1 ACIA address to a1551 lea sr1dflt,a2 *Serial-1 dflt table addr to a2552 bsr.w aciainit *Go initialize the port553 * 554 lea sr2iorec,a0 *Serial-2 iorec address to a0555 lea SR2ACIA,a1 *Serial-2 ACIA address to a1556 lea sr2dflt,a2 *Serial-2 dflt table addr to a2557 bsr.w aciainit *Go initialize the port558 * 513 514 move.l #nullfpu,0x0068 | Set FPU interrupt vector 515 move.l #api_int,0x006C | Set analog trap vector 516 move.l #timeint,0x0070 | Set timer trap vector 517 518 move.l #_hdvini,hdv_init | Set disk init vector 519 move.l #getbpb,hdv_bpb | Set get BPB vector 520 move.l #rwabs,hdv_rw | Set disk I/O vector 521 move.l #bootload,hdv_boot | Setup boot load vector 522 move.l #mediach,hdv_mchg | Setup media change vector 523 524 move.w #0xFFFF,fverify | Set read after write flag 525 move.w #FL_SKR,seekrate | Set default seek rate 526 move.w #0xFFFF,booted | Say we're not booted yet 527 move.l #buffer,dskbufp | Setup default disk buffer 528 529 .page 530 531 move.b #7,PSG_WL | Select PSG R7 532 move.b #0x80,PSG_WD | Write 0x80 (port B = output) 533 move.b #15,PSG_WL | Select PSG R15 534 move.b #0x00,PSG_WD | Write 0x00 (sync enable) 535 536 move.b #0x00,TIME_T1H | Setup timer 1 (PLL) 537 move.b #0x1F,TIME_T1L | ... for divide by 64 538 move.b #0x0C,TIME_T2H | Setup timer 2 (FC) 539 move.b #0x7F,TIME_T2L | ... for divide by 3200 540 move.b #0x03,TIME_T3H | Setup timer 3 (RTC) 541 move.b #0x20,TIME_T3L | ... for 1Ms interval 542 move.b #0x42,TIME_CRX | Setup CR3 543 move.b #0x41,TIME_CR2 | Setup CR2 544 move.b #0x81,TIME_CRX | Setup CR1 545 move.b #0x80,TIME_CRX | Start the timers 546 547 .endc 548 549 lea sr1iorec,a0 | Serial-1 iorec address to a0 550 lea SR1ACIA,a1 | Serial-1 ACIA address to a1 551 lea sr1dflt,a2 | Serial-1 dflt table addr to a2 552 bsr.w aciainit | Go initialize the port 553 554 lea sr2iorec,a0 | Serial-2 iorec address to a0 555 lea SR2ACIA,a1 | Serial-2 ACIA address to a1 556 lea sr2dflt,a2 | Serial-2 dflt table addr to a2 557 bsr.w aciainit | Go initialize the port 558 559 559 .ifne BUCHLA 560 * 561 lea mc1iorec,a0 *MIDI-1 iorec address to a0562 lea MC1ACIA,a1 *MIDI-1 ACIA address to a1563 lea mc1dflt,a2 *MIDI-1 dflt table addr to a2564 bsr.w aciainit *Go initialize the port565 * 566 lea mc2iorec,a0 *MIDI-2 iorec address to a0567 lea MC2ACIA,a1 *MIDI-2 ACIA address to a1568 lea mc2dflt,a2 *MIDI-2 dflt table addr to a2569 bsr.w aciainit *Go initialize the port570 * 571 .page 572 * 573 lea VSDDINIT,a1 *Setup to load VSDD regs574 lea vsddtab,a0 *... from vsddtab575 move.w #15,d0 *... all 16 registers576 * 577 vsddinit: move.w (a0)+,(a1)+ *Load the VSDD registers560 561 lea mc1iorec,a0 | MIDI-1 iorec address to a0 562 lea MC1ACIA,a1 | MIDI-1 ACIA address to a1 563 lea mc1dflt,a2 | MIDI-1 dflt table addr to a2 564 bsr.w aciainit | Go initialize the port 565 566 lea mc2iorec,a0 | MIDI-2 iorec address to a0 567 lea MC2ACIA,a1 | MIDI-2 ACIA address to a1 568 lea mc2dflt,a2 | MIDI-2 dflt table addr to a2 569 bsr.w aciainit | Go initialize the port 570 571 .page 572 573 lea VSDDINIT,a1 | Setup to load VSDD regs 574 lea vsddtab,a0 | ... from vsddtab 575 move.w #15,d0 | ... all 16 registers 576 577 vsddinit: move.w (a0)+,(a1)+ | Load the VSDD registers 578 578 btst.l #0,d0 579 579 btst.l #0,d0 580 580 btst.l #0,d0 581 581 dbf d0,vsddinit 582 * 583 move.w vsddit02,VSDDINIT *Enable the video584 * 585 move.l #api_fum,api_fi *Clear analog processor fifo586 move.l #api_fum,api_fo *...587 * 588 move.w #23,d0 *Setup to clear key LEDs589 move.b # $80,d1 *...590 * 591 ledclear: move.b d1,LEDS *Clear a LED592 addq.b #1,d1 *Increment LED number593 dbra d0,ledclear *Loop until all are done594 * 595 move.w #7,d0 *Setup to clear pot LEDs596 move.b # $18,d1 *...597 * 598 ledclr2: move.b d1,LEDS *Clear a LED599 addq.b #1,d1 *Increment LED number600 dbra d0,ledclr2 *Loop until all are done601 * 602 clr.w fc_sw *Stop the frame clock603 clr.l fc_val *... and reset it604 * 605 .page 606 * 607 lea FPUBASE+FPU_CTL,a0 *Point at FPU master level608 move.w # $0000,$08(a0) *Set CV1 to 0609 addq.w #1,d0 *Delay610 addq.w #1,d0 *...611 move.w # $0000,$0A(a0) *Set SF1 to 0612 addq.w #1,d0 *Delay613 addq.w #1,d0 *...614 move.w # $0000,$0C(a0) *Set CV2 to 0615 addq.w #1,d0 *Delay616 addq.w #1,d0 *...617 move.w # $0000,$0E(a0) *Set SF2 to 0618 addq.w #1,d0 *Delay619 addq.w #1,d0 *...620 move.w # $0000,$10(a0) *Set CV3 to 0621 addq.w #1,d0 *Delay622 addq.w #1,d0 *...623 move.w # $0000,$12(a0) *Set SF3 to 0624 addq.w #1,d0 *Delay625 addq.w #1,d0 *...626 move.w # $8300,$02(a0) *Set new value '10' to -10.00627 addq.w #1,d0 *Delay628 addq.w #1,d0 *...629 move.w # $8300,$1C(a0) *Set new value '01' to -10.00630 addq.w #1,d0 *Delay631 addq.w #1,d0 *...632 move.w # $0001,$16(a0) *Set exponent for shortest time633 addq.w #1,d0 *Delay634 addq.w #1,d0 *...635 move.w # $FFF0,$14(a0) *Set mantissa for shortest time636 addq.w #1,d0 *Delay637 addq.w #1,d0 *...638 move.w # $0005,$00(a0) *Send control word to FPU639 * 640 .endc 641 * 642 .page 643 * 644 move.w #INITIPL,sr *Enable interrupts645 lea basepage,a1 *Pass start_ a pseudo base page646 move.l #_errno,p_bbase(a1) *...647 clr.l p_blen(a1) *...648 move.l a1,-(a7) *...649 jsr start_ *Go start ROMP (we assume ...)650 * 651 jmp biosinit *Just in case we return ...652 * 653 .page 654 * 582 583 move.w vsddit02,VSDDINIT | Enable the video 584 585 move.l #api_fum,api_fi | Clear analog processor fifo 586 move.l #api_fum,api_fo | ... 587 588 move.w #23,d0 | Setup to clear key LEDs 589 move.b #0x80,d1 | ... 590 591 ledclear: move.b d1,LEDS | Clear a LED 592 addq.b #1,d1 | Increment LED number 593 dbra d0,ledclear | Loop until all are done 594 595 move.w #7,d0 | Setup to clear pot LEDs 596 move.b #0x18,d1 | ... 597 598 ledclr2: move.b d1,LEDS | Clear a LED 599 addq.b #1,d1 | Increment LED number 600 dbra d0,ledclr2 | Loop until all are done 601 602 clr.w fc_sw | Stop the frame clock 603 clr.l fc_val | ... and reset it 604 605 .page 606 607 lea FPUBASE+FPU_CTL,a0 | Point at FPU master level 608 move.w #0x0000,0x08(a0) | Set CV1 to 0 609 addq.w #1,d0 | Delay 610 addq.w #1,d0 | ... 611 move.w #0x0000,0x0A(a0) | Set SF1 to 0 612 addq.w #1,d0 | Delay 613 addq.w #1,d0 | ... 614 move.w #0x0000,0x0C(a0) | Set CV2 to 0 615 addq.w #1,d0 | Delay 616 addq.w #1,d0 | ... 617 move.w #0x0000,0x0E(a0) | Set SF2 to 0 618 addq.w #1,d0 | Delay 619 addq.w #1,d0 | ... 620 move.w #0x0000,0x10(a0) | Set CV3 to 0 621 addq.w #1,d0 | Delay 622 addq.w #1,d0 | ... 623 move.w #0x0000,0x12(a0) | Set SF3 to 0 624 addq.w #1,d0 | Delay 625 addq.w #1,d0 | ... 626 move.w #0x8300,0x02(a0) | Set new value '10' to -10.00 627 addq.w #1,d0 | Delay 628 addq.w #1,d0 | ... 629 move.w #0x8300,0x1C(a0) | Set new value '01' to -10.00 630 addq.w #1,d0 | Delay 631 addq.w #1,d0 | ... 632 move.w #0x0001,0x16(a0) | Set exponent for shortest time 633 addq.w #1,d0 | Delay 634 addq.w #1,d0 | ... 635 move.w #0xFFF0,0x14(a0) | Set mantissa for shortest time 636 addq.w #1,d0 | Delay 637 addq.w #1,d0 | ... 638 move.w #0x0005,0x00(a0) | Send control word to FPU 639 640 .endc 641 642 .page 643 644 move.w #INITIPL,sr | Enable interrupts 645 lea basepage,a1 | Pass start_ a pseudo base page 646 move.l #_errno,p_bbase(a1) | ... 647 clr.l p_blen(a1) | ... 648 move.l a1,-(a7) | ... 649 jsr start_ | Go start ROMP (we assume ...) 650 651 jmp biosinit | Just in case we return ... 652 653 .page 654 655 655 .ifne BUCHLA 656 * 657 *nullfpu -- Null FPU trap handler658 *------- ---------------------659 nullfpu: movem.l d0-d0/a0-a0,-(a7) *Save registers660 movea.l #FPUBASE,a0 *Setup FPU base address in a0661 move.w FPU_IN(a0),d0 *Read FPU interrupt port662 andi.l # $000000FF,d0 *Mask for voice & parameter663 lsl.l #5,d0 *Shift for word offset664 addi.l #FPU_CTL,d0 *Add FPU control offset665 move.w #FPU_RST,0(a0,d0.L) *Reset the function666 clr.w FPU_CLR(a0) *Clear the interrupt667 movem.l (a7)+,d0-d0/a0-a0 *Restore registers668 rte *Return to interrupted code669 * 670 .endc 671 * 672 .page 673 * 674 *hardhlt -- Bus error trap handler675 *------- ----------------------676 hardhlt: stop # $2700 *stop dead -- system is AFU677 bra hardhlt *...678 * 679 *badtrap -- Bad trap handler680 *------- ----------------681 badtrap: move.w (a7)+,_crshsr *Get crash SR682 move.l (a7)+,_crshpc *Get crash PC683 move.l a7,_crshsp *Get crash SP684 bsr badtr1 *Get TRAP PC with vector number656 657 | nullfpu -- Null FPU trap handler 658 | ------- --------------------- 659 nullfpu: movem.l d0-d0/a0-a0,-(a7) | Save registers 660 movea.l #FPUBASE,a0 | Setup FPU base address in a0 661 move.w FPU_IN(a0),d0 | Read FPU interrupt port 662 andi.l #0x000000FF,d0 | Mask for voice & parameter 663 lsl.l #5,d0 | Shift for word offset 664 addi.l #FPU_CTL,d0 | Add FPU control offset 665 move.w #FPU_RST,0(a0,d0.L) | Reset the function 666 clr.w FPU_CLR(a0) | Clear the interrupt 667 movem.l (a7)+,d0-d0/a0-a0 | Restore registers 668 rte | Return to interrupted code 669 670 .endc 671 672 .page 673 674 | hardhlt -- Bus error trap handler 675 | ------- ---------------------- 676 hardhlt: stop #0x2700 | stop dead -- system is AFU 677 bra hardhlt | ... 678 679 | badtrap -- Bad trap handler 680 | ------- ---------------- 681 badtrap: move.w (a7)+,_crshsr | Get crash SR 682 move.l (a7)+,_crshpc | Get crash PC 683 move.l a7,_crshsp | Get crash SP 684 bsr badtr1 | Get TRAP PC with vector number 685 685 nop 686 * 687 badtr1: move.l (a7)+,_crshvc *Save for analysis of vector #688 movem.l d0-d7/a0-a7,_crshrg *Save crash registers689 move.l usp,a0 *Preserve crash USP690 move.l a0,_crshus *...691 move.l a7,d0 *Get SP692 andi.l # $FFFFFFFE,d0 *... make sure it's even693 movea.l d0,a1 *...694 move.w #15,d0 *Save top 16 words695 lea _crshst,a0 *... of crash stack in _crshst696 * 697 badtr2: move.w (a1)+,(a0)+ *Save a stack value698 dbf d0,badtr2 *Loop until all are saved699 * 700 clr.l d0 *Get TRAP number701 move.b _crshvc,d0 *... as LS byte of d0702 move.l _crshpc,a0 *Save crash PC in a0703 move.w # $FFFF,_wzcrsh *Indicate we crashed704 move.l #rsarea,savptr *Restore system save pointer705 move.l #SSTACK,a7 *Reset the stack pointer706 move.l #RSMAGIC,_rsflag *... and the stack sentinel707 trap #15 *TRAP to ROMP708 * 709 jmp biosinit *Recover with a cold start710 * 711 .page 712 * 686 687 badtr1: move.l (a7)+,_crshvc | Save for analysis of vector # 688 movem.l d0-d7/a0-a7,_crshrg | Save crash registers 689 move.l usp,a0 | Preserve crash USP 690 move.l a0,_crshus | ... 691 move.l a7,d0 | Get SP 692 andi.l #0xFFFFFFFE,d0 | ... make sure it's even 693 movea.l d0,a1 | ... 694 move.w #15,d0 | Save top 16 words 695 lea _crshst,a0 | ... of crash stack in _crshst 696 697 badtr2: move.w (a1)+,(a0)+ | Save a stack value 698 dbf d0,badtr2 | Loop until all are saved 699 700 clr.l d0 | Get TRAP number 701 move.b _crshvc,d0 | ... as LS byte of d0 702 move.l _crshpc,a0 | Save crash PC in a0 703 move.w #0xFFFF,_wzcrsh | Indicate we crashed 704 move.l #rsarea,savptr | Restore system save pointer 705 move.l #SSTACK,a7 | Reset the stack pointer 706 move.l #RSMAGIC,_rsflag | ... and the stack sentinel 707 trap #15 | TRAP to ROMP 708 709 jmp biosinit | Recover with a cold start 710 711 .page 712 713 713 .ifne BUCHLA 714 * 715 *timeint -- Timer interrupt handler716 *------- -----------------------717 timeint: movem.l d0-d7/a0-a6,-(a7) *Save registers718 move.b TIME_CR2,d0 *Get timer interrupt status719 btst.l #2,d0 *Check timer 3 status720 beq tmi02 *Jump if not active721 * 722 move.b TIME_T3H,d1 *Read timer 1 count723 lsl.l #8,d1 *...724 move.b TIME_T3L,d1 *...725 move.w d1,t3count *... and save it726 * 727 addq.l #1,_hz_1k *Update 1ms clock (1 KHz)728 * 729 move.w tdiv1,d1 *Update divider730 addq.w #1,d1 *...731 move.w d1,tdiv1 *...732 * 733 cmpi.w #5,d1 *Do we need to update _hz_200 ?734 blt tmi02 *Jump if not735 * 736 addq.l #1,_hz_200 *Update 5ms clock (200 Hz)737 * 738 move.w tdiv2,d1 *Update divider739 addq.w #1,d1 *...740 move.w d1,tdiv2 *...741 * 742 cmpi.w #4,d1 *Do we need to update frclock ?743 blt tmi01 *Jump if not744 * 745 addq.l #1,frclock *Update 20 Ms clock (50 Hz)746 tst.w flock *See if floppy is active747 bne tmi00 *Don't call flopvbl if so748 * 749 bsr flopvbl *Check on the floppy750 * 751 tmi00: move.w #0,tdiv2 *Reset tdiv2752 * 753 tmi01: move.w #0,tdiv1 *Reset tdiv1754 * 755 .page 756 * 757 tmi02: btst.l #0,d0 *Check timer 1 int758 beq tmi03 *Jump if not set759 * 760 move.b TIME_T1H,d1 *Read timer 1 to clear int.761 lsl.l #8,d1 *...762 move.b TIME_T1L,d1 *...763 move.w d1,t1count *... and save the count764 * 765 tmi03: btst.l #1,d0 *Check for timer 2 int.766 beq tmi04 *Jump if not set767 * 768 move.b TIME_T2H,d1 *Read timer 2 to clear int.769 lsl.l #8,d1 *...770 move.b TIME_T2L,d1 *...771 move.w d1,t2count *... and save the count772 * 773 tst.w fc_sw *Should we update the frame ?774 beq tmi04 *Jump if not775 * 776 bmi tmi05 *Jump if we count down777 * 778 move.l fc_val,d0 *Get the frame count779 cmp.l #FCMAX,d0 *See it we've topped out780 bge tmi06 *Jump if limit was hit781 * 782 addq.l #1,d0 *Count up 1 frame783 move.l d0,fc_val *Store updated frame count784 bra tmi04 *Done785 * 786 tmi06: move.l #FCMAX,fc_val *Force hard limit, just in case787 bra tmi04 *Done788 * 789 tmi05: move.l fc_val,d0 *Get the frame count790 beq tmi04 *Done if already zero791 * 792 subq.l #1,d0 *Count down 1 frame793 move.l d0,fc_val *Store udpated frame count794 * 795 movea.l timevec,a0 *Do RTC vector796 move.w #1,-(a7) *... pass 1 msec on stack797 jsr (a0) *...798 addq.l #4,a7 *...799 * 800 tmi04: movem.l (a7)+,d0-d7/a0-a6 *Restore registers801 rte *Return to interrupted code802 * 803 .endc 804 * 805 .page 806 * 807 *trap14 -- Extended BIOS entry point808 *------ -------------------------809 trap14: lea t14tab,a0 *Setup trap 14 table address810 bra trapent *Go process trap811 * 812 *trap13 -- Main BIOS entry point813 *------ ---------------------814 trap13: lea t13tab,a0 *Setup trap 13 table address815 * 816 trapent: move.l savptr,a1 *Get save area pointer817 move.w (a7)+,d0 *Status register to D0818 move.w d0,-(a1) *Save in save area819 move.l (a7)+,-(a1) *Stash PC in save area820 movem.l d3-d7/a3-a7,-(a1) *Save parameter register821 move.l a1,savptr *Update save pointer822 btst #13,d0 *Were we in sup. mode ?823 bne trwzsup *Jump if so824 * 825 move.l usp,a7 *Move user sp to stack ptr.826 * 827 trwzsup: move.w (a7)+,d0 *Get function number from stack828 cmp.w (a0)+,d0 *Check against limit829 bge trpexit *Jump if it's invalid830 * 831 lsl.w #2,d0 *Multiply by 4 for use as index832 move.l 0(a0,d0),d0 *Get routine address833 move.l d0,a0 *... into a0834 bpl trpnind *Jump if it's indirect835 * 836 move.l (a0),a0 *Use indirect value837 * 838 trpnind: sub.l a5,a5 *Clear a5839 jsr (a0) *Execute the routine840 * 841 trpexit: move.l savptr,a1 *Get SAVPTR into a1842 movem.l (a1)+,d3-d7/a3-a7 *Restore registers843 move.l (a1)+,-(a7) *Push return onto stack844 move.w (a1)+,-(a7) *Push status onto stack845 move.l a1,savptr *Update SAVPTR846 * 847 *nullrte -- null rte848 *------- --------849 nullrte: rte *Return to interrupted code850 * 851 *nullrts -- null return852 *------- -----------853 nullrts: rts *Just return to the caller854 * 855 .page 856 * 857 *bconstat -- Get character device input status858 *-------- ---------------------------------859 bconstat: lea cdt01,a0 *Point at status table860 bra condisp *Jump to dispatcher861 * 862 *bconin -- Get input from character device863 *------ -------------------------------864 bconin: lea cdt02,a0 *Point at input table865 bra condisp *Jump to dispatcher866 * 867 *bconout -- Output to character device868 *------- --------------------------869 bconout: lea cdt03,a0 *Point at output table870 bra condisp *Jump to dispatcher871 * 872 *bcostat -- Get character device output status873 *------- ----------------------------------874 bcostat: lea cdt04,a0 *Point at status table875 * 876 *condisp -- Character device function dispatcher877 *------- ------------------------------------878 condisp: move.w 4(a7),d0 *Get device number879 lsl.w #2,d0 *... times 4 for pointer880 move.l 0(a0,d0),a0 *Get routine address881 jmp (a0) *Jump to it882 * 883 .page 884 * 885 *sr1ist -- Check CON (Serial-1) input buffer status886 *------ ----------------------------------------887 sr1ist: lea sr1iorec,a0 *Address of iorec to a0888 lea SR1ACIA,a1 *Address of ACIA to a1889 bra chkist *Go check buffer status890 * 891 *sr2ist -- Check AUX (Serial-2) input buffer status892 *------ ----------------------------------------893 sr2ist: lea sr2iorec,a0 *Address of iorec to a0894 lea SR2ACIA,a1 *Address of ACIA to a1895 * 714 715 | timeint -- Timer interrupt handler 716 | ------- ----------------------- 717 timeint: movem.l d0-d7/a0-a6,-(a7) | Save registers 718 move.b TIME_CR2,d0 | Get timer interrupt status 719 btst.l #2,d0 | Check timer 3 status 720 beq tmi02 | Jump if not active 721 722 move.b TIME_T3H,d1 | Read timer 1 count 723 lsl.l #8,d1 | ... 724 move.b TIME_T3L,d1 | ... 725 move.w d1,t3count | ... and save it 726 727 addq.l #1,_hz_1k | Update 1ms clock (1 KHz) 728 729 move.w tdiv1,d1 | Update divider 730 addq.w #1,d1 | ... 731 move.w d1,tdiv1 | ... 732 733 cmpi.w #5,d1 | Do we need to update _hz_200 ? 734 blt tmi02 | Jump if not 735 736 addq.l #1,_hz_200 | Update 5ms clock (200 Hz) 737 738 move.w tdiv2,d1 | Update divider 739 addq.w #1,d1 | ... 740 move.w d1,tdiv2 | ... 741 742 cmpi.w #4,d1 | Do we need to update frclock ? 743 blt tmi01 | Jump if not 744 745 addq.l #1,frclock | Update 20 Ms clock (50 Hz) 746 tst.w flock | See if floppy is active 747 bne tmi00 | Don't call flopvbl if so 748 749 bsr flopvbl | Check on the floppy 750 751 tmi00: move.w #0,tdiv2 | Reset tdiv2 752 753 tmi01: move.w #0,tdiv1 | Reset tdiv1 754 755 .page 756 757 tmi02: btst.l #0,d0 | Check timer 1 int 758 beq tmi03 | Jump if not set 759 760 move.b TIME_T1H,d1 | Read timer 1 to clear int. 761 lsl.l #8,d1 | ... 762 move.b TIME_T1L,d1 | ... 763 move.w d1,t1count | ... and save the count 764 765 tmi03: btst.l #1,d0 | Check for timer 2 int. 766 beq tmi04 | Jump if not set 767 768 move.b TIME_T2H,d1 | Read timer 2 to clear int. 769 lsl.l #8,d1 | ... 770 move.b TIME_T2L,d1 | ... 771 move.w d1,t2count | ... and save the count 772 773 tst.w fc_sw | Should we update the frame ? 774 beq tmi04 | Jump if not 775 776 bmi tmi05 | Jump if we count down 777 778 move.l fc_val,d0 | Get the frame count 779 cmp.l #FCMAX,d0 | See it we've topped out 780 bge tmi06 | Jump if limit was hit 781 782 addq.l #1,d0 | Count up 1 frame 783 move.l d0,fc_val | Store updated frame count 784 bra tmi04 | Done 785 786 tmi06: move.l #FCMAX,fc_val | Force hard limit, just in case 787 bra tmi04 | Done 788 789 tmi05: move.l fc_val,d0 | Get the frame count 790 beq tmi04 | Done if already zero 791 792 subq.l #1,d0 | Count down 1 frame 793 move.l d0,fc_val | Store udpated frame count 794 795 movea.l timevec,a0 | Do RTC vector 796 move.w #1,-(a7) | ... pass 1 msec on stack 797 jsr (a0) | ... 798 addq.l #4,a7 | ... 799 800 tmi04: movem.l (a7)+,d0-d7/a0-a6 | Restore registers 801 rte | Return to interrupted code 802 803 .endc 804 805 .page 806 807 | trap14 -- Extended BIOS entry point 808 | ------ ------------------------- 809 trap14: lea t14tab,a0 | Setup trap 14 table address 810 bra trapent | Go process trap 811 812 | trap13 -- Main BIOS entry point 813 | ------ --------------------- 814 trap13: lea t13tab,a0 | Setup trap 13 table address 815 816 trapent: move.l savptr,a1 | Get save area pointer 817 move.w (a7)+,d0 | Status register to D0 818 move.w d0,-(a1) | Save in save area 819 move.l (a7)+,-(a1) | Stash PC in save area 820 movem.l d3-d7/a3-a7,-(a1) | Save parameter register 821 move.l a1,savptr | Update save pointer 822 btst #13,d0 | Were we in sup. mode ? 823 bne trwzsup | Jump if so 824 825 move.l usp,a7 | Move user sp to stack ptr. 826 827 trwzsup: move.w (a7)+,d0 | Get function number from stack 828 cmp.w (a0)+,d0 | Check against limit 829 bge trpexit | Jump if it's invalid 830 831 lsl.w #2,d0 | Multiply by 4 for use as index 832 move.l 0(a0,d0),d0 | Get routine address 833 move.l d0,a0 | ... into a0 834 bpl trpnind | Jump if it's indirect 835 836 move.l (a0),a0 | Use indirect value 837 838 trpnind: sub.l a5,a5 | Clear a5 839 jsr (a0) | Execute the routine 840 841 trpexit: move.l savptr,a1 | Get SAVPTR into a1 842 movem.l (a1)+,d3-d7/a3-a7 | Restore registers 843 move.l (a1)+,-(a7) | Push return onto stack 844 move.w (a1)+,-(a7) | Push status onto stack 845 move.l a1,savptr | Update SAVPTR 846 847 | nullrte -- null rte 848 | ------- -------- 849 nullrte: rte | Return to interrupted code 850 851 | nullrts -- null return 852 | ------- ----------- 853 nullrts: rts | Just return to the caller 854 855 .page 856 857 | bconstat -- Get character device input status 858 | -------- --------------------------------- 859 bconstat: lea cdt01,a0 | Point at status table 860 bra condisp | Jump to dispatcher 861 862 | bconin -- Get input from character device 863 | ------ ------------------------------- 864 bconin: lea cdt02,a0 | Point at input table 865 bra condisp | Jump to dispatcher 866 867 | bconout -- Output to character device 868 | ------- -------------------------- 869 bconout: lea cdt03,a0 | Point at output table 870 bra condisp | Jump to dispatcher 871 872 | bcostat -- Get character device output status 873 | ------- ---------------------------------- 874 bcostat: lea cdt04,a0 | Point at status table 875 876 | condisp -- Character device function dispatcher 877 | ------- ------------------------------------ 878 condisp: move.w 4(a7),d0 | Get device number 879 lsl.w #2,d0 | ... times 4 for pointer 880 move.l 0(a0,d0),a0 | Get routine address 881 jmp (a0) | Jump to it 882 883 .page 884 885 | sr1ist -- Check CON (Serial-1) input buffer status 886 | ------ ---------------------------------------- 887 sr1ist: lea sr1iorec,a0 | Address of iorec to a0 888 lea SR1ACIA,a1 | Address of ACIA to a1 889 bra chkist | Go check buffer status 890 891 | sr2ist -- Check AUX (Serial-2) input buffer status 892 | ------ ---------------------------------------- 893 sr2ist: lea sr2iorec,a0 | Address of iorec to a0 894 lea SR2ACIA,a1 | Address of ACIA to a1 895 896 896 .ifne BUCHLA 897 * 898 bra chkist *Go check buffer status899 * 900 *mc1ist -- Check MC1 (MIDI-1) input buffer status901 *------ --------------------------------------902 mc1ist: lea mc1iorec,a0 *Address of iorec to a0903 lea MC1ACIA,a1 *Address of ACIA to a1904 bra chkist *Go check buffer status905 * 906 *mc2ist -- Check MC2 (MIDI-2) input buffer status907 *------ --------------------------------------908 mc2ist: lea mc2iorec,a0 *Address of iorec to a0909 lea MC2ACIA,a1 *Address of ACIA to a1910 * 911 .endc 912 * 913 *chkist -- Check input buffer status914 *------ -------------------------915 chkist: moveq.l #-1,d0 *Default to "Input available"916 lea ibufhd(a0),a2 *Head index to a2917 lea ibuftl(a0),a3 *Tail index to a3918 cmpm.w (a3)+,(a2)+ *Buffer clear ?919 bne chkist1 *Jump if not920 * 921 moveq.l #0,d0 *Set to "Buffer empty"922 * 923 chkist1: rts *Return to caller924 * 925 .page 926 * 927 *sr1ost -- Check CON (Serial-1) output buffer status928 *------ -----------------------------------------929 sr1ost: lea sr1iorec,a0 *Address of iorec to a0930 bra chkost *Go check buffer status931 * 932 *sr2ost -- Check AUX (Serial-2) output buffer status933 *------ -----------------------------------------934 sr2ost: lea sr2iorec,a0 *Address of iorec to a0935 * 897 898 bra chkist | Go check buffer status 899 900 | mc1ist -- Check MC1 (MIDI-1) input buffer status 901 | ------ -------------------------------------- 902 mc1ist: lea mc1iorec,a0 | Address of iorec to a0 903 lea MC1ACIA,a1 | Address of ACIA to a1 904 bra chkist | Go check buffer status 905 906 | mc2ist -- Check MC2 (MIDI-2) input buffer status 907 | ------ -------------------------------------- 908 mc2ist: lea mc2iorec,a0 | Address of iorec to a0 909 lea MC2ACIA,a1 | Address of ACIA to a1 910 911 .endc 912 913 | chkist -- Check input buffer status 914 | ------ ------------------------- 915 chkist: moveq.l #-1,d0 | Default to "Input available" 916 lea ibufhd(a0),a2 | Head index to a2 917 lea ibuftl(a0),a3 | Tail index to a3 918 cmpm.w (a3)+,(a2)+ | Buffer clear ? 919 bne chkist1 | Jump if not 920 921 moveq.l #0,d0 | Set to "Buffer empty" 922 923 chkist1: rts | Return to caller 924 925 .page 926 927 | sr1ost -- Check CON (Serial-1) output buffer status 928 | ------ ----------------------------------------- 929 sr1ost: lea sr1iorec,a0 | Address of iorec to a0 930 bra chkost | Go check buffer status 931 932 | sr2ost -- Check AUX (Serial-2) output buffer status 933 | ------ ----------------------------------------- 934 sr2ost: lea sr2iorec,a0 | Address of iorec to a0 935 936 936 .ifne BUCHLA 937 * 938 bra chkost *Go check buffer status939 * 940 *mc1ost -- Check MC1 (MIDI-1) output buffer status941 *------ ---------------------------------------942 mc1ost: lea mc1iorec,a0 *Address of iorec to a0943 bra chkost *Go check buffer status944 * 945 *mc2ost -- Check MC2 (MIDI-2) output buffer status946 *------ ---------------------------------------947 mc2ost: lea mc2iorec,a0 *Address of iorec to a0948 * 949 .endc 950 * 951 *chkost -- Check output buffer status952 *------ --------------------------953 chkost: moveq.l #-1,d0 *Default to "Output OK"954 move.w obuftl(a0),d2 *Tail index to d2955 bsr wrapout *Test for pointer wraparound956 cmp.w obufhd(a0),d2 *Compare with head index957 bne chkost1 *Jump if not equal958 * 959 moveq.l #0,d0 *Set to "Buffer full"960 * 961 chkost1: rts *Return to caller962 * 963 .page 964 * 965 *wrapin -- Check input pointer for wraparound966 *------ ----------------------------------967 wrapin: add.w #1,d1 *Head index +1968 cmp.w ibufsize(a0),d1 *= buffer size ?969 bcs wrapin1 *Jump if not970 * 971 moveq.l #0,d1 *Wraparound972 * 973 wrapin1: rts *Return to caller974 * 975 *wrapout -- Check output pointer for wraparound976 *------- -----------------------------------977 wrapout: addq.w #1,d2 *Tail index +1978 cmp.w obufsize(a0),d2 *= buffer size ?979 bcs wrapout1 *Jump if not980 * 981 moveq.l #0,d2 *Wrap around if so982 * 983 wrapout1: rts *Return to caller984 * 985 .page 986 * 987 *sr1inp -- Get input from Serial-1 (wait on busy)988 *------ ---------------------------------------989 sr1inp: lea sr1iorec,a0 *Serial-1 iorec address990 lea SR1ACIA,a1 *Serial-1 ACIA base991 bra serinp *Go get a byte992 * 993 *sr2inp -- Get input from Serial-2 (wait on busy)994 *------ ---------------------------------------995 sr2inp: lea sr2iorec,a0 *Serial-2 iorec address996 lea SR2ACIA,a1 *Serial-2 ACIA base997 * 998 *serinp -- Get a byte from a serial port (with handshaking)999 *------ -------------------------------------------------1000 serinp: bsr chkist *Check input status1001 tst.w d0 *Character ready ?1002 beq serinp *Loop until one is ...1003 * 1004 bsr getser *Get a byte from the buffer1005 and.w # $FFFF,d0 *Isolate LS bits 7..01006 rts *Return to caller1007 * 1008 .page 1009 * 937 938 bra chkost | Go check buffer status 939 940 | mc1ost -- Check MC1 (MIDI-1) output buffer status 941 | ------ --------------------------------------- 942 mc1ost: lea mc1iorec,a0 | Address of iorec to a0 943 bra chkost | Go check buffer status 944 945 | mc2ost -- Check MC2 (MIDI-2) output buffer status 946 | ------ --------------------------------------- 947 mc2ost: lea mc2iorec,a0 | Address of iorec to a0 948 949 .endc 950 951 | chkost -- Check output buffer status 952 | ------ -------------------------- 953 chkost: moveq.l #-1,d0 | Default to "Output OK" 954 move.w obuftl(a0),d2 | Tail index to d2 955 bsr wrapout | Test for pointer wraparound 956 cmp.w obufhd(a0),d2 | Compare with head index 957 bne chkost1 | Jump if not equal 958 959 moveq.l #0,d0 | Set to "Buffer full" 960 961 chkost1: rts | Return to caller 962 963 .page 964 965 | wrapin -- Check input pointer for wraparound 966 | ------ ---------------------------------- 967 wrapin: add.w #1,d1 | Head index +1 968 cmp.w ibufsize(a0),d1 | = buffer size ? 969 bcs wrapin1 | Jump if not 970 971 moveq.l #0,d1 | Wraparound 972 973 wrapin1: rts | Return to caller 974 975 | wrapout -- Check output pointer for wraparound 976 | ------- ----------------------------------- 977 wrapout: addq.w #1,d2 | Tail index +1 978 cmp.w obufsize(a0),d2 | = buffer size ? 979 bcs wrapout1 | Jump if not 980 981 moveq.l #0,d2 | Wrap around if so 982 983 wrapout1: rts | Return to caller 984 985 .page 986 987 | sr1inp -- Get input from Serial-1 (wait on busy) 988 | ------ --------------------------------------- 989 sr1inp: lea sr1iorec,a0 | Serial-1 iorec address 990 lea SR1ACIA,a1 | Serial-1 ACIA base 991 bra serinp | Go get a byte 992 993 | sr2inp -- Get input from Serial-2 (wait on busy) 994 | ------ --------------------------------------- 995 sr2inp: lea sr2iorec,a0 | Serial-2 iorec address 996 lea SR2ACIA,a1 | Serial-2 ACIA base 997 998 | serinp -- Get a byte from a serial port (with handshaking) 999 | ------ ------------------------------------------------- 1000 serinp: bsr chkist | Check input status 1001 tst.w d0 | Character ready ? 1002 beq serinp | Loop until one is ... 1003 1004 bsr getser | Get a byte from the buffer 1005 and.w #0xFFFF,d0 | Isolate LS bits 7..0 1006 rts | Return to caller 1007 1008 .page 1009 1010 1010 .ifne BUCHLA 1011 * 1012 *mc1inp -- Get input from MIDI-1 (wait on busy)1013 *------ -------------------------------------1014 mc1inp: lea mc1iorec,a0 *MIDI-1 iorec address1015 lea MC1ACIA,a1 *MIDI-1 ACIA base1016 bra midinp *Go get a byte1017 * 1018 *mc2inp -- Get input from MIDI-2 (wait on busy)1019 *------ -------------------------------------1020 mc2inp: lea mc2iorec,a0 *MIDI-2 iorec address1021 lea MC2ACIA,a1 *MIDI-2 ACIA base1022 * 1023 *midinp -- Get input from a MIDI port (no handshaking)1024 *------ --------------------------------------------1025 midinp: bsr chkist *Check input status1026 tst.w d0 *Character ready ?1027 beq midinp *Loop until one is ...1028 * 1029 move.w sr,-(a7) *Save status register1030 ori.w #IPL7,sr *Set IPL = 7 (disable ints)1031 move.w ibufhd(a0),d1 *Head index to d11032 cmp.w ibuftl(a0),d1 *Compare to tail index1033 beq midin_1 *Jump if (somehow) empty1034 * 1035 addq.w #1,d1 *Increment head index1036 cmp.w ibufsize(a0),d1 *Did pointer wrap around ?1037 bcs midin_2 *Jump if not1038 * 1039 moveq.l #0,d1 *Wraparound1040 * 1041 midin_2: move.l ibuf(a0),a2 *Get buffer base address in a21042 moveq.l #0,d0 *Clear MS bits of d01043 move.b 0(a2,d1),d0 *Get character from buffer1044 move.w d1,ibufhd(a0) *Update buffer head index1045 * 1046 midin_1: move.w (a7)+,sr *Restore status1047 rts *Return to caller1048 * 1049 .endc 1050 * 1051 .page 1052 * 1053 *getser -- Get a byte from a serial port buffer (with handshaking)1054 *------ --------------------------------------------------------1055 getser: move.w sr,-(a7) *Save status register1056 ori.w #IPL7,sr *Set IPL = 7 (disable ints)1057 move.w ibufhd(a0),d1 *Get input buffer head index1058 cmp.w ibuftl(a0),d1 *Compare tail index1059 beq rs_mt *Jump if buffer empty1060 * 1061 bsr wrapin *Adjust pointer for wraparound1062 move.l ibuf(a0),a2 *Get buffer address1063 moveq.l #0,d0 *Clear out MS bits of d01064 move.b 0(a2,d1),d0 *Get character from buffer1065 move.w d1,ibufhd(a0) *Update head index1066 move.w (a7)+,sr *Restore status1067 andi # $FFFE,sr *Clear carry = OK1068 bra rs_xnf *Go do XON/XOFF check1069 * 1070 rs_mt: move.w (a7)+,sr *Restore status1071 ori # $0001,sr *Set carry = no character there1072 * 1073 rs_xnf: btst #0,linedisc(a0) *Check for XON/XOFF mode1074 beq rs_exit *Jump if not enabled1075 * 1076 tst.b flagxon(a0) *XON active ?1077 beq rs_exit *Jump if not1078 * 1079 bsr rsilen *Get length of buffer used1080 cmp.w ibuflow(a0),d2 *At low water mark ?1081 bne rs_exit *Jump if not1082 * 1083 move.b # $11,d1 *Send an XON1084 bsr serput *...1085 clr.b flagxon(a0) *Clear XON flag1086 * 1087 rs_exit: rts *Return to caller1088 * 1089 .page 1090 * 1091 *sr1out -- Output to serial-11092 *------ ------------------1093 sr1out: lea sr1iorec,a0 *Serial-1 iorec address to a01094 lea SR1ACIA,a1 *Serial-1 ACIA address to a11095 move.w 6(a7),d1 *Get data byte from stack1096 bsr serput *Attempt to output1097 bcs sr1out *Try until it works ...1098 * 1099 rts *Return to caller1100 * 1101 *sr2out -- Output to Serial-21102 *------ ------------------1103 sr2out: lea sr2iorec,a0 *Serial-2 iorec address to a01104 lea SR2ACIA,a1 *Serial-2 ACIA address to a11105 move.w 6(a7),d1 *Get data byte from stack1106 bsr serput *Attempt to output1107 bcs sr2out *Try until it works ...1108 * 1109 rts *Return to caller1110 * 1011 1012 | mc1inp -- Get input from MIDI-1 (wait on busy) 1013 | ------ ------------------------------------- 1014 mc1inp: lea mc1iorec,a0 | MIDI-1 iorec address 1015 lea MC1ACIA,a1 | MIDI-1 ACIA base 1016 bra midinp | Go get a byte 1017 1018 | mc2inp -- Get input from MIDI-2 (wait on busy) 1019 | ------ ------------------------------------- 1020 mc2inp: lea mc2iorec,a0 | MIDI-2 iorec address 1021 lea MC2ACIA,a1 | MIDI-2 ACIA base 1022 1023 | midinp -- Get input from a MIDI port (no handshaking) 1024 | ------ -------------------------------------------- 1025 midinp: bsr chkist | Check input status 1026 tst.w d0 | Character ready ? 1027 beq midinp | Loop until one is ... 1028 1029 move.w sr,-(a7) | Save status register 1030 ori.w #IPL7,sr | Set IPL = 7 (disable ints) 1031 move.w ibufhd(a0),d1 | Head index to d1 1032 cmp.w ibuftl(a0),d1 | Compare to tail index 1033 beq midin_1 | Jump if (somehow) empty 1034 1035 addq.w #1,d1 | Increment head index 1036 cmp.w ibufsize(a0),d1 | Did pointer wrap around ? 1037 bcs midin_2 | Jump if not 1038 1039 moveq.l #0,d1 | Wraparound 1040 1041 midin_2: move.l ibuf(a0),a2 | Get buffer base address in a2 1042 moveq.l #0,d0 | Clear MS bits of d0 1043 move.b 0(a2,d1),d0 | Get character from buffer 1044 move.w d1,ibufhd(a0) | Update buffer head index 1045 1046 midin_1: move.w (a7)+,sr | Restore status 1047 rts | Return to caller 1048 1049 .endc 1050 1051 .page 1052 1053 | getser -- Get a byte from a serial port buffer (with handshaking) 1054 | ------ -------------------------------------------------------- 1055 getser: move.w sr,-(a7) | Save status register 1056 ori.w #IPL7,sr | Set IPL = 7 (disable ints) 1057 move.w ibufhd(a0),d1 | Get input buffer head index 1058 cmp.w ibuftl(a0),d1 | Compare tail index 1059 beq rs_mt | Jump if buffer empty 1060 1061 bsr wrapin | Adjust pointer for wraparound 1062 move.l ibuf(a0),a2 | Get buffer address 1063 moveq.l #0,d0 | Clear out MS bits of d0 1064 move.b 0(a2,d1),d0 | Get character from buffer 1065 move.w d1,ibufhd(a0) | Update head index 1066 move.w (a7)+,sr | Restore status 1067 andi #0xFFFE,sr | Clear carry = OK 1068 bra rs_xnf | Go do XON/XOFF check 1069 1070 rs_mt: move.w (a7)+,sr | Restore status 1071 ori #0x0001,sr | Set carry = no character there 1072 1073 rs_xnf: btst #0,linedisc(a0) | Check for XON/XOFF mode 1074 beq rs_exit | Jump if not enabled 1075 1076 tst.b flagxon(a0) | XON active ? 1077 beq rs_exit | Jump if not 1078 1079 bsr rsilen | Get length of buffer used 1080 cmp.w ibuflow(a0),d2 | At low water mark ? 1081 bne rs_exit | Jump if not 1082 1083 move.b #0x11,d1 | Send an XON 1084 bsr serput | ... 1085 clr.b flagxon(a0) | Clear XON flag 1086 1087 rs_exit: rts | Return to caller 1088 1089 .page 1090 1091 | sr1out -- Output to serial-1 1092 | ------ ------------------ 1093 sr1out: lea sr1iorec,a0 | Serial-1 iorec address to a0 1094 lea SR1ACIA,a1 | Serial-1 ACIA address to a1 1095 move.w 6(a7),d1 | Get data byte from stack 1096 bsr serput | Attempt to output 1097 bcs sr1out | Try until it works ... 1098 1099 rts | Return to caller 1100 1101 | sr2out -- Output to Serial-2 1102 | ------ ------------------ 1103 sr2out: lea sr2iorec,a0 | Serial-2 iorec address to a0 1104 lea SR2ACIA,a1 | Serial-2 ACIA address to a1 1105 move.w 6(a7),d1 | Get data byte from stack 1106 bsr serput | Attempt to output 1107 bcs sr2out | Try until it works ... 1108 1109 rts | Return to caller 1110 1111 1111 .ifne BUCHLA 1112 * 1113 *mc1out -- Output to MIDI-11114 *------ ----------------1115 mc1out: lea mc1iorec,a0 *MIDI-1 iorec address to a01116 lea MC1ACIA,a1 *MIDI-1 ACIA address to a11117 move.w 6(a7),d1 *Get data byte from stack1118 bsr midput *Attempt to output1119 bcs mc1out *Try until it works ...1120 * 1121 rts *Return to caller1122 * 1123 *mc2out -- Output to MIDI-21124 *------ ----------------1125 mc2out: lea mc2iorec,a0 *MIDI-2 iorec address to a01126 lea MC2ACIA,a1 *MIDI-2 ACIA address to a11127 move.w 6(a7),d1 *Get data byte from stack1128 bsr midput *Attempt to output1129 bcs mc2out *Try until it works ...1130 * 1131 rts *Return to caller1132 * 1133 .endc 1134 * 1135 .page 1136 * 1137 *serput -- Output a character to a serial port1138 *------ -----------------------------------1139 serput: move.w sr,-(a7) *Save status register1140 ori.w #IPL7,sr *Set IPL = 7 (disable ints)1141 move.b ACIA_ISR(a1),isr(a0) *Get ACIA isr1142 move.b ACIA_CSR(a1),csr(a0) *Get ACIA csr1143 btst #0,linedisc(a0) *XON/XOFF mode ?1144 beq serpt_1 *Jump if not1145 * 1146 tst.b flagxoff(a0) *XON active ?1147 bne serpt_2 *Jump if so1148 * 1149 serpt_1: btst.b #6,isr(a0) *Is ACIA still sending ?1150 beq serpt_2 *Jump if so1151 * 1152 move.w obufhd(a0),d2 *Head index to d21153 cmp.w obuftl(a0),d2 *Compare to tail index1154 bne serpt_2 *Jump if buffer not empty1155 * 1156 move.b d1,ACIA_TDR(a1) *Give byte to ACIA to send1157 bra serpt_3 *Go deal with RTS/CTS if needed1158 * 1159 serpt_2: move.w obuftl(a0),d2 *Tail index to d21160 bsr wrapout *Adjust for wraparound1161 cmp.w obufhd(a0),d2 *Compare to head index1162 beq serpt_4 *Jump if buffer full1163 * 1164 move.l obuf(a0),a2 *Get buffer base address in a21165 move.b d1,0(a2,d2) *Put character in buffer1166 move.w d2,obuftl(a0) *Update buffer tail index1167 * 1168 serpt_3: bsr serchk *Check status on our way out1169 bsr rtschk *Handle RTS protocol1170 move.w (a7)+,sr *Restore status register1171 andi # $FFFE,sr *Clear carry flag = OK1172 rts *Return to caller1173 * 1174 serpt_4: bsr serchk *Check status on our way out1175 bsr rtschk *Handle RTS protocol1176 move.w (a7)+,sr *Restore status register1177 ori # $0001,sr *Set carry flag = buffer full1178 rts *Return to caller1179 * 1180 .page 1181 * 1112 1113 | mc1out -- Output to MIDI-1 1114 | ------ ---------------- 1115 mc1out: lea mc1iorec,a0 | MIDI-1 iorec address to a0 1116 lea MC1ACIA,a1 | MIDI-1 ACIA address to a1 1117 move.w 6(a7),d1 | Get data byte from stack 1118 bsr midput | Attempt to output 1119 bcs mc1out | Try until it works ... 1120 1121 rts | Return to caller 1122 1123 | mc2out -- Output to MIDI-2 1124 | ------ ---------------- 1125 mc2out: lea mc2iorec,a0 | MIDI-2 iorec address to a0 1126 lea MC2ACIA,a1 | MIDI-2 ACIA address to a1 1127 move.w 6(a7),d1 | Get data byte from stack 1128 bsr midput | Attempt to output 1129 bcs mc2out | Try until it works ... 1130 1131 rts | Return to caller 1132 1133 .endc 1134 1135 .page 1136 1137 | serput -- Output a character to a serial port 1138 | ------ ----------------------------------- 1139 serput: move.w sr,-(a7) | Save status register 1140 ori.w #IPL7,sr | Set IPL = 7 (disable ints) 1141 move.b ACIA_ISR(a1),isr(a0) | Get ACIA isr 1142 move.b ACIA_CSR(a1),csr(a0) | Get ACIA csr 1143 btst #0,linedisc(a0) | XON/XOFF mode ? 1144 beq serpt_1 | Jump if not 1145 1146 tst.b flagxoff(a0) | XON active ? 1147 bne serpt_2 | Jump if so 1148 1149 serpt_1: btst.b #6,isr(a0) | Is ACIA still sending ? 1150 beq serpt_2 | Jump if so 1151 1152 move.w obufhd(a0),d2 | Head index to d2 1153 cmp.w obuftl(a0),d2 | Compare to tail index 1154 bne serpt_2 | Jump if buffer not empty 1155 1156 move.b d1,ACIA_TDR(a1) | Give byte to ACIA to send 1157 bra serpt_3 | Go deal with RTS/CTS if needed 1158 1159 serpt_2: move.w obuftl(a0),d2 | Tail index to d2 1160 bsr wrapout | Adjust for wraparound 1161 cmp.w obufhd(a0),d2 | Compare to head index 1162 beq serpt_4 | Jump if buffer full 1163 1164 move.l obuf(a0),a2 | Get buffer base address in a2 1165 move.b d1,0(a2,d2) | Put character in buffer 1166 move.w d2,obuftl(a0) | Update buffer tail index 1167 1168 serpt_3: bsr serchk | Check status on our way out 1169 bsr rtschk | Handle RTS protocol 1170 move.w (a7)+,sr | Restore status register 1171 andi #0xFFFE,sr | Clear carry flag = OK 1172 rts | Return to caller 1173 1174 serpt_4: bsr serchk | Check status on our way out 1175 bsr rtschk | Handle RTS protocol 1176 move.w (a7)+,sr | Restore status register 1177 ori #0x0001,sr | Set carry flag = buffer full 1178 rts | Return to caller 1179 1180 .page 1181 1182 1182 .ifne BUCHLA 1183 * 1184 *midput -- Output to MIDI1185 *------ --------------1186 midput: move.w sr,-(a7) *Save status register1187 ori.w #IPL7,sr *Set IPL = 7 (diable ints)1188 move.b ACIA_ISR(a1),isr(a0) *Get ACIA isr1189 move.b ACIA_CSR(a1),csr(a0) *Get ACIA csr1190 btst.b #6,isr(a0) *Is ACIA still sending ?1191 beq midpt_2 *Jump if so1192 * 1193 move.w obufhd(a0),d2 *Head index to d21194 cmp.w obuftl(a0),d2 *Compare to tail index1195 bne midpt_2 *Jump if buffer not empty1196 * 1197 move.b d1,ACIA_TDR(a1) *Give byte to ACIA to send1198 bra midpt_3 *Go set final status and exit1199 * 1200 midpt_2: move.w obuftl(a0),d2 *Tail index to d21201 bsr wrapout *Adjust for wraparound1202 cmp.w obufhd(a0),d2 *Compare to head index1203 beq midpt_4 *Jump if buffer full1204 * 1205 move.l obuf(a0),a2 *Get buffer base address in a21206 move.b d1,0(a2,d2) *Put character in buffer1207 move.w d2,obuftl(a0) *Update buffer tail index1208 * 1209 midpt_3: bsr midchk *Check status on our way out1210 move.w (a7)+,sr *Restore status register1211 andi # $FFFE,sr *Clear carry flag = OK1212 rts *Return to caller1213 * 1214 midpt_4: bsr midchk *Check status on our way out1215 move.w (a7)+,sr *Restore status register1216 ori # $0001,sr *Set carry flag = buffer full1217 rts *Return to caller1218 * 1219 .endc 1220 * 1221 .page 1222 * 1223 *rtschk -- Check RTS mode and turn on RTS if it's enabled1224 *------ ----------------------------------------------1225 rtschk: btst #1,linedisc(a0) *RTS/CTS mode set ?1226 beq rts_1 *Jump if not1227 * 1228 bsr rtson *Turn on RTS1229 * 1230 rts_1: rts *Return to caller1231 * 1232 *rsilen -- Get length of portion of input buffer that's been used so far1233 *------ -------------------------------------------------------------1234 rsilen: move.w ibuftl(a0),d2 *Tail index to d21235 move.w ibufhd(a0),d3 *Head index to d31236 cmp.w d3,d2 *Head > Tail ?1237 bhi rsi_1 *Jump if not1238 * 1239 add.w ibufsize(a0),d2 *Add buffer size to tail index1240 * 1241 rsi_1: sub.w d3,d2 *Length = (adjusted)Tail - Head1242 rts *Return to caller1243 * 1244 *rtson -- Turn on RTS line1245 *----- ----------------1246 rtson: move.b cfr1(a0),d0 *Pick up CFR1 image1247 bclr #0,d0 *Turn on RTS line (active low)1248 bset #7,d0 *Make sure MS bit is set1249 move.b d0,cfr1(a0) *Update CFR1 image1250 move.b d0,ACIA_CFR(a1) *Send CFR to hardware1251 rts *Return to caller1252 * 1253 *rtsoff -- Turn off RTS line1254 *------ -----------------1255 rtsoff: move.b cfr1(a0),d0 *Pick up CFR1 image1256 bset #0,d0 *Turn off RTS line (active low)1257 bset #7,d0 *Make sure MS bit is set1258 move.b d0,cfr1(a0) *Update CFR1 image1259 move.b d0,ACIA_CFR(a1) *Send CFR to hardware1183 1184 | midput -- Output to MIDI 1185 | ------ -------------- 1186 midput: move.w sr,-(a7) | Save status register 1187 ori.w #IPL7,sr | Set IPL = 7 (diable ints) 1188 move.b ACIA_ISR(a1),isr(a0) | Get ACIA isr 1189 move.b ACIA_CSR(a1),csr(a0) | Get ACIA csr 1190 btst.b #6,isr(a0) | Is ACIA still sending ? 1191 beq midpt_2 | Jump if so 1192 1193 move.w obufhd(a0),d2 | Head index to d2 1194 cmp.w obuftl(a0),d2 | Compare to tail index 1195 bne midpt_2 | Jump if buffer not empty 1196 1197 move.b d1,ACIA_TDR(a1) | Give byte to ACIA to send 1198 bra midpt_3 | Go set final status and exit 1199 1200 midpt_2: move.w obuftl(a0),d2 | Tail index to d2 1201 bsr wrapout | Adjust for wraparound 1202 cmp.w obufhd(a0),d2 | Compare to head index 1203 beq midpt_4 | Jump if buffer full 1204 1205 move.l obuf(a0),a2 | Get buffer base address in a2 1206 move.b d1,0(a2,d2) | Put character in buffer 1207 move.w d2,obuftl(a0) | Update buffer tail index 1208 1209 midpt_3: bsr midchk | Check status on our way out 1210 move.w (a7)+,sr | Restore status register 1211 andi #0xFFFE,sr | Clear carry flag = OK 1212 rts | Return to caller 1213 1214 midpt_4: bsr midchk | Check status on our way out 1215 move.w (a7)+,sr | Restore status register 1216 ori #0x0001,sr | Set carry flag = buffer full 1217 rts | Return to caller 1218 1219 .endc 1220 1221 .page 1222 1223 | rtschk -- Check RTS mode and turn on RTS if it's enabled 1224 | ------ ---------------------------------------------- 1225 rtschk: btst #1,linedisc(a0) | RTS/CTS mode set ? 1226 beq rts_1 | Jump if not 1227 1228 bsr rtson | Turn on RTS 1229 1230 rts_1: rts | Return to caller 1231 1232 | rsilen -- Get length of portion of input buffer that's been used so far 1233 | ------ ------------------------------------------------------------- 1234 rsilen: move.w ibuftl(a0),d2 | Tail index to d2 1235 move.w ibufhd(a0),d3 | Head index to d3 1236 cmp.w d3,d2 | Head > Tail ? 1237 bhi rsi_1 | Jump if not 1238 1239 add.w ibufsize(a0),d2 | Add buffer size to tail index 1240 1241 rsi_1: sub.w d3,d2 | Length = (adjusted)Tail - Head 1242 rts | Return to caller 1243 1244 | rtson -- Turn on RTS line 1245 | ----- ---------------- 1246 rtson: move.b cfr1(a0),d0 | Pick up CFR1 image 1247 bclr #0,d0 | Turn on RTS line (active low) 1248 bset #7,d0 | Make sure MS bit is set 1249 move.b d0,cfr1(a0) | Update CFR1 image 1250 move.b d0,ACIA_CFR(a1) | Send CFR to hardware 1251 rts | Return to caller 1252 1253 | rtsoff -- Turn off RTS line 1254 | ------ ----------------- 1255 rtsoff: move.b cfr1(a0),d0 | Pick up CFR1 image 1256 bset #0,d0 | Turn off RTS line (active low) 1257 bset #7,d0 | Make sure MS bit is set 1258 move.b d0,cfr1(a0) | Update CFR1 image 1259 move.b d0,ACIA_CFR(a1) | Send CFR to hardware 1260 1260 rts 1261 * 1262 .page 1263 * 1264 *serintr -- Serial (Serial-1, Serial-2, MIDI-1, MIDI-2) interrupt handler1265 *------- -------------------------------------------------------------1266 serintr: movem.l d0-d3/a0-a2,-(a7) *Save registers1267 lea sr1iorec,a0 *Point at Serial-1 iorec1268 lea SR1ACIA,a1 *Point at Serial-1 ACIA1269 bsr serint *Go process (possible) int.1270 * 1271 lea sr2iorec,a0 *Point at Serial-2 iorec1272 lea SR2ACIA,a1 *Point at Serial-2 ACIA1273 bsr serint *Go process (possible) int.1274 * 1261 1262 .page 1263 1264 | serintr -- Serial (Serial-1, Serial-2, MIDI-1, MIDI-2) interrupt handler 1265 | ------- ------------------------------------------------------------- 1266 serintr: movem.l d0-d3/a0-a2,-(a7) | Save registers 1267 lea sr1iorec,a0 | Point at Serial-1 iorec 1268 lea SR1ACIA,a1 | Point at Serial-1 ACIA 1269 bsr serint | Go process (possible) int. 1270 1271 lea sr2iorec,a0 | Point at Serial-2 iorec 1272 lea SR2ACIA,a1 | Point at Serial-2 ACIA 1273 bsr serint | Go process (possible) int. 1274 1275 1275 .ifne BUCHLA 1276 * 1277 lea mc1iorec,a0 *Point at MIDI-1 iorec1278 lea MC1ACIA,a1 *Point at MIDI-1 ACIA1279 bsr midint *Go process (possible) int.1280 * 1281 lea mc2iorec,a0 *Point at MIDI-2 iorec1282 lea MC2ACIA,a1 *Point at MIDI-2 ACIA1283 bsr midint *Go process (possible) int.1284 * 1285 .endc 1286 * 1287 movem.l (a7)+,d0-d3/a0-a2 *Restore registers1288 rte *Return from exception1289 * 1290 .page 1291 * 1292 *serint -- Process an interrupt from Serial-1 or Serial-21293 *------ ----------------------------------------------1294 serint: move.b ACIA_ISR(a1),isr(a0) *Get and save ISR1295 move.b ACIA_CSR(a1),csr(a0) *Get and save CSR1296 * 1297 btst.b #7,isr(a0) *Was int for this device ?1298 beq serintx *Jump if not1299 * 1300 serchk: btst.b #1,isr(a0) *FRM/OVR/BRK error ?1301 bne sererr *Jump if so1302 * 1303 btst.b #0,isr(a0) *Receiver interrupt ?1304 bne serrx *Jump if so1305 * 1306 sertxq: btst.b #6,isr(a0) *Transmitter interrupt ?1307 bne sertx *Jump if so1308 * 1309 serctq: btst.b #5,isr(a0) *CTS interrupt ?1310 bne sercts *Jump if so1311 * 1312 serintx: rts *Return to caller1313 * 1314 sererr: addq.w #1,errct(a0) *Update error count1315 move.b ACIA_RDR(a1),erbyte(a0) *Get error byte1276 1277 lea mc1iorec,a0 | Point at MIDI-1 iorec 1278 lea MC1ACIA,a1 | Point at MIDI-1 ACIA 1279 bsr midint | Go process (possible) int. 1280 1281 lea mc2iorec,a0 | Point at MIDI-2 iorec 1282 lea MC2ACIA,a1 | Point at MIDI-2 ACIA 1283 bsr midint | Go process (possible) int. 1284 1285 .endc 1286 1287 movem.l (a7)+,d0-d3/a0-a2 | Restore registers 1288 rte | Return from exception 1289 1290 .page 1291 1292 | serint -- Process an interrupt from Serial-1 or Serial-2 1293 | ------ ---------------------------------------------- 1294 serint: move.b ACIA_ISR(a1),isr(a0) | Get and save ISR 1295 move.b ACIA_CSR(a1),csr(a0) | Get and save CSR 1296 1297 btst.b #7,isr(a0) | Was int for this device ? 1298 beq serintx | Jump if not 1299 1300 serchk: btst.b #1,isr(a0) | FRM/OVR/BRK error ? 1301 bne sererr | Jump if so 1302 1303 btst.b #0,isr(a0) | Receiver interrupt ? 1304 bne serrx | Jump if so 1305 1306 sertxq: btst.b #6,isr(a0) | Transmitter interrupt ? 1307 bne sertx | Jump if so 1308 1309 serctq: btst.b #5,isr(a0) | CTS interrupt ? 1310 bne sercts | Jump if so 1311 1312 serintx: rts | Return to caller 1313 1314 sererr: addq.w #1,errct(a0) | Update error count 1315 move.b ACIA_RDR(a1),erbyte(a0) | Get error byte 1316 1316 rts 1317 * 1318 *Handle CTS interupt1319 * 1320 sercts: btst.b #1,linedisc(a0) *RTS/CTS mode ?1321 beq serintx *Ignore if not1322 * 1323 btst.b #5,csr(a0) *CTS set ?1324 beq serintx *Ignore if not1325 * 1326 sercts1: btst.b #6,isr(a0) *TDRE set ?1327 beq sercts1 *Loop until it is (!)1328 * 1329 move.w obufhd(a0),d2 *Head index to d21330 cmp.w obuftl(a0),d2 *Compare to tail index1331 beq serintx *Done if buffer empty1332 * 1333 bsr.w wrapout *Adjust pointer for wraparound1334 move.l obuf(a0),a2 *Get buffer base in a21335 move.b 0(a2,d2),ACIA_TDR(a1) *Send byte on its way1336 move.w d2,obufhd(a0) *Save updated head index1317 1318 | Handle CTS interupt 1319 1320 sercts: btst.b #1,linedisc(a0) | RTS/CTS mode ? 1321 beq serintx | Ignore if not 1322 1323 btst.b #5,csr(a0) | CTS set ? 1324 beq serintx | Ignore if not 1325 1326 sercts1: btst.b #6,isr(a0) | TDRE set ? 1327 beq sercts1 | Loop until it is (!) 1328 1329 move.w obufhd(a0),d2 | Head index to d2 1330 cmp.w obuftl(a0),d2 | Compare to tail index 1331 beq serintx | Done if buffer empty 1332 1333 bsr.w wrapout | Adjust pointer for wraparound 1334 move.l obuf(a0),a2 | Get buffer base in a2 1335 move.b 0(a2,d2),ACIA_TDR(a1) | Send byte on its way 1336 move.w d2,obufhd(a0) | Save updated head index 1337 1337 rts 1338 * 1339 .page 1340 * 1341 *Handle receiver interrupt1342 * 1343 serrx: btst.b #1,linedisc(a0) *RTS/CTS mode set ?1344 beq serrx1 *Jump if not1345 * 1346 bsr.w rtsoff *Turn off RTS1347 * 1348 serrx1: move.b ACIA_RDR(a1),d0 *Read data from ACIA1349 btst.b #1,linedisc(a0) *RTS/CTS mode set ?1350 bne serrx3 *Jump if so1351 * 1352 btst.b #0,linedisc(a0) *XON/XOFF mode set ?1353 beq serrx3 *Jump if not1354 * 1355 cmpi.b # $11,d0 *Is this an XON ?1356 bne serrx2 *Jump if not1357 * 1358 move.b # $00,flagxoff(a0) *Clear flagxoff1359 bra sertxq *Done1360 * 1361 serrx2: cmpi.b # $13,d0 *Is this an XOFF ?1362 bne serrx3 *Jump if not1363 * 1364 move.b # $FF,flagxoff(a0) *Set flagxoff1365 bra sertxq *Done1366 * 1367 serrx3: move.w ibuftl(a0),d1 *Get tail index in d11368 bsr.w wrapin *Adjust for wraparound1369 cmp.w ibufhd(a0),d1 *Head = tail ?1370 beq seribf *If so, we drop the character1371 * 1372 move.l ibuf(a0),a2 *Get buffer address1373 move.b d0,0(a2,d1) *Stash byte in buffer1374 move.w d1,ibuftl(a0) *Save updated tail index1375 bsr rsilen *Get length of buffer used1376 cmp.w ibufhi(a0),d2 *Hit high water mark ?1377 bne serrx4 *Jump if not1378 * 1379 btst.b #1,linedisc(a0) *RTS/CTS mode set ?1380 bne sertxq *Done if so1381 * 1382 btst.b #0,linedisc(a0) *XON/XOFF mode set ?1383 beq serrx4 *Jump if not1384 * 1385 tst.b flagxon(a0) *XOFF already sent ?1386 bne serrx4 *Jump if so1387 * 1388 move.b # $FF,flagxon(a0) *Set the flag1389 move.b # $13,d1 *Send an XOFF1390 bsr.w serput *...1391 * 1392 .page 1393 * 1394 serrx4: btst #1,linedisc(a0) *RTS/CTS mode set ?1395 beq sertxq *Done if not1396 * 1397 bsr rtson *Turn on RTS1338 1339 .page 1340 1341 | Handle receiver interrupt 1342 1343 serrx: btst.b #1,linedisc(a0) | RTS/CTS mode set ? 1344 beq serrx1 | Jump if not 1345 1346 bsr.w rtsoff | Turn off RTS 1347 1348 serrx1: move.b ACIA_RDR(a1),d0 | Read data from ACIA 1349 btst.b #1,linedisc(a0) | RTS/CTS mode set ? 1350 bne serrx3 | Jump if so 1351 1352 btst.b #0,linedisc(a0) | XON/XOFF mode set ? 1353 beq serrx3 | Jump if not 1354 1355 cmpi.b #0x11,d0 | Is this an XON ? 1356 bne serrx2 | Jump if not 1357 1358 move.b #0x00,flagxoff(a0) | Clear flagxoff 1359 bra sertxq | Done 1360 1361 serrx2: cmpi.b #0x13,d0 | Is this an XOFF ? 1362 bne serrx3 | Jump if not 1363 1364 move.b #0xFF,flagxoff(a0) | Set flagxoff 1365 bra sertxq | Done 1366 1367 serrx3: move.w ibuftl(a0),d1 | Get tail index in d1 1368 bsr.w wrapin | Adjust for wraparound 1369 cmp.w ibufhd(a0),d1 | Head = tail ? 1370 beq seribf | If so, we drop the character 1371 1372 move.l ibuf(a0),a2 | Get buffer address 1373 move.b d0,0(a2,d1) | Stash byte in buffer 1374 move.w d1,ibuftl(a0) | Save updated tail index 1375 bsr rsilen | Get length of buffer used 1376 cmp.w ibufhi(a0),d2 | Hit high water mark ? 1377 bne serrx4 | Jump if not 1378 1379 btst.b #1,linedisc(a0) | RTS/CTS mode set ? 1380 bne sertxq | Done if so 1381 1382 btst.b #0,linedisc(a0) | XON/XOFF mode set ? 1383 beq serrx4 | Jump if not 1384 1385 tst.b flagxon(a0) | XOFF already sent ? 1386 bne serrx4 | Jump if so 1387 1388 move.b #0xFF,flagxon(a0) | Set the flag 1389 move.b #0x13,d1 | Send an XOFF 1390 bsr.w serput | ... 1391 1392 .page 1393 1394 serrx4: btst #1,linedisc(a0) | RTS/CTS mode set ? 1395 beq sertxq | Done if not 1396 1397 bsr rtson | Turn on RTS 1398 1398 bra sertxq 1399 * 1400 *Handle transmitter interrupt1401 * 1402 sertx: btst.b #1,linedisc(a0) *RTS/CTS mode set ?1403 bne sertx2 *If so, go check CTS1404 * 1405 btst.b #0,linedisc(a0) *XON/XOFF mode set ?1406 beq sertx1 *Jump if not1407 * 1408 tst.b flagxoff(a0) *Check flagxoff1409 bne serctq *Done if set1410 * 1411 sertx1: move.w obufhd(a0),d2 *Head index to d21412 cmp.w obuftl(a0),d2 *Compare to tail index1413 beq serctq *Done if buffer empty1414 * 1415 bsr wrapout *Adjust pointer for wraparound1416 move.l obuf(a0),a2 *Get buffer base address1417 move.b 0(a2,d2),ACIA_TDR(a1) *Send byte on its way1418 move.w d2,obufhd(a0) *Save updated head index1419 bra serctq *Done1420 * 1421 sertx2: btst.b #5,csr(a0) *CTS set in csr ?1422 beq serctq *If not, go check for CTS int1423 * 1424 bra sertx1 *CTS was set, go transmit1425 * 1426 seribf: move.b d0,erbyte(a0) *Log dropped character1427 addq.w #1,ibfct(a0) *...1428 bra sertxq *Go check Tx interrupt1429 * 1430 .page 1431 * 1399 1400 | Handle transmitter interrupt 1401 1402 sertx: btst.b #1,linedisc(a0) | RTS/CTS mode set ? 1403 bne sertx2 | If so, go check CTS 1404 1405 btst.b #0,linedisc(a0) | XON/XOFF mode set ? 1406 beq sertx1 | Jump if not 1407 1408 tst.b flagxoff(a0) | Check flagxoff 1409 bne serctq | Done if set 1410 1411 sertx1: move.w obufhd(a0),d2 | Head index to d2 1412 cmp.w obuftl(a0),d2 | Compare to tail index 1413 beq serctq | Done if buffer empty 1414 1415 bsr wrapout | Adjust pointer for wraparound 1416 move.l obuf(a0),a2 | Get buffer base address 1417 move.b 0(a2,d2),ACIA_TDR(a1) | Send byte on its way 1418 move.w d2,obufhd(a0) | Save updated head index 1419 bra serctq | Done 1420 1421 sertx2: btst.b #5,csr(a0) | CTS set in csr ? 1422 beq serctq | If not, go check for CTS int 1423 1424 bra sertx1 | CTS was set, go transmit 1425 1426 seribf: move.b d0,erbyte(a0) | Log dropped character 1427 addq.w #1,ibfct(a0) | ... 1428 bra sertxq | Go check Tx interrupt 1429 1430 .page 1431 1432 1432 .ifne BUCHLA 1433 * 1434 *midint -- Process an interrupt from MIDI-1 or MIDI-21435 *------ ------------------------------------------1436 midint: move.b ACIA_ISR(a1),isr(a0) *Get and save ISR1437 move.b ACIA_CSR(a1),csr(a0) *Get and save CSR1438 * 1439 btst.b #7,isr(a0) *Was int for this device ?1440 beq midintx *Jump if not1441 * 1442 midchk: btst.b #1,isr(a0) *FRM/OVR/BRK error ?1443 bne miderr *Jump if so1444 * 1445 btst.b #0,isr(a0) *Receiver interrupt ?1446 bne midrx *Jump if so1447 * 1448 midtxq: btst.b #6,isr(a0) *Transmitter interrupt ?1449 bne midtx *Jump if so1450 * 1451 midintx: rts *Return to caller1452 * 1453 miderr: addq.w #1,errct(a0) *Update error count1454 move.b ACIA_RDR(a1),erbyte(a0) *Get error byte1433 1434 | midint -- Process an interrupt from MIDI-1 or MIDI-2 1435 | ------ ------------------------------------------ 1436 midint: move.b ACIA_ISR(a1),isr(a0) | Get and save ISR 1437 move.b ACIA_CSR(a1),csr(a0) | Get and save CSR 1438 1439 btst.b #7,isr(a0) | Was int for this device ? 1440 beq midintx | Jump if not 1441 1442 midchk: btst.b #1,isr(a0) | FRM/OVR/BRK error ? 1443 bne miderr | Jump if so 1444 1445 btst.b #0,isr(a0) | Receiver interrupt ? 1446 bne midrx | Jump if so 1447 1448 midtxq: btst.b #6,isr(a0) | Transmitter interrupt ? 1449 bne midtx | Jump if so 1450 1451 midintx: rts | Return to caller 1452 1453 miderr: addq.w #1,errct(a0) | Update error count 1454 move.b ACIA_RDR(a1),erbyte(a0) | Get error byte 1455 1455 rts 1456 * 1457 *Handle receiver interrupt1458 * 1459 midrx: move.b ACIA_RDR(a1),d0 *Read data from ACIA1460 move.w ibuftl(a0),d1 *Get tail index in d11461 bsr.w wrapin *Adjust for wraparound1462 cmp.w ibufhd(a0),d1 *Head = tail ?1463 beq midibf *If so, we drop the character1464 * 1465 move.l ibuf(a0),a2 *Get buffer address1466 move.b d0,0(a2,d1) *Stash byte in buffer1467 move.w d1,ibuftl(a0) *Save updated tail index1468 bra midtxq *Done (go check tx int)1469 * 1470 .page 1471 * 1472 *Handle transmitter interrupt1473 * 1474 midtx: move.w obufhd(a0),d2 *Head index to d21475 cmp.w obuftl(a0),d2 *Compare to tail index1476 beq midintx *Done if buffer empty1477 * 1478 bsr wrapout *Adjust pointer for wraparound1479 move.l obuf(a0),a2 *Get buffer base address1480 move.b 0(a2,d2),ACIA_TDR(a1) *Send byte on its way1481 move.w d2,obufhd(a0) *Save updated head index1482 bra midintx *Done1483 * 1484 midibf: move.b d0,erbyte(a0) *Log dropped character1485 addq.w #1,ibfct(a0) *...1486 bra midtxq *Go check Tx interrupt1487 * 1488 .endc 1489 * 1490 .page 1491 * 1492 *setexec -- Set an exception vector1493 *------- -----------------------1494 setexec: move.w 4(a7),d0 *Get vector number1495 lsl.w #2,d0 *.. times 41496 sub.l a0,a0 *Clear a01497 lea 0(a0,d0),a0 *Get address of old vector1498 move.l (a0),d0 *Move old vector to d01499 move.l 6(a7),d1 *Pick up new vector1500 bmi setexec1 *Don't set if = -11501 * 1502 move.l d1,(a0) *Set new vector1503 * 1504 setexec1: rts *Return to caller1505 * 1506 *piorec -- Get pointer to iorec structure1507 *------ ------------------------------1508 piorec: moveq.l #0,d1 *Clear out d11509 move.w 4(a7),d1 *Get device number1510 move.w sr,-(a7) *Save status register1511 ori.w #IPL7,sr *Set IPL = 7 (no ints)1512 lea iortab,a2 *Get base address of table1513 asl.l #2,d1 *Device # times 4 for index1514 move.l 0(a2,d1),d0 *Get iorec address from table1515 move.w (a7)+,sr *Restore status register1516 rts *Return to caller1517 * 1518 .page 1519 * 1520 *setport -- Set ACIA parameters (unit, mode, baud, CFR0, CFR1)1521 *------- ---------------------------------------------------1522 setport: moveq.l #0,d1 *Clear out d11523 move.w 4(a7),d1 *Get device number1524 asl.l #3,d1 *Times 8 for index1525 ori.w #IPL7,sr *Set IPL = 7 (no ints)1526 lea aciatab,a2 *Get base of table1527 move.l 0(a2,d1),d0 *Get iorec address1528 move.l 4(a2,d1),d2 *Get ACIA address1529 movea.l d0,a0 *Setup a0 = iorec address1530 movea.l d2,a1 *Setup a1 = ACIA address1531 tst.w 6(a7) *Change mode ?1532 bmi setpt1 *Jump if not1533 * 1534 move.b 7(a7),linedisc(a0) *Set line discipline (mode)1535 * 1536 setpt1: tst.w 8(a7) *Change baud rate ?1537 bmi setpt2 *Jump if not1538 * 1539 moveq.l #0,d1 *Clear out d11540 move.w 8(a7),d1 *Get baud rate index1541 lea brtable,a2 *Get base of baud rate table1542 move.b 0(a2,d1),d2 *Get baud rate code from table1543 move.b cfr0(a0),d0 *Get current CFR01544 andi.w # $0070,d0 *Mask off old baud rate code1545 or.w d2,d0 *OR in new baud rate code1546 move.b d0,cfr0(a0) *Update CFR0 in table1547 move.b d0,ACIA_CFR(a1) *Update hardware1548 * 1549 setpt2: tst.w 10(a7) *Change CFR0 ?1550 bmi setpt3 *Jump if not1551 * 1552 move.b 11(a7),cfr0(a0) *Update CFR0 in table1553 move.b cfr0(a0),ACIA_CFR(a1) *Update CFR0 in hardware1554 * 1555 setpt3: tst.w 12(a7) *Change CFR1 ?1556 bmi setpt4 *Jump if not1557 * 1558 bset.b #7,13(a7) *Force D7 = 1 in argument1559 move.b 13(a7),cfr1(a0) *Update CFR1 in table1560 move.b cfr1(a0),ACIA_CFR(a1) *Update CFR1 in hardware1561 * 1562 setpt4: rts *Return to caller1563 * 1564 .page 1565 * 1566 *aciainit -- Initialize an ACIA port1567 *-------- -----------------------1568 aciainit: move.w #IORECLN,d0 *Setup byte count for move1569 move.l a0,-(a7) *Save iorec base1570 * 1571 aciai_1: move.b (a2)+,(a0)+ *Move the default to the iorec1572 dbf d0,aciai_1 *...1573 * 1574 move.l (a7)+,a0 *Restore iorec base1575 move.b cfr0(a0),ACIA_CFR(a1) *Setup CFR01576 move.b cfr1(a0),ACIA_CFR(a1) *Setup CFR11577 move.b ACIA_RDR(a1),d0 *Clear RDR1578 move.b # $7F,ACIA_IER(a1) *Disable all interrupts1579 btst.b #1,linedisc(a0) *Are we in RTS/CTS mode ?1580 bne aciai_2 *Jump if so1581 * 1582 move.b # $C3,ACIA_IER(a1) *Enable TDRE, RDRF1583 bra aciai_3 *Go return1584 * 1585 aciai_2: move.b # $E3,ACIA_IER(a1) *Enable interrupts we want1586 * 1587 aciai_3: rts *Return to caller1588 * 1589 .page 1590 * 1456 1457 | Handle receiver interrupt 1458 1459 midrx: move.b ACIA_RDR(a1),d0 | Read data from ACIA 1460 move.w ibuftl(a0),d1 | Get tail index in d1 1461 bsr.w wrapin | Adjust for wraparound 1462 cmp.w ibufhd(a0),d1 | Head = tail ? 1463 beq midibf | If so, we drop the character 1464 1465 move.l ibuf(a0),a2 | Get buffer address 1466 move.b d0,0(a2,d1) | Stash byte in buffer 1467 move.w d1,ibuftl(a0) | Save updated tail index 1468 bra midtxq | Done (go check tx int) 1469 1470 .page 1471 1472 | Handle transmitter interrupt 1473 1474 midtx: move.w obufhd(a0),d2 | Head index to d2 1475 cmp.w obuftl(a0),d2 | Compare to tail index 1476 beq midintx | Done if buffer empty 1477 1478 bsr wrapout | Adjust pointer for wraparound 1479 move.l obuf(a0),a2 | Get buffer base address 1480 move.b 0(a2,d2),ACIA_TDR(a1) | Send byte on its way 1481 move.w d2,obufhd(a0) | Save updated head index 1482 bra midintx | Done 1483 1484 midibf: move.b d0,erbyte(a0) | Log dropped character 1485 addq.w #1,ibfct(a0) | ... 1486 bra midtxq | Go check Tx interrupt 1487 1488 .endc 1489 1490 .page 1491 1492 | setexec -- Set an exception vector 1493 | ------- ----------------------- 1494 setexec: move.w 4(a7),d0 | Get vector number 1495 lsl.w #2,d0 | .. times 4 1496 sub.l a0,a0 | Clear a0 1497 lea 0(a0,d0),a0 | Get address of old vector 1498 move.l (a0),d0 | Move old vector to d0 1499 move.l 6(a7),d1 | Pick up new vector 1500 bmi setexec1 | Don't set if = -1 1501 1502 move.l d1,(a0) | Set new vector 1503 1504 setexec1: rts | Return to caller 1505 1506 | piorec -- Get pointer to iorec structure 1507 | ------ ------------------------------ 1508 piorec: moveq.l #0,d1 | Clear out d1 1509 move.w 4(a7),d1 | Get device number 1510 move.w sr,-(a7) | Save status register 1511 ori.w #IPL7,sr | Set IPL = 7 (no ints) 1512 lea iortab,a2 | Get base address of table 1513 asl.l #2,d1 | Device # times 4 for index 1514 move.l 0(a2,d1),d0 | Get iorec address from table 1515 move.w (a7)+,sr | Restore status register 1516 rts | Return to caller 1517 1518 .page 1519 1520 | setport -- Set ACIA parameters (unit, mode, baud, CFR0, CFR1) 1521 | ------- --------------------------------------------------- 1522 setport: moveq.l #0,d1 | Clear out d1 1523 move.w 4(a7),d1 | Get device number 1524 asl.l #3,d1 | Times 8 for index 1525 ori.w #IPL7,sr | Set IPL = 7 (no ints) 1526 lea aciatab,a2 | Get base of table 1527 move.l 0(a2,d1),d0 | Get iorec address 1528 move.l 4(a2,d1),d2 | Get ACIA address 1529 movea.l d0,a0 | Setup a0 = iorec address 1530 movea.l d2,a1 | Setup a1 = ACIA address 1531 tst.w 6(a7) | Change mode ? 1532 bmi setpt1 | Jump if not 1533 1534 move.b 7(a7),linedisc(a0) | Set line discipline (mode) 1535 1536 setpt1: tst.w 8(a7) | Change baud rate ? 1537 bmi setpt2 | Jump if not 1538 1539 moveq.l #0,d1 | Clear out d1 1540 move.w 8(a7),d1 | Get baud rate index 1541 lea brtable,a2 | Get base of baud rate table 1542 move.b 0(a2,d1),d2 | Get baud rate code from table 1543 move.b cfr0(a0),d0 | Get current CFR0 1544 andi.w #0x0070,d0 | Mask off old baud rate code 1545 or.w d2,d0 | OR in new baud rate code 1546 move.b d0,cfr0(a0) | Update CFR0 in table 1547 move.b d0,ACIA_CFR(a1) | Update hardware 1548 1549 setpt2: tst.w 10(a7) | Change CFR0 ? 1550 bmi setpt3 | Jump if not 1551 1552 move.b 11(a7),cfr0(a0) | Update CFR0 in table 1553 move.b cfr0(a0),ACIA_CFR(a1) | Update CFR0 in hardware 1554 1555 setpt3: tst.w 12(a7) | Change CFR1 ? 1556 bmi setpt4 | Jump if not 1557 1558 bset.b #7,13(a7) | Force D7 = 1 in argument 1559 move.b 13(a7),cfr1(a0) | Update CFR1 in table 1560 move.b cfr1(a0),ACIA_CFR(a1) | Update CFR1 in hardware 1561 1562 setpt4: rts | Return to caller 1563 1564 .page 1565 1566 | aciainit -- Initialize an ACIA port 1567 | -------- ----------------------- 1568 aciainit: move.w #IORECLN,d0 | Setup byte count for move 1569 move.l a0,-(a7) | Save iorec base 1570 1571 aciai_1: move.b (a2)+,(a0)+ | Move the default to the iorec 1572 dbf d0,aciai_1 | ... 1573 1574 move.l (a7)+,a0 | Restore iorec base 1575 move.b cfr0(a0),ACIA_CFR(a1) | Setup CFR0 1576 move.b cfr1(a0),ACIA_CFR(a1) | Setup CFR1 1577 move.b ACIA_RDR(a1),d0 | Clear RDR 1578 move.b #0x7F,ACIA_IER(a1) | Disable all interrupts 1579 btst.b #1,linedisc(a0) | Are we in RTS/CTS mode ? 1580 bne aciai_2 | Jump if so 1581 1582 move.b #0xC3,ACIA_IER(a1) | Enable TDRE, RDRF 1583 bra aciai_3 | Go return 1584 1585 aciai_2: move.b #0xE3,ACIA_IER(a1) | Enable interrupts we want 1586 1587 aciai_3: rts | Return to caller 1588 1589 .page 1590 1591 1591 .ifne BUCHLA 1592 * 1593 *fastcopy -- Copy disk sector quickly1594 *-------- ------------------------1595 fastcopy: move.l 4(a7),a0 *Get source pointer1596 move.l 8(a7),a1 *Get destination pointer1597 move.w $3F,d0 * 512 bytes (63+1)*81598 * 1599 fastcpy1: move.b (a0)+,(a1)+ *Move 8 bytes1600 move.b (a0)+,(a1)+ *...1601 move.b (a0)+,(a1)+ *...1602 move.b (a0)+,(a1)+ *...1603 move.b (a0)+,(a1)+ *...1604 move.b (a0)+,(a1)+ *...1605 move.b (a0)+,(a1)+ *...1606 move.b (a0)+,(a1)+ *...1607 dbra d0,fastcpy1 *Loop until all bytes are moved1608 * 1609 rts *Return to caller1610 * 1611 .page 1612 * 1613 *_hdvini -- Drive initialization1614 *------- --------------------1615 _hdvini: link a6,#-18 *Reserve space on stack1616 movem.l d3-d7/a3-a5,-(a7) *Preserve registers1617 move.l #300,maxactim * maxactim = 300 *20ms1618 clr.w d0 *Put zeros in ...1619 move.w d0,nflops *... nflops1620 move.w d0,dskmode *... dskmode1621 move.w d0,-2(a6) *Start with drive A1622 bra hdvilp *...1623 * 1624 hdvilp1: movea.l #dskmode,a0 *Get dskmode address in a01625 movea.w -2(a6),a1 *Drive number in a11626 adda.l a1,a0 *Point at dskmode for drive1627 clr.b (a0) *Clear flag in dskmode1628 clr.w -(a7) *Push arguments onto stack1629 clr.w -(a7) *...1630 clr.w -(a7) *...1631 move.w -2(a6),-(a7) *Push drive number onto stack1632 clr.l -(a7) *... filler1633 clr.l -(a7) *... filler1634 jsr flopini *Initialize drive1635 adda.l #16,a7 *Cleanup stack1636 move.w d0,-(a7) *Save error code on stack1637 movea.w -2(a6),a0 *Get drive number1638 adda.l a0,a0 *... times 21639 adda.l #dskerrs,a0 *Add base of dskerrs1640 move.w (a7)+,(a0) *Move error code off of stack1641 bne hdvind *Jump if drive not present1642 * 1643 addq.w #1,nflops *Update number of drives1644 or.l #3,drvbits *Setup drive bits1645 * 1646 hdvind: addq.w #1,-2(a6) *Increment drive number1647 * 1648 hdvilp: cmp.w #2,-2(a6) *See if it's 2 yet1649 blt hdvilp1 *Loop until it is1650 * 1651 movem.l (a7)+,d3-d7/a3-a5 *Restore registers1652 unlk a6 *Release temporary stack space1653 rts *Return to caller1654 * 1655 *drvmap -- get drive map1656 *------ -------------1657 drvmap: move.l drvbits,d0 *Get drive bits1658 rts *Return to caller1659 * 1660 .page 1661 * 1662 *getbpb -- get BIOS parameter block1663 *------ ------------------------1664 getbpb: link a6,#-12 *Reserve space for temporaries1665 movem.l d5-d7/a4-a5,-(a7) *Save registers on stack1666 cmp.w #2,8(a6) *Check drive number1667 blt gbpb1 *Jump if OK1668 * 1669 clr.l d0 *Set drive number to 01670 bra gbpber *Go flag error1671 * 1672 gbpb1: move.w 8(a6),d0 *Get drive number1673 asl.w #5,d0 *... times 321674 ext.l d0 *... extend sign1675 move.l d0,a5 *Move to a51676 add.l #drvbpbs,a5 *Add base of drive bpb are1677 move.l a5,a4 *Save in a41678 * 1679 gbpbrds: move.w #1,(a7) *floprd count = 1,1680 clr.w -(a7) *... side = 0,1681 clr.w -(a7) *... track = 0,1682 move.w #1,-(a7) *... sector = 1,1683 move.w 8(a6),-(a7) *... drive #,1684 clr.l -(a7) *... filler1685 move.l #buffer,-(a7) *... buffer address,1686 jsr floprd *Go read the sector1687 add.l #16,a7 *Cleanup stack1688 move.l d0,-12(a6) *Save error code1689 tst.l -12(a6) *... and test it1690 bge gbpb2 *Jump if OK1691 * 1692 move.w 8(a6),(a7) *Put drive number on stack1693 move.l -12(a6),d0 *Get error code1694 move.w d0,-(a7) *... and put it on the stack1695 jsr criter *Go do critical error routine1696 addq.l #2,a7 *Cleanup stack1697 move.l d0,-12(a6) *Save error code1698 * 1699 gbpb2: move.l -12(a6),d0 *Get error code1700 cmp.l #RETRYIT,d0 *Magic number for retry ?1701 beq gbpbrds *Re-read if so1702 * 1703 tst.l -12(a6) *Test error code1704 bge gbpb3 *Jump if OK1705 * 1706 clr.l d0 *Set code in d01707 bra gbpber *Go set error code1708 * 1709 .page 1710 * 1711 gbpb3: move.l #buffer+11,(a7) *Bytes per sector1712 bsr itom *Convert 8086 to 68K format1713 move.w d0,d7 *Save bytes per sector1714 beq gbpb4 *Jump if zero1715 * 1716 move.b buffer+13,d6 *Sectors per cluster1717 ext.w d6 *... sign extended1718 and.w # $FF,d6 *... and trimmed1719 bne gbpb5 *Jump if non-zero1720 * 1721 gbpb4: clr.l d0 *Set error code1722 bra gbpber *...1723 * 1724 gbpb5: move.w d7,(a4) *Set recsize1725 move.w d6,2(a4) *Set clsiz1726 move.l #buffer+22,(a7) *Convert sectors per fat1727 bsr itom *...1728 move.w d0,8(a4) *Set fsiz1729 move.w 8(a4),d0 *Get fsiz1730 addq.w #1,d0 *... plus 11731 move.w d0,10(a4) *Set fatrec1732 move.w (a4),d0 *Get recsize1733 muls.w 2(a4),d0 *... times clsiz1734 move.w d0,4(a4) *Set clsizb1735 move.l #buffer+17,(a7) *Convert number of dir ents1736 bsr itom *...1737 asl.w #5,d0 *... times 321738 ext.l d0 *... sign extended1739 divs.w (a4),d0 *... / recsize1740 move.w d0,6(a4) *Set rdlen1741 move.w 10(a4),d0 *Get fatrec1742 add.w 6(a4),d0 *... + rdlen1743 add.w 8(a4),d0 *... + fsiz1744 move.w d0,12(a4) *Set datrec1745 move.l #buffer+19,(a7) *Get number of sectors1746 bsr itom *... convert1747 sub.w 12(a4),d0 *... - datrec1748 ext.l d0 *... sign extended1749 divs.w 2(a4),d0 *... / clsiz1750 move.w d0,14(a4) *Set numcl1751 * 1752 .page 1753 * 1754 move.l #buffer+26,(a7) *Convert number of heads1755 bsr itom *...1756 move.w d0,20(a5) *Set dnsides1757 move.l #buffer+24,(a7) *Convert sectors per track1758 bsr itom *...1759 move.w d0,24(a5) *Set dspt1760 move.w 20(a5),d0 *Get dnsides1761 muls.w 24(a5),d0 * ... *dspt1762 move.w d0,22(a5) *Set dspc1763 move.l #buffer+28,(a7) *Convert number of hidden sects1764 bsr itom *...1765 move.w d0,26(a5) *Set dhidden1766 move.l #buffer+19,(a7) *Convert sectors on disk1767 bsr itom *...1768 ext.l d0 *... sign extended1769 divs.w 22(a5),d0 *... / dspc1770 move.w d0,18(a5) *Set dntracks1771 clr.w d7 *Counter = 01772 bra gbpblpt *Jump to end of loop1773 * 1774 gbpb6: move.l a5,a0 *Get buffer pointer1775 move.w d7,a1 *Loop count to a11776 add.l a1,a0 *... + bpb address1777 move.w d7,a1 *Loop count to a11778 add.l #buffer,a1 *... + buffer address1779 move.b 8(a1),28(a0) *Copy a s/n byte1780 addq.w #1,d7 *Update loop count1781 * 1782 gbpblpt: cmp.w #3,d7 *Moved 3 bytes ?1783 blt gbpb6 *Loop if not1784 * 1785 .page 1786 * 1787 move.l #cdev,a0 *Address of cdev table1788 move.w 8(a6),a1 *... plus drive number1789 add.l a1,a0 *... to a01790 move.l #wpstatus,a1 *Address of wpstatus table1791 move.w 8(a6),a2 *... plus drive number1792 add.l a2,a1 *... to a11793 move.b (a1),(a0) *Move wpstatus to cdev1592 1593 | fastcopy -- Copy disk sector quickly 1594 | -------- ------------------------ 1595 fastcopy: move.l 4(a7),a0 | Get source pointer 1596 move.l 8(a7),a1 | Get destination pointer 1597 move.w 0x3F,d0 | 512 bytes (63+1)|8 1598 1599 fastcpy1: move.b (a0)+,(a1)+ | Move 8 bytes 1600 move.b (a0)+,(a1)+ | ... 1601 move.b (a0)+,(a1)+ | ... 1602 move.b (a0)+,(a1)+ | ... 1603 move.b (a0)+,(a1)+ | ... 1604 move.b (a0)+,(a1)+ | ... 1605 move.b (a0)+,(a1)+ | ... 1606 move.b (a0)+,(a1)+ | ... 1607 dbra d0,fastcpy1 | Loop until all bytes are moved 1608 1609 rts | Return to caller 1610 1611 .page 1612 1613 | _hdvini -- Drive initialization 1614 | ------- -------------------- 1615 _hdvini: link a6,#-18 | Reserve space on stack 1616 movem.l d3-d7/a3-a5,-(a7) | Preserve registers 1617 move.l #300,maxactim | maxactim = 300 | 20ms 1618 clr.w d0 | Put zeros in ... 1619 move.w d0,nflops | ... nflops 1620 move.w d0,dskmode | ... dskmode 1621 move.w d0,-2(a6) | Start with drive A 1622 bra hdvilp | ... 1623 1624 hdvilp1: movea.l #dskmode,a0 | Get dskmode address in a0 1625 movea.w -2(a6),a1 | Drive number in a1 1626 adda.l a1,a0 | Point at dskmode for drive 1627 clr.b (a0) | Clear flag in dskmode 1628 clr.w -(a7) | Push arguments onto stack 1629 clr.w -(a7) | ... 1630 clr.w -(a7) | ... 1631 move.w -2(a6),-(a7) | Push drive number onto stack 1632 clr.l -(a7) | ... filler 1633 clr.l -(a7) | ... filler 1634 jsr flopini | Initialize drive 1635 adda.l #16,a7 | Cleanup stack 1636 move.w d0,-(a7) | Save error code on stack 1637 movea.w -2(a6),a0 | Get drive number 1638 adda.l a0,a0 | ... times 2 1639 adda.l #dskerrs,a0 | Add base of dskerrs 1640 move.w (a7)+,(a0) | Move error code off of stack 1641 bne hdvind | Jump if drive not present 1642 1643 addq.w #1,nflops | Update number of drives 1644 or.l #3,drvbits | Setup drive bits 1645 1646 hdvind: addq.w #1,-2(a6) | Increment drive number 1647 1648 hdvilp: cmp.w #2,-2(a6) | See if it's 2 yet 1649 blt hdvilp1 | Loop until it is 1650 1651 movem.l (a7)+,d3-d7/a3-a5 | Restore registers 1652 unlk a6 | Release temporary stack space 1653 rts | Return to caller 1654 1655 | drvmap -- get drive map 1656 | ------ ------------- 1657 drvmap: move.l drvbits,d0 | Get drive bits 1658 rts | Return to caller 1659 1660 .page 1661 1662 | getbpb -- get BIOS parameter block 1663 | ------ ------------------------ 1664 getbpb: link a6,#-12 | Reserve space for temporaries 1665 movem.l d5-d7/a4-a5,-(a7) | Save registers on stack 1666 cmp.w #2,8(a6) | Check drive number 1667 blt gbpb1 | Jump if OK 1668 1669 clr.l d0 | Set drive number to 0 1670 bra gbpber | Go flag error 1671 1672 gbpb1: move.w 8(a6),d0 | Get drive number 1673 asl.w #5,d0 | ... times 32 1674 ext.l d0 | ... extend sign 1675 move.l d0,a5 | Move to a5 1676 add.l #drvbpbs,a5 | Add base of drive bpb are 1677 move.l a5,a4 | Save in a4 1678 1679 gbpbrds: move.w #1,(a7) | floprd count = 1, 1680 clr.w -(a7) | ... side = 0, 1681 clr.w -(a7) | ... track = 0, 1682 move.w #1,-(a7) | ... sector = 1, 1683 move.w 8(a6),-(a7) | ... drive #, 1684 clr.l -(a7) | ... filler 1685 move.l #buffer,-(a7) | ... buffer address, 1686 jsr floprd | Go read the sector 1687 add.l #16,a7 | Cleanup stack 1688 move.l d0,-12(a6) | Save error code 1689 tst.l -12(a6) | ... and test it 1690 bge gbpb2 | Jump if OK 1691 1692 move.w 8(a6),(a7) | Put drive number on stack 1693 move.l -12(a6),d0 | Get error code 1694 move.w d0,-(a7) | ... and put it on the stack 1695 jsr criter | Go do critical error routine 1696 addq.l #2,a7 | Cleanup stack 1697 move.l d0,-12(a6) | Save error code 1698 1699 gbpb2: move.l -12(a6),d0 | Get error code 1700 cmp.l #RETRYIT,d0 | Magic number for retry ? 1701 beq gbpbrds | Re-read if so 1702 1703 tst.l -12(a6) | Test error code 1704 bge gbpb3 | Jump if OK 1705 1706 clr.l d0 | Set code in d0 1707 bra gbpber | Go set error code 1708 1709 .page 1710 1711 gbpb3: move.l #buffer+11,(a7) | Bytes per sector 1712 bsr itom | Convert 8086 to 68K format 1713 move.w d0,d7 | Save bytes per sector 1714 beq gbpb4 | Jump if zero 1715 1716 move.b buffer+13,d6 | Sectors per cluster 1717 ext.w d6 | ... sign extended 1718 and.w #0xFF,d6 | ... and trimmed 1719 bne gbpb5 | Jump if non-zero 1720 1721 gbpb4: clr.l d0 | Set error code 1722 bra gbpber | ... 1723 1724 gbpb5: move.w d7,(a4) | Set recsize 1725 move.w d6,2(a4) | Set clsiz 1726 move.l #buffer+22,(a7) | Convert sectors per fat 1727 bsr itom | ... 1728 move.w d0,8(a4) | Set fsiz 1729 move.w 8(a4),d0 | Get fsiz 1730 addq.w #1,d0 | ... plus 1 1731 move.w d0,10(a4) | Set fatrec 1732 move.w (a4),d0 | Get recsize 1733 muls.w 2(a4),d0 | ... times clsiz 1734 move.w d0,4(a4) | Set clsizb 1735 move.l #buffer+17,(a7) | Convert number of dir ents 1736 bsr itom | ... 1737 asl.w #5,d0 | ... times 32 1738 ext.l d0 | ... sign extended 1739 divs.w (a4),d0 | ... / recsize 1740 move.w d0,6(a4) | Set rdlen 1741 move.w 10(a4),d0 | Get fatrec 1742 add.w 6(a4),d0 | ... + rdlen 1743 add.w 8(a4),d0 | ... + fsiz 1744 move.w d0,12(a4) | Set datrec 1745 move.l #buffer+19,(a7) | Get number of sectors 1746 bsr itom | ... convert 1747 sub.w 12(a4),d0 | ... - datrec 1748 ext.l d0 | ... sign extended 1749 divs.w 2(a4),d0 | ... / clsiz 1750 move.w d0,14(a4) | Set numcl 1751 1752 .page 1753 1754 move.l #buffer+26,(a7) | Convert number of heads 1755 bsr itom | ... 1756 move.w d0,20(a5) | Set dnsides 1757 move.l #buffer+24,(a7) | Convert sectors per track 1758 bsr itom | ... 1759 move.w d0,24(a5) | Set dspt 1760 move.w 20(a5),d0 | Get dnsides 1761 muls.w 24(a5),d0 | ... | dspt 1762 move.w d0,22(a5) | Set dspc 1763 move.l #buffer+28,(a7) | Convert number of hidden sects 1764 bsr itom | ... 1765 move.w d0,26(a5) | Set dhidden 1766 move.l #buffer+19,(a7) | Convert sectors on disk 1767 bsr itom | ... 1768 ext.l d0 | ... sign extended 1769 divs.w 22(a5),d0 | ... / dspc 1770 move.w d0,18(a5) | Set dntracks 1771 clr.w d7 | Counter = 0 1772 bra gbpblpt | Jump to end of loop 1773 1774 gbpb6: move.l a5,a0 | Get buffer pointer 1775 move.w d7,a1 | Loop count to a1 1776 add.l a1,a0 | ... + bpb address 1777 move.w d7,a1 | Loop count to a1 1778 add.l #buffer,a1 | ... + buffer address 1779 move.b 8(a1),28(a0) | Copy a s/n byte 1780 addq.w #1,d7 | Update loop count 1781 1782 gbpblpt: cmp.w #3,d7 | Moved 3 bytes ? 1783 blt gbpb6 | Loop if not 1784 1785 .page 1786 1787 move.l #cdev,a0 | Address of cdev table 1788 move.w 8(a6),a1 | ... plus drive number 1789 add.l a1,a0 | ... to a0 1790 move.l #wpstatus,a1 | Address of wpstatus table 1791 move.w 8(a6),a2 | ... plus drive number 1792 add.l a2,a1 | ... to a1 1793 move.b (a1),(a0) | Move wpstatus to cdev 1794 1794 beq gbpb7 1795 * 1796 moveq.l #1,d0 *Set status = "Uncertain"1795 1796 moveq.l #1,d0 | Set status = "Uncertain" 1797 1797 bra gbpb8 1798 * 1799 gbpb7: clr.w d0 *Set status = "Unchanged"1800 * 1801 gbpb8: move.l #dskmode,a1 *Update dskmode table1802 move.w 8(a6),a2 *...1803 add.l a2,a1 *...1804 move.b d0,(a1) *...1805 move.l a5,d0 *Setup to return bpb pointer1806 * 1807 gbpber: tst.l (a7)+ *Pop garbage off top of stack1808 movem.l (a7)+,d6-d7/a4-a5 *Restore registers1798 1799 gbpb7: clr.w d0 | Set status = "Unchanged" 1800 1801 gbpb8: move.l #dskmode,a1 | Update dskmode table 1802 move.w 8(a6),a2 | ... 1803 add.l a2,a1 | ... 1804 move.b d0,(a1) | ... 1805 move.l a5,d0 | Setup to return bpb pointer 1806 1807 gbpber: tst.l (a7)+ | Pop garbage off top of stack 1808 movem.l (a7)+,d6-d7/a4-a5 | Restore registers 1809 1809 unlk a6 1810 1810 rts 1811 * 1812 .page 1813 * 1814 *mediach -- check for media change1815 *------- ----------------------1816 mediach: link a6,#0 *Create scratch on stack1817 movem.l d6-d7/a5,-(a7) *Save registers on stack1818 cmp.w #2,8(a6) *Check drive number1819 blt media1 *Jump if OK1820 * 1821 moveq.l #ERR15,d0 *Error -- "unknown device"1822 bra media2 *...1823 * 1824 media1: move.w 8(a6),d7 *Get drive number in d71825 movea.w d7,a5 *Point into dskmode table1826 add.l #dskmode,a5 *...1827 cmp.b #2,(a5) *Definitely changed ?1828 bne media3 *Jump if not1829 * 1830 moveq.l #2,d0 *Setup to return "Changed"1831 bra media2 *Done -- go return to caller1832 * 1833 media3: move.l #wplatch,a0 *Check wplatch for drive1834 tst.b 0(a0,d7) *...1835 beq media4 *Jump if not set1836 * 1837 move.b #1,(a5) *Set dskmode to "Uncertain"1838 * 1839 media4: move.l _hz_200,d0 *Get time in d01840 movea.w d7,a1 *Calculate acctim table address1841 add.l a1,a1 * ... = drive # *41842 add.l a1,a1 *...1843 add.l #acctim,a1 *... + acctim base address1844 move.l (a1),d1 *Get acctim for drive1845 sub.l d1,d0 *Subtract from current time1846 cmp.l maxactim,d0 *Timed out ?1847 bge media5 *Jump if so1848 * 1849 clr.w d0 *Setup to return "Unchanged"1811 1812 .page 1813 1814 | mediach -- check for media change 1815 | ------- ---------------------- 1816 mediach: link a6,#0 | Create scratch on stack 1817 movem.l d6-d7/a5,-(a7) | Save registers on stack 1818 cmp.w #2,8(a6) | Check drive number 1819 blt media1 | Jump if OK 1820 1821 moveq.l #ERR15,d0 | Error -- "unknown device" 1822 bra media2 | ... 1823 1824 media1: move.w 8(a6),d7 | Get drive number in d7 1825 movea.w d7,a5 | Point into dskmode table 1826 add.l #dskmode,a5 | ... 1827 cmp.b #2,(a5) | Definitely changed ? 1828 bne media3 | Jump if not 1829 1830 moveq.l #2,d0 | Setup to return "Changed" 1831 bra media2 | Done -- go return to caller 1832 1833 media3: move.l #wplatch,a0 | Check wplatch for drive 1834 tst.b 0(a0,d7) | ... 1835 beq media4 | Jump if not set 1836 1837 move.b #1,(a5) | Set dskmode to "Uncertain" 1838 1839 media4: move.l _hz_200,d0 | Get time in d0 1840 movea.w d7,a1 | Calculate acctim table address 1841 add.l a1,a1 | ... = drive # | 4 1842 add.l a1,a1 | ... 1843 add.l #acctim,a1 | ... + acctim base address 1844 move.l (a1),d1 | Get acctim for drive 1845 sub.l d1,d0 | Subtract from current time 1846 cmp.l maxactim,d0 | Timed out ? 1847 bge media5 | Jump if so 1848 1849 clr.w d0 | Setup to return "Unchanged" 1850 1850 bra media2 1851 * 1852 media5: move.b (a5),d0 *Return status from dskmode1851 1852 media5: move.b (a5),d0 | Return status from dskmode 1853 1853 ext.w d0 1854 * 1855 media2: tst.l (a7)+ *Pop extra stack word1856 movem.l (a7)+,d7/a5 *Restore registers1854 1855 media2: tst.l (a7)+ | Pop extra stack word 1856 movem.l (a7)+,d7/a5 | Restore registers 1857 1857 unlk a6 1858 rts *Return to caller1859 * 1860 .page 1861 * 1862 *rwabs -- read / write sector(s)1863 *----- ----------------------1864 rwabs: link a6,#-4 *Reserve stack for temps1865 movem.l d4-d7/a5,-(a7) *Save registers on stack1866 cmp.w #2,18(a6) *Drive number1858 rts | Return to caller 1859 1860 .page 1861 1862 | rwabs -- read / write sector(s) 1863 | ----- ---------------------- 1864 rwabs: link a6,#-4 | Reserve stack for temps 1865 movem.l d4-d7/a5,-(a7) | Save registers on stack 1866 cmp.w #2,18(a6) | Drive number 1867 1867 blt rwabs1 1868 * 1869 moveq.l #ERR15,d0 *ERROR -- "unknown device"1868 1869 moveq.l #ERR15,d0 | ERROR -- "unknown device" 1870 1870 bra rwabser 1871 * 1872 rwabs1: move.w 18(a6),d6 *Save drive number1873 cmp.w #2,8(a6) *Check rwflag1871 1872 rwabs1: move.w 18(a6),d6 | Save drive number 1873 cmp.w #2,8(a6) | Check rwflag 1874 1874 bge rwabs7 1875 * 1875 1876 1876 move.w d6,d0 1877 1877 asl.w #5,d0 … … 1880 1880 add.l #drvbpbs,a5 1881 1881 move.w d6,(a7) 1882 bsr mediach *Test for media change1883 move.w d0,d7 *Save status1884 cmp.w #2,d7 *Disk changed ?1885 bne rwabs2 *Jump if not1886 * 1887 moveq.l #ERR14,d0 *ERROR -- "media changed"1888 bra rwabser *...1889 * 1890 rwabs2: cmp.w #1,d7 *Disk possibly changed ?1882 bsr mediach | Test for media change 1883 move.w d0,d7 | Save status 1884 cmp.w #2,d7 | Disk changed ? 1885 bne rwabs2 | Jump if not 1886 1887 moveq.l #ERR14,d0 | ERROR -- "media changed" 1888 bra rwabser | ... 1889 1890 rwabs2: cmp.w #1,d7 | Disk possibly changed ? 1891 1891 bne rwabs7 1892 * 1893 rwabs3: move.w #1,(a7) *floprd count = 1,1894 clr.w -(a7) *... side = 0,1895 clr.w -(a7) *... track = 0,1896 move.w #1,-(a7) *... sector = 1,1897 move.w d6,-(a7) *... drive number,1898 clr.l -(a7) *... filler,1899 move.l #buffer,-(a7) *... buffer address,1900 jsr floprd *Read boot sector1901 add.l #16,a7 *Cleanup stack1902 move.l d0,-4(a6) *Save error number1903 tst.l -4(a6) *... and test it1904 bge rwabs11 *Jump if OK1905 * 1906 .page 1907 * 1892 1893 rwabs3: move.w #1,(a7) | floprd count = 1, 1894 clr.w -(a7) | ... side = 0, 1895 clr.w -(a7) | ... track = 0, 1896 move.w #1,-(a7) | ... sector = 1, 1897 move.w d6,-(a7) | ... drive number, 1898 clr.l -(a7) | ... filler, 1899 move.l #buffer,-(a7) | ... buffer address, 1900 jsr floprd | Read boot sector 1901 add.l #16,a7 | Cleanup stack 1902 move.l d0,-4(a6) | Save error number 1903 tst.l -4(a6) | ... and test it 1904 bge rwabs11 | Jump if OK 1905 1906 .page 1907 1908 1908 move.w d6,(a7) 1909 1909 move.l -4(a6),d0 1910 1910 move.w d0,-(a7) 1911 jsr criter *Call critical error code1912 addq.l #2,a7 *Cleanup stack1911 jsr criter | Call critical error code 1912 addq.l #2,a7 | Cleanup stack 1913 1913 move.l d0,-4(a6) 1914 * 1914 1915 1915 rwabs11: move.l -4(a6),d0 1916 1916 cmp.l #RETRYIT,d0 1917 beq rwabs3 *Read again1918 * 1919 tst.l -4(a6) *Test error number1920 bge rwabs4 *OK ?1921 * 1917 beq rwabs3 | Read again 1918 1919 tst.l -4(a6) | Test error number 1920 bge rwabs4 | OK ? 1921 1922 1922 move.l -4(a6),d0 1923 bra rwabser *ERROR1924 * 1925 rwabs4: clr.w d7 *Clear media change status1923 bra rwabser | ERROR 1924 1925 rwabs4: clr.w d7 | Clear media change status 1926 1926 bra rwabs10 1927 * 1928 rwabs6: move.l #buffer,a0 *Address of sector buffer to a01929 move.b 8(a0,d7),d0 *Serial number1927 1928 rwabs6: move.l #buffer,a0 | Address of sector buffer to a0 1929 move.b 8(a0,d7),d0 | Serial number 1930 1930 ext.w d0 1931 move.b 28(a5,d7),d1 *Compare to old one1931 move.b 28(a5,d7),d1 | Compare to old one 1932 1932 ext.w d1 1933 1933 cmp.w d1,d0 1934 beq rwabs5 *Jump if they're the same1935 * 1936 moveq.l #ERR14,d0 *ERROR -- "media changed"1934 beq rwabs5 | Jump if they're the same 1935 1936 moveq.l #ERR14,d0 | ERROR -- "media changed" 1937 1937 bra rwabser 1938 * 1939 rwabs5: addq.w #1,d7 *Next byte of serial number1940 * 1941 rwabs10: cmp.w #3,d7 *All 3 bytes checked ?1942 blt rwabs6 *Loop if not1943 * 1944 .page 1945 * 1946 move.w d6,a0 *Point at wplatch for drive1947 add.l #wplatch,a0 *...1948 move.w d6,a1 *Point at wpstatus for drive1949 add.l #wpstatus,a1 *...1950 move.b (a1),(a0) *Move wpstatus to wplatch1951 bne rwabs9 *Jump if set1952 * 1953 move.w d6,a0 *Set dskmode to "Unchanged"1954 add.l #dskmode,a0 *...1955 clr.b (a0) *...1956 * 1957 rwabs7: tst.w nflops *Test nflops1938 1939 rwabs5: addq.w #1,d7 | Next byte of serial number 1940 1941 rwabs10: cmp.w #3,d7 | All 3 bytes checked ? 1942 blt rwabs6 | Loop if not 1943 1944 .page 1945 1946 move.w d6,a0 | Point at wplatch for drive 1947 add.l #wplatch,a0 | ... 1948 move.w d6,a1 | Point at wpstatus for drive 1949 add.l #wpstatus,a1 | ... 1950 move.b (a1),(a0) | Move wpstatus to wplatch 1951 bne rwabs9 | Jump if set 1952 1953 move.w d6,a0 | Set dskmode to "Unchanged" 1954 add.l #dskmode,a0 | ... 1955 clr.b (a0) | ... 1956 1957 rwabs7: tst.w nflops | Test nflops 1958 1958 bne rwabs8 1959 * 1960 moveq.l #ERR02,d0 *ERROR -- "drive not ready"1959 1960 moveq.l #ERR02,d0 | ERROR -- "drive not ready" 1961 1961 bra rwabser 1962 * 1963 rwabs8: cmp.w #1,8(a6) *Check rwflag1962 1963 rwabs8: cmp.w #1,8(a6) | Check rwflag 1964 1964 ble rwabs9 1965 * 1966 subq.w #2,8(a6) *Adjust to 0|11967 * 1968 rwabs9: move.w 14(a6),(a7) *Setup count,1969 move.w d6,-(a7) *... drive,1970 move.w 16(a6),-(a7) *... recno,1971 move.l 10(a6),-(a7) *... buffer,1972 move.w 8(a6),-(a7) *... rwflag1973 bsr floprw *Call floprw1974 * 1975 add.l #10,a7 *Cleanup stack1976 * 1977 rwabser: tst.l (a7)+ *Pop stack scratch1978 movem.l (a7)+,d5-d7/a5 *Restore registers1979 unlk a6 *Release temporaries1980 rts *Return to caller1981 * 1982 .page 1983 * 1984 *floprw -- Floppy read / write driver1985 *------ --------------------------1986 floprw: link a6,#-6 *Reserve space for temps1987 movem.l d2-d7/a5,-(a7) *Save registers1988 move.w 16(a6),d0 *Drive number to d01989 asl.w #5,d0 * Shift ( *32 )1990 ext.l d0 *Sign extend it, too1991 move.l d0,a5 *Result in a51992 add.l #drvbpbs,a5 *Add base of BPB table1993 btst #0,13(a6) *Buffer address even ?1994 bne floprw01 *Jump if not1995 * 1996 clr.w d0 *Clear odd flag1997 bra floprw02 *Go save the flag1998 * 1999 floprw01: moveq.l #1,d0 *Set odd flag2000 * 2001 floprw02: move.w d0,-2(a6) *Save it2002 tst.w 22(a5) *dspc set ?2003 bne floprw20 *Jump if so2004 * 2005 moveq.l #9,d0 *Assume 92006 move.w d0,22(a5) *... and make it the default2007 move.w d0,24(a5) *... for dspt and dspc2008 * 1965 1966 subq.w #2,8(a6) | Adjust to 0|1 1967 1968 rwabs9: move.w 14(a6),(a7) | Setup count, 1969 move.w d6,-(a7) | ... drive, 1970 move.w 16(a6),-(a7) | ... recno, 1971 move.l 10(a6),-(a7) | ... buffer, 1972 move.w 8(a6),-(a7) | ... rwflag 1973 bsr floprw | Call floprw 1974 1975 add.l #10,a7 | Cleanup stack 1976 1977 rwabser: tst.l (a7)+ | Pop stack scratch 1978 movem.l (a7)+,d5-d7/a5 | Restore registers 1979 unlk a6 | Release temporaries 1980 rts | Return to caller 1981 1982 .page 1983 1984 | floprw -- Floppy read / write driver 1985 | ------ -------------------------- 1986 floprw: link a6,#-6 | Reserve space for temps 1987 movem.l d2-d7/a5,-(a7) | Save registers 1988 move.w 16(a6),d0 | Drive number to d0 1989 asl.w #5,d0 | Shift ( |32 ) 1990 ext.l d0 | Sign extend it, too 1991 move.l d0,a5 | Result in a5 1992 add.l #drvbpbs,a5 | Add base of BPB table 1993 btst #0,13(a6) | Buffer address even ? 1994 bne floprw01 | Jump if not 1995 1996 clr.w d0 | Clear odd flag 1997 bra floprw02 | Go save the flag 1998 1999 floprw01: moveq.l #1,d0 | Set odd flag 2000 2001 floprw02: move.w d0,-2(a6) | Save it 2002 tst.w 22(a5) | dspc set ? 2003 bne floprw20 | Jump if so 2004 2005 moveq.l #9,d0 | Assume 9 2006 move.w d0,22(a5) | ... and make it the default 2007 move.w d0,24(a5) | ... for dspt and dspc 2008 2009 2009 floprw20: bra floprw18 2010 * 2011 floprw03: tst.w -2(a6) *Is odd flag set ?2012 beq floprw04 *Jump if not2013 * 2014 move.l #buffer,d0 *Point to sector buffer2010 2011 floprw03: tst.w -2(a6) | Is odd flag set ? 2012 beq floprw04 | Jump if not 2013 2014 move.l #buffer,d0 | Point to sector buffer 2015 2015 bra floprw05 2016 * 2017 floprw04: move.l 10(a6),d0 *Get buffer address2018 * 2019 floprw05: move.l d0,-6(a6) *... and save2020 move.w 14(a6),d6 *Get recno (lsn)2021 ext.l d6 *Extend it to long2022 divs.w 22(a5),d6 *Divide by dspc for track #2023 move.w 14(a6),d4 *Get recno2024 ext.l d4 *Extend to long2025 divs.w 22(a5),d4 *Divide by dspc2026 swap d4 *Use remainder as sector number2027 cmp.w 24(a5),d4 *Compare with dspt2028 bge floprw06 *Greater than or equal ?2029 * 2030 clr.l d5 *Use side 02016 2017 floprw04: move.l 10(a6),d0 | Get buffer address 2018 2019 floprw05: move.l d0,-6(a6) | ... and save 2020 move.w 14(a6),d6 | Get recno (lsn) 2021 ext.l d6 | Extend it to long 2022 divs.w 22(a5),d6 | Divide by dspc for track # 2023 move.w 14(a6),d4 | Get recno 2024 ext.l d4 | Extend to long 2025 divs.w 22(a5),d4 | Divide by dspc 2026 swap d4 | Use remainder as sector number 2027 cmp.w 24(a5),d4 | Compare with dspt 2028 bge floprw06 | Greater than or equal ? 2029 2030 clr.l d5 | Use side 0 2031 2031 bra floprw07 2032 * 2033 floprw06: moveq.l #1,d5 *Use side 12034 sub.w 24(a5),d4 *Subtract dspt from sector #2035 * 2036 .page 2037 * 2038 floprw07: tst.w -2(a6) *Is odd flag set ?2039 beq floprw08 *Jump if not2040 * 2041 moveq.l #1,d3 *Set counter to 12032 2033 floprw06: moveq.l #1,d5 | Use side 1 2034 sub.w 24(a5),d4 | Subtract dspt from sector # 2035 2036 .page 2037 2038 floprw07: tst.w -2(a6) | Is odd flag set ? 2039 beq floprw08 | Jump if not 2040 2041 moveq.l #1,d3 | Set counter to 1 2042 2042 bra floprw10 2043 * 2044 floprw08: move.w 24(a5),d0 *Get dspt2045 sub.w d4,d0 *Subtract sector number2046 cmp.w 18(a6),d0 *Compare with number of sectors2047 bge floprw09 *Jump if greater than or eq to2048 * 2049 move.w 24(a5),d3 *Get dspt2050 sub.w d4,d3 *Subtract sector number2043 2044 floprw08: move.w 24(a5),d0 | Get dspt 2045 sub.w d4,d0 | Subtract sector number 2046 cmp.w 18(a6),d0 | Compare with number of sectors 2047 bge floprw09 | Jump if greater than or eq to 2048 2049 move.w 24(a5),d3 | Get dspt 2050 sub.w d4,d3 | Subtract sector number 2051 2051 bra floprw10 2052 * 2053 floprw09: move.w 18(a6),d3 *Count = number of sectors2054 * 2055 floprw10: addq.w #1,d4 *Adjust sector number (1 org)2056 * 2057 floprw11: tst.w 8(a6) *Test r/w flag2058 beq floprw14 *Jump if it's a read2059 * 2060 move.l -6(a6),d0 *Get buffer pointer2061 cmp.l 10(a6),d0 *See if it's = buffer addr2062 beq floprw12 *Jump if so2063 * 2064 move.l -6(a6),(a7) *Get source address2065 move.l 10(a6),-(a7) *Destination address2066 jsr fastcopy *Copy the sector2067 addq.l #4,a7 *Cleanup stack2068 * 2069 floprw12: move.w d3,(a7) *Number of sectors2070 move.w d5,-(a7) *Side number2071 move.w d6,-(a7) *Track number2072 move.w d4,-(a7) *Sector number2073 move.w 16(a6),-(a7) *Drive number2074 clr.l -(a7) *Filler2075 move.l -6(a6),-(a7) *Buffer address2076 jsr flopwr *Write sector2077 add.l #16,a7 *Cleaup stack2078 move.l d0,d7 *Save error code in d72079 tst.l d7 *Errors ?2080 bne floprw13 *Jump if so2081 * 2082 .page 2083 * 2084 tst.w fverify *Verify after write ?2085 beq floprw13 *Jump if not2086 * 2087 move.w d3,(a7) *Number of sectors2088 move.w d5,-(a7) *Side number2089 move.w d6,-(a7) *Track number2090 move.w d4,-(a7) *Sector number2091 move.w 16(a6),-(a7) *Drive number2092 clr.l -(a7) *Filler2093 move.l #buffer,-(a7) *Buffer address2094 jsr flopver *Verify sector(s)2095 add.l #16,a7 *Cleanup stack2096 move.l d0,d7 *Save error code in d72097 tst.l d7 *Errors ?2098 bne floprw13 *Jump if so2099 * 2100 move.l #buffer,(a7) *Address of sector buffer2101 bsr itom *Convert first word of buffer2102 tst.w d0 *Bad sectors ?2103 beq floprw13 *Jump if not2104 * 2105 moveq.l #ERR16,d7 *ERROR -- "Bad sectors"2106 * 2052 2053 floprw09: move.w 18(a6),d3 | Count = number of sectors 2054 2055 floprw10: addq.w #1,d4 | Adjust sector number (1 org) 2056 2057 floprw11: tst.w 8(a6) | Test r/w flag 2058 beq floprw14 | Jump if it's a read 2059 2060 move.l -6(a6),d0 | Get buffer pointer 2061 cmp.l 10(a6),d0 | See if it's = buffer addr 2062 beq floprw12 | Jump if so 2063 2064 move.l -6(a6),(a7) | Get source address 2065 move.l 10(a6),-(a7) | Destination address 2066 jsr fastcopy | Copy the sector 2067 addq.l #4,a7 | Cleanup stack 2068 2069 floprw12: move.w d3,(a7) | Number of sectors 2070 move.w d5,-(a7) | Side number 2071 move.w d6,-(a7) | Track number 2072 move.w d4,-(a7) | Sector number 2073 move.w 16(a6),-(a7) | Drive number 2074 clr.l -(a7) | Filler 2075 move.l -6(a6),-(a7) | Buffer address 2076 jsr flopwr | Write sector 2077 add.l #16,a7 | Cleaup stack 2078 move.l d0,d7 | Save error code in d7 2079 tst.l d7 | Errors ? 2080 bne floprw13 | Jump if so 2081 2082 .page 2083 2084 tst.w fverify | Verify after write ? 2085 beq floprw13 | Jump if not 2086 2087 move.w d3,(a7) | Number of sectors 2088 move.w d5,-(a7) | Side number 2089 move.w d6,-(a7) | Track number 2090 move.w d4,-(a7) | Sector number 2091 move.w 16(a6),-(a7) | Drive number 2092 clr.l -(a7) | Filler 2093 move.l #buffer,-(a7) | Buffer address 2094 jsr flopver | Verify sector(s) 2095 add.l #16,a7 | Cleanup stack 2096 move.l d0,d7 | Save error code in d7 2097 tst.l d7 | Errors ? 2098 bne floprw13 | Jump if so 2099 2100 move.l #buffer,(a7) | Address of sector buffer 2101 bsr itom | Convert first word of buffer 2102 tst.w d0 | Bad sectors ? 2103 beq floprw13 | Jump if not 2104 2105 moveq.l #ERR16,d7 | ERROR -- "Bad sectors" 2106 2107 2107 floprw13: bra floprw15 2108 * 2109 .page 2110 * 2111 floprw14: move.w d3,(a7) *Number of sectors2112 move.w d5,-(a7) *Side number2113 move.w d6,-(a7) *Track number2114 move.w d4,-(a7) *Sector number2115 move.w 16(a6),-(a7) *Drive number2116 clr.l -(a7) *Filler2117 move.l -6(a6),-(a7) *Sector buffer2118 jsr floprd *Read floppy sector(s)2119 add.l #16,a7 *Cleanup stack2120 move.l d0,d7 *Save error code in d72121 move.l -6(a6),d0 *User buffer address2122 cmp.l 10(a6),d0 *Is it the desired buffer ?2123 beq floprw15 *Jump if so2124 * 2125 move.l 10(a6),(a7) *Push source address2126 move.l -6(a6),-(a7) *Push destination address2127 jsr fastcopy *Copy the sector2128 addq.l #4,a7 *Cleanup stack2129 * 2130 floprw15: tst.l d7 *Error code set ?2131 bge floprw16 *Jump if not2132 * 2133 move.w 16(a6),(a7) *Push drive number2134 move.l d7,d0 *Error code2135 move.w d0,-(a7) *... onto stack2136 jsr criter *Call critical error handler2137 addq.l #2,a7 *Cleanup stack2138 move.l d0,d7 *Get error code2139 * 2140 floprw16: cmp.l #RETRYIT,d7 *Re-try ?2141 beq floprw11 *Jump if so2142 * 2143 tst.l d7 *Check error code2144 bge floprw17 *Jump if no error2145 * 2146 move.l d7,d0 *Error code is the result2108 2109 .page 2110 2111 floprw14: move.w d3,(a7) | Number of sectors 2112 move.w d5,-(a7) | Side number 2113 move.w d6,-(a7) | Track number 2114 move.w d4,-(a7) | Sector number 2115 move.w 16(a6),-(a7) | Drive number 2116 clr.l -(a7) | Filler 2117 move.l -6(a6),-(a7) | Sector buffer 2118 jsr floprd | Read floppy sector(s) 2119 add.l #16,a7 | Cleanup stack 2120 move.l d0,d7 | Save error code in d7 2121 move.l -6(a6),d0 | User buffer address 2122 cmp.l 10(a6),d0 | Is it the desired buffer ? 2123 beq floprw15 | Jump if so 2124 2125 move.l 10(a6),(a7) | Push source address 2126 move.l -6(a6),-(a7) | Push destination address 2127 jsr fastcopy | Copy the sector 2128 addq.l #4,a7 | Cleanup stack 2129 2130 floprw15: tst.l d7 | Error code set ? 2131 bge floprw16 | Jump if not 2132 2133 move.w 16(a6),(a7) | Push drive number 2134 move.l d7,d0 | Error code 2135 move.w d0,-(a7) | ... onto stack 2136 jsr criter | Call critical error handler 2137 addq.l #2,a7 | Cleanup stack 2138 move.l d0,d7 | Get error code 2139 2140 floprw16: cmp.l #RETRYIT,d7 | Re-try ? 2141 beq floprw11 | Jump if so 2142 2143 tst.l d7 | Check error code 2144 bge floprw17 | Jump if no error 2145 2146 move.l d7,d0 | Error code is the result 2147 2147 bra floprw19 2148 * 2149 .page 2150 * 2151 floprw17: move.w d3,d0 *Sector counter to d02152 ext.l d0 *Sign extend2153 moveq.l #9,d1 *Times 5122154 asl.l d1,d0 *...2155 add.l d0,10(a6) *Update buffer address2156 add.w d3,14(a6) *Update sector number2157 sub.w d3,18(a6) *Update sector count2158 * 2159 floprw18: tst.w 18(a6) *More sectors ?2160 bne floprw03 *Jump if so2161 * 2162 clr.l d0 *Set "no error" as result2163 * 2164 floprw19: tst.l (a7)+ *Test top of stack2165 movem.l (a7)+,d3-d7/a5 *Restore registers2166 unlk a6 *Release stack space2167 rts *Return to caller2168 * 2169 .page 2170 * 2171 *itom -- Convert 8086 integer format to 680000 integer format2172 *---- ----------------------------------------------------2173 itom: link a6,#-4 *Reserve stack for temps2174 move.l 8(a6),a0 *Address of the number to a02175 move.b 1(a0),d0 *Get high byte2176 ext.w d0 *Make it a word2177 and.w # $FF,d0 *Isolate bits 0..72178 asl.w #8,d0 *Shift in bits 8..152179 move.l 8(a6),a1 *Address of the number to a12180 move.b (a1),d1 *Get low byte2181 ext.w d1 *Extend to word2182 and.w # $FF,d1 *Isolate bits 0..72183 or.w d1,d0 *Combine with bits 8..152184 unlk a6 *Release stack space2185 rts *Return to caller2186 * 2187 .page 2188 * 2189 *flopini -- Initialize floppy drive2190 *------- -----------------------2191 flopini: lea dsb0,a1 *Point to dsb for drive A2192 tst.w 12(a7) *Drive A wanted ?2193 beq flopin01 *Jump if so2194 * 2195 lea dsb1,a1 *Drive B dsb address to a12196 * 2197 flopin01: move.w seekrate,2(a1) *Get seek rate2198 moveq.l #ERR01,d0 *Set default error number2199 clr.w 0(a1) *Set track number to 02200 bsr floplock *Setup floppy parameters2201 bsr select *Select drive and side2202 move.w # $FF00,0(a1)2203 bsr restore *Restore the drive2148 2149 .page 2150 2151 floprw17: move.w d3,d0 | Sector counter to d0 2152 ext.l d0 | Sign extend 2153 moveq.l #9,d1 | Times 512 2154 asl.l d1,d0 | ... 2155 add.l d0,10(a6) | Update buffer address 2156 add.w d3,14(a6) | Update sector number 2157 sub.w d3,18(a6) | Update sector count 2158 2159 floprw18: tst.w 18(a6) | More sectors ? 2160 bne floprw03 | Jump if so 2161 2162 clr.l d0 | Set "no error" as result 2163 2164 floprw19: tst.l (a7)+ | Test top of stack 2165 movem.l (a7)+,d3-d7/a5 | Restore registers 2166 unlk a6 | Release stack space 2167 rts | Return to caller 2168 2169 .page 2170 2171 | itom -- Convert 8086 integer format to 680000 integer format 2172 | ---- ---------------------------------------------------- 2173 itom: link a6,#-4 | Reserve stack for temps 2174 move.l 8(a6),a0 | Address of the number to a0 2175 move.b 1(a0),d0 | Get high byte 2176 ext.w d0 | Make it a word 2177 and.w #0xFF,d0 | Isolate bits 0..7 2178 asl.w #8,d0 | Shift in bits 8..15 2179 move.l 8(a6),a1 | Address of the number to a1 2180 move.b (a1),d1 | Get low byte 2181 ext.w d1 | Extend to word 2182 and.w #0xFF,d1 | Isolate bits 0..7 2183 or.w d1,d0 | Combine with bits 8..15 2184 unlk a6 | Release stack space 2185 rts | Return to caller 2186 2187 .page 2188 2189 | flopini -- Initialize floppy drive 2190 | ------- ----------------------- 2191 flopini: lea dsb0,a1 | Point to dsb for drive A 2192 tst.w 12(a7) | Drive A wanted ? 2193 beq flopin01 | Jump if so 2194 2195 lea dsb1,a1 | Drive B dsb address to a1 2196 2197 flopin01: move.w seekrate,2(a1) | Get seek rate 2198 moveq.l #ERR01,d0 | Set default error number 2199 clr.w 0(a1) | Set track number to 0 2200 bsr floplock | Setup floppy parameters 2201 bsr select | Select drive and side 2202 move.w #0xFF00,0(a1) 2203 bsr restore | Restore the drive 2204 2204 moveq.l #6,d7 2205 2205 bsr hseek1 2206 2206 bne flopin02 2207 * 2208 bsr restore *Restore the drive2209 beq flopok *Jump if no error2210 * 2211 flopin02: bra flopfail *Jump to error handler2212 * 2213 .page 2214 * 2215 *floprd -- Read floppy2216 *------ -----------2217 floprd: bsr change *Disk changed ?2218 moveq.l #ERR11,d0 *Set to "read error"2219 bsr floplock *Set parameters2220 * 2221 floprd01: bsr select *Select drive and side2222 bsr go2track *Position on track2223 bne floprd02 *Try again on error2224 * 2225 move.w #ERR01,deferr *Set default error2226 move.l edma(a5),a0 *Get final DMA address2227 move.l cdma(a5),a2 *Get first DMA address2228 move.l # $40000,d7 *Set timeout counter2229 move.b #FL_RM,DSKCMD(a6) *Start readng the disk2230 * 2231 floprd03: btst #0,DSKCMD(a6) *Disk busy yet ?2232 bne floprd05 *Jump if so2233 * 2234 subq.l #1,d7 *Decrement timeout counter2235 beq floprd04 *Jump if timed out2236 * 2237 bra floprd03 *Go try for busy again2238 * 2239 floprd05: move.l # $40000,d7 *Reset timeout counter2240 bra floprd09 *Go join main read loop2241 * 2242 floprd07: subq.l #1,d7 *Decrement timeout counter2243 beq floprd04 *Jump if timed out2244 * 2245 btst #0,DSKCMD(a6) *Done yet ?2246 beq floprd08 *Jump if so2247 * 2248 floprd09: btst #1,DSKCMD(a6) *DRQ set ?2249 beq floprd07 *Jump if not2250 * 2251 move.b DSKDAT(a6),(a2)+ *Read the byte into the buffer2252 cmp.l a0,a2 *Done reading ?2253 bne floprd07 *Jump if not2254 * 2255 .page 2256 * 2257 floprd08: move.b DSKCMD(a6),d0 *Read final status into d02258 and.b # $1C,d0 *Mask for error bits2259 beq flopok *Jump if no errors2260 * 2261 bsr errbits *Determine error code2262 * 2263 floprd02: cmp.w #1,retrycnt(a5) *Re-try ?2264 bne floprd06 *Jump if not2265 * 2266 bsr reseek *Home and repeat the seek2267 * 2268 floprd06: subq.w #1,retrycnt(a5) *Update re-try count2269 bpl floprd01 *Re-try if count still >02270 * 2271 bra flopfail *Failure2272 * 2273 floprd04: move.w #ERR02,curerr(a5) *Set error code "not ready"2274 bsr rs1772 *Reset the WD17722275 bra floprd02 *See if it can be retried2276 * 2277 .page 2278 * 2279 *errbits -- Develop error code for floppy I/O error2280 *------- ---------------------------------------2281 errbits: moveq.l #ERR13,d1 *Write protect ?2282 btst #6,d0 *...2283 bne errbits1 *Jump if so2284 * 2285 moveq.l #ERR08,d1 *Record not found ?2286 btst #4,d0 *...2287 bne errbits1 *Jump if so2288 * 2289 moveq.l #ERR04,d1 *CRC error ?2290 btst #3,d0 *...2291 bne errbits1 *Jump if so2292 * 2293 moveq.l #ERR12,d1 *Lost data ?2294 btst #2,d0 *...2295 bne errbits1 *Jump if so2296 * 2297 move.w deferr(a5),d1 *Use default error2298 * 2299 errbits1: move.w d1,curerr(a5) *... as curerr2300 rts *Return to caller2301 * 2302 .page 2303 * 2304 *flopwr -- Floppy write2305 *------ ------------2306 flopwr: bsr change *Check for disk change2307 moveq.l #ERR10,d0 *Set write error2308 bsr floplock *Set parameters2309 move.w csect(a5),d0 *Get sector number in d02310 subq.w #1,d0 *... -12311 or.w ctrack(a5),d0 *OR with track number2312 or.w cside(a5),d0 *OR with side number2313 bne flopwr01 *Jump if not boot sector2314 * 2315 moveq.l #2,d0 *Media change2316 bsr setdmode *Set to "unsure"2317 * 2318 flopwr01: bsr select *Select drive and side2319 bsr go2track *Seek2320 bne flopwr06 *Re-try on error2321 * 2322 flopwr02: move.w #ERR01,curerr(a5) *Set for default error2323 move.l cdma(a5),a2 *Get I/O address2324 move.l # $40000,d7 *Set timeout counter2325 move.w ctrack(a5),d0 *Get track number2326 cmpi.w #40,d0 *See if we need precomp2327 bcs flopwr10 *Jump if not2328 * 2329 move.b #FL_WS,DSKCMD(a6) *Write with precomp2330 bra flopwr08 *Go join main write loop2331 * 2332 flopwr10: move.b #FL_WS+FL_NC,DSKCMD(a6) *Write (no precomp)2333 * 2334 .page 2335 * 2336 flopwr08: btst #0,DSKCMD(a6) *Busy yet ?2337 bne flopwr09 *Jump if so2338 * 2339 subq.l #1,d7 *Decrement tiemout count2340 bne flopwr08 *Jump if not timed out2341 * 2342 flopwr13: bsr rs1772 *Reset WD17722343 bra flopwr05 *See if we can retry2344 * 2345 flopwr11: btst #0,DSKCMD(a6) *Done ?2346 beq flopwr04 *Jump if so2347 * 2348 flopwr09: btst #1,DSKCMD(a6) *DRQ set ?2349 bne flopwr12 *Jump if so2350 * 2351 subq.l #1,d7 *Decrement timeout counter2352 beq flopwr13 *Jump if timed out2353 * 2354 bra flopwr11 *Jump if not2355 * 2356 flopwr12: move.b (a2)+,DSKDAT(a6) *Write byte to floppy2357 bra flopwr11 *Go get the next one2358 * 2359 .page 2360 * 2361 flopwr04: move.b DSKCMD(a6),d0 *Get floppy status2362 bsr errbits *Set error code2363 btst #6,d0 *Write protect error ?2364 bne flopfail *Fail if so2365 * 2366 and.b # $5C,d0 *Mask error bits2367 bne flopwr05 *Jump if an error occurred2368 * 2369 addq.w #1,csect(a5) *Update sector number2370 add.l #512,cdma(a5) *Update DMA address2371 subq.w #1,ccount(a5) *Decrement sector count2372 beq flopok *Jump if zero -- done2373 * 2374 bsr select1 *Set sector and DMA pointer2375 bra flopwr02 *Write next sector2376 * 2377 flopwr05: cmp.w #1,retrycnt(a5) *Second re-try ?2378 bne flopwr07 *Jump if not2379 * 2380 flopwr06: bsr reseek *Restore and re-seek2381 * 2382 flopwr07: subq.w #1,retrycnt(a5) *Update re-try count2383 bpl flopwr01 *Re-try if still >02384 * 2385 bra flopfail *... else fail2386 * 2387 .page 2388 * 2389 *flopfmt -- Format a track on the floppy2390 *------- ----------------------------2391 flopfmt: cmp.l #FMAGIC,22(a7) *Is the magic right ?2392 bne flopfail *Fail immediately if not2393 * 2394 bsr change *Check for disk change2395 moveq.l #ERR01,d0 *Set default error number2396 bsr floplock *Set parameters2397 bsr select *Select drive and side2398 move.w 14(a7),spt(a5) *Set sectors per track,2399 move.w 20(a7),interlv(a5) *... interleave,2400 move.w 26(a7),virgin(a5) *... initial data,2401 moveq.l #2,d0 *Disk changed2402 bsr setdmode *...2403 bsr hseek *Seek2404 bne flopfail *Fail if seek error occurs2405 * 2406 move.w ctrack(a5),0(a1) *Current track to DSB2407 move.w #ERR01,curerr(a5) *Default to curerr2408 bsr fmtrack *Format the track2409 bne flopfail *Fail if error occurs2410 * 2411 move.w spt(a5),ccount(a5) *Use spt as ccount2412 move.w #1,csect(a5) *Start with sector 12413 bsr verify1 *Verify the sector2414 move.l cdma(a5),a2 *Get bad sector list2415 tst.w (a2) *Any bad ones ?2416 beq flopok *Jump if not2417 * 2418 move.w #ERR16,curerr(a5) *ERROR -- "bad sectors"2207 2208 bsr restore | Restore the drive 2209 beq flopok | Jump if no error 2210 2211 flopin02: bra flopfail | Jump to error handler 2212 2213 .page 2214 2215 | floprd -- Read floppy 2216 | ------ ----------- 2217 floprd: bsr change | Disk changed ? 2218 moveq.l #ERR11,d0 | Set to "read error" 2219 bsr floplock | Set parameters 2220 2221 floprd01: bsr select | Select drive and side 2222 bsr go2track | Position on track 2223 bne floprd02 | Try again on error 2224 2225 move.w #ERR01,deferr | Set default error 2226 move.l edma(a5),a0 | Get final DMA address 2227 move.l cdma(a5),a2 | Get first DMA address 2228 move.l #0x40000,d7 | Set timeout counter 2229 move.b #FL_RM,DSKCMD(a6) | Start readng the disk 2230 2231 floprd03: btst #0,DSKCMD(a6) | Disk busy yet ? 2232 bne floprd05 | Jump if so 2233 2234 subq.l #1,d7 | Decrement timeout counter 2235 beq floprd04 | Jump if timed out 2236 2237 bra floprd03 | Go try for busy again 2238 2239 floprd05: move.l #0x40000,d7 | Reset timeout counter 2240 bra floprd09 | Go join main read loop 2241 2242 floprd07: subq.l #1,d7 | Decrement timeout counter 2243 beq floprd04 | Jump if timed out 2244 2245 btst #0,DSKCMD(a6) | Done yet ? 2246 beq floprd08 | Jump if so 2247 2248 floprd09: btst #1,DSKCMD(a6) | DRQ set ? 2249 beq floprd07 | Jump if not 2250 2251 move.b DSKDAT(a6),(a2)+ | Read the byte into the buffer 2252 cmp.l a0,a2 | Done reading ? 2253 bne floprd07 | Jump if not 2254 2255 .page 2256 2257 floprd08: move.b DSKCMD(a6),d0 | Read final status into d0 2258 and.b #0x1C,d0 | Mask for error bits 2259 beq flopok | Jump if no errors 2260 2261 bsr errbits | Determine error code 2262 2263 floprd02: cmp.w #1,retrycnt(a5) | Re-try ? 2264 bne floprd06 | Jump if not 2265 2266 bsr reseek | Home and repeat the seek 2267 2268 floprd06: subq.w #1,retrycnt(a5) | Update re-try count 2269 bpl floprd01 | Re-try if count still >0 2270 2271 bra flopfail | Failure 2272 2273 floprd04: move.w #ERR02,curerr(a5) | Set error code "not ready" 2274 bsr rs1772 | Reset the WD1772 2275 bra floprd02 | See if it can be retried 2276 2277 .page 2278 2279 | errbits -- Develop error code for floppy I/O error 2280 | ------- --------------------------------------- 2281 errbits: moveq.l #ERR13,d1 | Write protect ? 2282 btst #6,d0 | ... 2283 bne errbits1 | Jump if so 2284 2285 moveq.l #ERR08,d1 | Record not found ? 2286 btst #4,d0 | ... 2287 bne errbits1 | Jump if so 2288 2289 moveq.l #ERR04,d1 | CRC error ? 2290 btst #3,d0 | ... 2291 bne errbits1 | Jump if so 2292 2293 moveq.l #ERR12,d1 | Lost data ? 2294 btst #2,d0 | ... 2295 bne errbits1 | Jump if so 2296 2297 move.w deferr(a5),d1 | Use default error 2298 2299 errbits1: move.w d1,curerr(a5) | ... as curerr 2300 rts | Return to caller 2301 2302 .page 2303 2304 | flopwr -- Floppy write 2305 | ------ ------------ 2306 flopwr: bsr change | Check for disk change 2307 moveq.l #ERR10,d0 | Set write error 2308 bsr floplock | Set parameters 2309 move.w csect(a5),d0 | Get sector number in d0 2310 subq.w #1,d0 | ... -1 2311 or.w ctrack(a5),d0 | OR with track number 2312 or.w cside(a5),d0 | OR with side number 2313 bne flopwr01 | Jump if not boot sector 2314 2315 moveq.l #2,d0 | Media change 2316 bsr setdmode | Set to "unsure" 2317 2318 flopwr01: bsr select | Select drive and side 2319 bsr go2track | Seek 2320 bne flopwr06 | Re-try on error 2321 2322 flopwr02: move.w #ERR01,curerr(a5) | Set for default error 2323 move.l cdma(a5),a2 | Get I/O address 2324 move.l #0x40000,d7 | Set timeout counter 2325 move.w ctrack(a5),d0 | Get track number 2326 cmpi.w #40,d0 | See if we need precomp 2327 bcs flopwr10 | Jump if not 2328 2329 move.b #FL_WS,DSKCMD(a6) | Write with precomp 2330 bra flopwr08 | Go join main write loop 2331 2332 flopwr10: move.b #FL_WS+FL_NC,DSKCMD(a6) | Write (no precomp) 2333 2334 .page 2335 2336 flopwr08: btst #0,DSKCMD(a6) | Busy yet ? 2337 bne flopwr09 | Jump if so 2338 2339 subq.l #1,d7 | Decrement tiemout count 2340 bne flopwr08 | Jump if not timed out 2341 2342 flopwr13: bsr rs1772 | Reset WD1772 2343 bra flopwr05 | See if we can retry 2344 2345 flopwr11: btst #0,DSKCMD(a6) | Done ? 2346 beq flopwr04 | Jump if so 2347 2348 flopwr09: btst #1,DSKCMD(a6) | DRQ set ? 2349 bne flopwr12 | Jump if so 2350 2351 subq.l #1,d7 | Decrement timeout counter 2352 beq flopwr13 | Jump if timed out 2353 2354 bra flopwr11 | Jump if not 2355 2356 flopwr12: move.b (a2)+,DSKDAT(a6) | Write byte to floppy 2357 bra flopwr11 | Go get the next one 2358 2359 .page 2360 2361 flopwr04: move.b DSKCMD(a6),d0 | Get floppy status 2362 bsr errbits | Set error code 2363 btst #6,d0 | Write protect error ? 2364 bne flopfail | Fail if so 2365 2366 and.b #0x5C,d0 | Mask error bits 2367 bne flopwr05 | Jump if an error occurred 2368 2369 addq.w #1,csect(a5) | Update sector number 2370 add.l #512,cdma(a5) | Update DMA address 2371 subq.w #1,ccount(a5) | Decrement sector count 2372 beq flopok | Jump if zero -- done 2373 2374 bsr select1 | Set sector and DMA pointer 2375 bra flopwr02 | Write next sector 2376 2377 flopwr05: cmp.w #1,retrycnt(a5) | Second re-try ? 2378 bne flopwr07 | Jump if not 2379 2380 flopwr06: bsr reseek | Restore and re-seek 2381 2382 flopwr07: subq.w #1,retrycnt(a5) | Update re-try count 2383 bpl flopwr01 | Re-try if still >0 2384 2385 bra flopfail | ... else fail 2386 2387 .page 2388 2389 | flopfmt -- Format a track on the floppy 2390 | ------- ---------------------------- 2391 flopfmt: cmp.l #FMAGIC,22(a7) | Is the magic right ? 2392 bne flopfail | Fail immediately if not 2393 2394 bsr change | Check for disk change 2395 moveq.l #ERR01,d0 | Set default error number 2396 bsr floplock | Set parameters 2397 bsr select | Select drive and side 2398 move.w 14(a7),spt(a5) | Set sectors per track, 2399 move.w 20(a7),interlv(a5) | ... interleave, 2400 move.w 26(a7),virgin(a5) | ... initial data, 2401 moveq.l #2,d0 | Disk changed 2402 bsr setdmode | ... 2403 bsr hseek | Seek 2404 bne flopfail | Fail if seek error occurs 2405 2406 move.w ctrack(a5),0(a1) | Current track to DSB 2407 move.w #ERR01,curerr(a5) | Default to curerr 2408 bsr fmtrack | Format the track 2409 bne flopfail | Fail if error occurs 2410 2411 move.w spt(a5),ccount(a5) | Use spt as ccount 2412 move.w #1,csect(a5) | Start with sector 1 2413 bsr verify1 | Verify the sector 2414 move.l cdma(a5),a2 | Get bad sector list 2415 tst.w (a2) | Any bad ones ? 2416 beq flopok | Jump if not 2417 2418 move.w #ERR16,curerr(a5) | ERROR -- "bad sectors" 2419 2419 bra flopfail 2420 * 2421 .page 2422 * 2423 *fmtrack -- Do the dirty work of formatting a track2424 *------- ---------------------------------------2425 fmtrack: move.w #ERR10,deferr(a5) *Set default error number2426 move.w #1,d3 *Start with sector 12427 move.l cdma(a5),a2 *Get track buffer address2428 move.w #60-1,d1 *Set count = 602429 move.b # $4E,d0 * Write $4E as initial gap2430 bsr wmult *...2431 * 2432 fmtrak01: move.w d3,d4 *Save sector number in d42433 * 2434 fmtrak02: move.w #12-1,d1 *Set count = 122435 clr.b d0 * Write $00 as sync2436 bsr wmult *...2437 move.w #3-1,d1 *Set count = 32438 move.b # $F5,d0 * Write $F5's2439 bsr wmult *...2440 move.b # $FE,(a2)+ * Write $FE (address mark)2441 move.b ctrack+1,(a2)+ *Write track #2442 move.b cside+1,(a2)+ *Write side #2443 move.b d4,(a2)+ *Write sector #2444 move.b #2,(a2)+ *Write sector size code2445 move.b # $F7,(a2)+ *Write checksum code2446 move.w #22-1,d1 *Set count = 222447 move.b # $4E,d0 *Write gap2448 bsr wmult *...2449 move.w #12-1,d1 *Set count = 122450 clr.b d0 * Write $00 as sync2451 bsr wmult *...2452 move.w #3-1,d1 *Set count = 32453 move.b # $F5,d0 * Write $F5's2454 bsr wmult *...2455 move.b # $FB,(a2)+ *Write DAM2456 move.w #256-1,d1 *Set count = 256 words2457 * 2458 .page 2459 * 2460 fmtrak03: move.b virgin(a5),(a2)+ *Write virgin data in buffer2461 move.b virgin+1(a5),(a2)+ *...2462 dbf d1,fmtrak03 *...2463 * 2464 move.b # $F7,(a2)+ *Write CRC code2465 move.w #40-1,d1 *Set count = 402466 move.b # $4E,d0 *Write gap2467 bsr wmult *...2468 add.w interlv(a5),d4 *Add interleave to sector #2469 cmp.w spt(a5),d4 *Check against spt2470 ble fmtrak02 *Jump if not >2471 * 2472 addq.w #1,d3 *Starting sector +12420 2421 .page 2422 2423 | fmtrack -- Do the dirty work of formatting a track 2424 | ------- --------------------------------------- 2425 fmtrack: move.w #ERR10,deferr(a5) | Set default error number 2426 move.w #1,d3 | Start with sector 1 2427 move.l cdma(a5),a2 | Get track buffer address 2428 move.w #60-1,d1 | Set count = 60 2429 move.b #0x4E,d0 | Write 0x4E as initial gap 2430 bsr wmult | ... 2431 2432 fmtrak01: move.w d3,d4 | Save sector number in d4 2433 2434 fmtrak02: move.w #12-1,d1 | Set count = 12 2435 clr.b d0 | Write 0x00 as sync 2436 bsr wmult | ... 2437 move.w #3-1,d1 | Set count = 3 2438 move.b #0xF5,d0 | Write 0xF5's 2439 bsr wmult | ... 2440 move.b #0xFE,(a2)+ | Write 0xFE (address mark) 2441 move.b ctrack+1,(a2)+ | Write track # 2442 move.b cside+1,(a2)+ | Write side # 2443 move.b d4,(a2)+ | Write sector # 2444 move.b #2,(a2)+ | Write sector size code 2445 move.b #0xF7,(a2)+ | Write checksum code 2446 move.w #22-1,d1 | Set count = 22 2447 move.b #0x4E,d0 | Write gap 2448 bsr wmult | ... 2449 move.w #12-1,d1 | Set count = 12 2450 clr.b d0 | Write 0x00 as sync 2451 bsr wmult | ... 2452 move.w #3-1,d1 | Set count = 3 2453 move.b #0xF5,d0 | Write 0xF5's 2454 bsr wmult | ... 2455 move.b #0xFB,(a2)+ | Write DAM 2456 move.w #256-1,d1 | Set count = 256 words 2457 2458 .page 2459 2460 fmtrak03: move.b virgin(a5),(a2)+ | Write virgin data in buffer 2461 move.b virgin+1(a5),(a2)+ | ... 2462 dbf d1,fmtrak03 | ... 2463 2464 move.b #0xF7,(a2)+ | Write CRC code 2465 move.w #40-1,d1 | Set count = 40 2466 move.b #0x4E,d0 | Write gap 2467 bsr wmult | ... 2468 add.w interlv(a5),d4 | Add interleave to sector # 2469 cmp.w spt(a5),d4 | Check against spt 2470 ble fmtrak02 | Jump if not > 2471 2472 addq.w #1,d3 | Starting sector +1 2473 2473 cmp.w interlv(a5),d3 2474 2474 ble fmtrak01 2475 * 2476 move.w #1401-1,d1 *Set count = 14012477 move.b # $4E,d0 *Write final gap2478 bsr wmult *...2479 move.l cdma(a5),a2 *Get buffer address2480 move.l # $40000,d7 *Set timeout count2481 move.w ctrack(a5),d0 *Get track number2482 cmpi.w #40,d0 *Do we need precomp ?2483 bcs fmtrak08 *Jump if not2484 * 2485 move.b #FL_WT,DSKCMD(a6) *Start format with precomp2486 bra fmtrak07 *Go join main format loop2487 * 2488 fmtrak08: move.b #FL_WT+FL_NC,DSKCMD(a6) *Start format without precomp2489 * 2490 .page 2491 * 2492 fmtrak07: btst #0,DSKCMD(a6) *Busy yet ?2493 bne fmtrak09 *Jump if so2494 * 2495 fmtrak04: subq.l #1,d7 *Decrement timeout counter2496 bne fmtrak07 *Jump if not timed out2497 * 2498 fmtrak05: bsr rs1772 *Reset WD17722499 moveq.l #1,d7 *Set error flag2500 rts *Return to caller2501 * 2502 fmtrak11: btst #0,DSKCMD(a6) *Done ?2503 beq fmtrak06 *Jump if so2504 * 2505 fmtrak09: btst #1,DSKCMD(a6) *DRQ set ?2506 bne fmtrak10 *Jump if so2507 * 2508 subq.l #1,d7 *Decrement timeout coutner2509 beq fmtrak05 *Jump if timed out2510 * 2511 bra fmtrak11 *Go check again2512 * 2513 fmtrak10: move.b (a2)+,DSKDAT(a6) *Write a byte of format2514 bra fmtrak11 *Go wait for DRQ2515 * 2516 fmtrak06: move.b DSKCMD(a6),d0 *Get final status2517 bsr errbits *Set possible error code2518 andi.b # $44,d0 *Check error bits2519 rts *Return to caller with status2520 * 2521 *wmult -- write multiple bytes into the track buffer2522 *----- ------------------------------------------2523 wmult: move.b d0,(a2)+ *Move a byte into the buffer2524 dbf d1,wmult *Loop until we're done2525 * 2526 rts *Return to caller2527 * 2528 .page 2529 * 2530 *flopver -- verify sector(s) on a floppy2531 *------- ----------------------------2532 flopver: bsr change *Check for disk change2533 moveq.l #ERR11,d0 *Set default to "read error"2534 bsr floplock *Set parameters2535 bsr select *Select drive and side2536 bsr go2track *Seek2537 bne flopfail *Jump if seek error2538 * 2539 bsr verify1 *Verify the data2540 bra flopok *Done2541 * 2542 *verify1 -- Verify the data for a sector2543 *------- ----------------------------2544 verify1: move.w #ERR11,deferr(a5) *Set default = "read error"2545 move.l cdma(a5),a2 *Pointer for bad sector list2546 add.l #512,cdma(a5) *Update by length of a sector2547 * 2548 verify01: move.w #2,retrycnt(a5) *Set retrycnt for 2 attempts2549 move.w csect(a5),d7 *Get sector nubmer2550 move.b d7,DSKSEC(a6) *Send to WD17722551 * 2552 verify02: moveq.l #0,d6 *Clear bad compare flag2553 move.l cdma(a5),a0 *Get compare address2554 move.l # $40000,d7 *Set timeout counter2555 move.b #FL_RS,DSKCMD(a6) *Start the read2556 * 2557 verify08: btst #0,DSKCMD(a6) *Busy yet ?2558 bne verify09 *Jump if so2559 * 2560 subq.l #1,d7 *Decrement timeout counter2561 beq verify13 *Jump if timed out2562 * 2563 bra verify08 *Wait for busy some more2564 * 2565 verify09: move.l # $40000,d7 *Reset timeout counter2566 bra verify11 *Go join main compare loop2567 * 2568 verify10: subq.l #1,d7 *Decrement timeout counter2569 beq verify13 *Jump if timed out2570 * 2571 btst #0,DSKCMD(a6) *Done yet ?2572 beq verify12 *Jump if so2573 * 2574 .page 2575 * 2576 verify11: btst #1,DSKCMD(a6) *DRQ set ?2577 beq verify10 *Jump if not2578 * 2579 move.b DSKDAT(a6),d0 *Read data2580 bra verify10 *Continue reading2581 * 2582 verify12: move.b DSKCMD(a6),d0 *Get final status2583 bsr errbits *Determine error code2584 and.b # $1C,d0 *Mask RNF, CRC, LOST2585 bne verify06 *Jump to re-try if any set2586 * 2587 verify05: addq.w #1,csect(a5) *Update sector number2588 subq.w #1,ccount(a5) *Update sector count2589 bne verify01 *Jump if more to do2590 * 2591 sub.l #512,cdma(a5) *Reset DMA pointer2592 clr.w (a2) *Set NIL in bad sector list2593 rts *Return to caller2594 * 2595 verify06: cmp.w #1,retrycnt(a5) *Is it the 2nd attempt ?2596 bne verify07 *Jump if not2597 * 2598 bsr reseek *Restore and re-seek2599 * 2600 verify07: subq.w #1,retrycnt(a5) *Decrement retry count2601 bpl verify02 *Re-try if still positive2602 * 2603 move.w csect(a5),(a2)+ *Add to bad sector list2604 bra verify05 *Go do next sector2605 * 2606 verify13: move.w #ERR02,curerr(a5) *Set timeout error code2607 bsr rs1772 *Reset WD17722608 bra verify06 *See if we can retry it2609 * 2610 .page 2611 * 2612 *flopvbl -- Floppy VBL timer interrupt handling2613 *------- -----------------------------------2614 flopvbl: movem.l d0-d1/a0-a1/a5-a6,-(a7) *Save registers2615 sub.l a5,a5 *Clear a5 for use as RAM base2616 lea FLOPPY,a6 *Base of floppy regs2617 st motoron(a5) *Set motoron flag2618 move.l frclock(a5),d0 *Get interrupt count2619 move.b d0,d1 *...2620 and.b #7,d1 *... MOD 82621 bne flopvb02 *Jump if not 8th int2622 * 2623 move.w sr,-(a7) *Save interrupt level2624 ori.w #IPL7,sr *Mask off interrupts2625 clr.w deslflag(a5) *Clear deselect flag2626 move.b mc1iorec+cfr1,d0 *Get port status2627 ori.b #1,d0 *Set drive select bit2628 move.b d0,MC1ACIA+ACIA_CFR *Send drive select to port2629 move.b d0,mc1iorec+cfr1 *Store updated port status2630 move.w (a7)+,sr *Restore interrupt level2631 lea wpstatus(a5),a0 *Point at wpstatus for drive2632 lea dsb0(a5),a1 *Point at dsb02633 move.b DSKCMD(a6),d0 *Read WD1772 status2634 btst #6,d0 *Test write protect bit2635 sne (a0) *... and save2636 * 2637 .page 2638 * 2639 flopvb02: move.w wpstatus(a5),d0 *Get wpstatus of drive A2640 or.w d0,wplatch(a5) *OR into wplatch2641 tst.w deslflag(a5) *Floppies already deselected ?2642 bne flopvb03 *Jump if so2643 * 2644 move.b DSKCMD(a6),d0 *Read WD1772 status2645 btst #7,d0 *Motor-on bit set ?2646 bne flopvb04 *Don't de-select if it is2647 * 2648 move.w sr,-(a7) *Save sr2649 ori.w #IPL7,sr *Disable interrupts2650 move.b mc1iorec+cfr1,d0 *Get cfr1 image2651 bclr #0,d0 *Clear d0 (drive select)2652 move.b d0,mc1iorec+cfr1 *Save new value2653 move.b d0,MC1ACIA+ACIA_CFR *Send to hardware2654 move.w (a7)+,sr *Restore sr (enable ints)2655 move.w #1,deslflag(a5) *Set the deselect flag2656 * 2657 flopvb03: clr.w motoron(a5) *Clear motoron flag2658 * 2659 flopvb04: movem.l (a7)+,d0-d1/a0-a1/a5-a6 *Restore registers2660 rts *Return to caller2661 * 2662 .page 2663 * 2664 *floplock -- Setup floppy parameters2665 *-------- -----------------------2666 floplock: movem.l d3-d7/a3-a6,flpregs *Save registers2667 move.w sr,flpsrsv *Save sr2668 ori.w #IPL7,sr *Disable ints2669 sub.l a5,a5 *Clear a52670 lea FLOPPY,a6 *Base of floppy registers2671 st motoron(a5) *Set motoron flag2672 move.w d0,deferr(a5) *Set default error code2673 move.w d0,curerr(a5) *... current error code2674 move.w #1,flock(a5) *Disable flopvbl routine2675 move.l 8(a7),cdma(a5) *Set cdma2676 move.w 16(a7),cdev(a5) *... cdev2677 move.w 18(a7),csect(a5) *... csect2678 move.w 20(a7),ctrack(a5) *... ctrack2679 move.w 22(a7),cside(a5) *... cside2680 move.w 24(a7),ccount(a5) *... ccount2681 move.w #2,retrycnt(a5) *... retrycnt2682 lea dsb0(a5),a1 *Address of dsb02683 tst.w cdev(a5) *Drive A ?2684 beq floplk01 *Jump if so2685 * 2686 lea dsb1(a5),a1 *Drive B, use dsb12687 * 2688 floplk01: moveq.l #0,d7 *Clear out d72689 move.w ccount(a5),d7 *Get ccount2690 lsl.w #8,d7 * ... *sector length (512)2691 lsl.w #1,d7 *...2692 move.l cdma(a5),a0 *Get DMA start address2693 add.l d7,a0 *Add length of sectors2694 move.l a0,edma(a5) *Set edma (end DMA address)2695 tst.w 0(a1) *Check current track2696 bpl floplk03 *Jump if >= 02697 * 2698 bsr select *Select the drive2699 clr.w 0(a1) *Set current track to 02700 bsr restore *Restore drive to track 02701 beq floplk03 *Jump if OK2702 * 2703 moveq.l #10,d7 *Seek out to track 102704 bsr hseek1 *...2705 bne floplk02 *Jump if an error occurred2706 * 2707 bsr restore *Try the restore again2708 beq floplk03 *Jump if OK2709 * 2710 floplk02: move.w # $FF00,0(a1) *Recalibrate error2711 * 2712 floplk03: rts *Return to caller2713 * 2714 .page 2715 * 2716 *flopfail -- Floppy I/O failure exit2717 *-------- -----------------------2718 flopfail: moveq.l #1,d0 *Set media change to "unsure"2719 bsr setdmode *...2720 move.w curerr(a5),d0 *Get curerr2721 ext.l d0 *...2722 bra flopok1 *Go set end status2723 * 2724 *flopok -- Floppy I/O success exit2725 *------ -----------------------2726 flopok: clr.l d0 *Set error code = 0 (no error)2727 * 2728 flopok1: move.l d0,-(a7) *Push code onto stack2729 move.w 0(a1),d7 *Get track number2730 move.b d7,DSKDAT(a6) *Send to WD17722731 move.w #FL_SK,d6 *Seek command to d62732 bsr flopcmds *Send command2733 move.w cdev(a5),d0 *Get drive number2734 lsl.w #2,d0 *Use as index2735 lea acctim(a5),a0 *... into acctim2736 move.l _hz_200(a5),0(a0,d0) *Set last access time2475 2476 move.w #1401-1,d1 | Set count = 1401 2477 move.b #0x4E,d0 | Write final gap 2478 bsr wmult | ... 2479 move.l cdma(a5),a2 | Get buffer address 2480 move.l #0x40000,d7 | Set timeout count 2481 move.w ctrack(a5),d0 | Get track number 2482 cmpi.w #40,d0 | Do we need precomp ? 2483 bcs fmtrak08 | Jump if not 2484 2485 move.b #FL_WT,DSKCMD(a6) | Start format with precomp 2486 bra fmtrak07 | Go join main format loop 2487 2488 fmtrak08: move.b #FL_WT+FL_NC,DSKCMD(a6) | Start format without precomp 2489 2490 .page 2491 2492 fmtrak07: btst #0,DSKCMD(a6) | Busy yet ? 2493 bne fmtrak09 | Jump if so 2494 2495 fmtrak04: subq.l #1,d7 | Decrement timeout counter 2496 bne fmtrak07 | Jump if not timed out 2497 2498 fmtrak05: bsr rs1772 | Reset WD1772 2499 moveq.l #1,d7 | Set error flag 2500 rts | Return to caller 2501 2502 fmtrak11: btst #0,DSKCMD(a6) | Done ? 2503 beq fmtrak06 | Jump if so 2504 2505 fmtrak09: btst #1,DSKCMD(a6) | DRQ set ? 2506 bne fmtrak10 | Jump if so 2507 2508 subq.l #1,d7 | Decrement timeout coutner 2509 beq fmtrak05 | Jump if timed out 2510 2511 bra fmtrak11 | Go check again 2512 2513 fmtrak10: move.b (a2)+,DSKDAT(a6) | Write a byte of format 2514 bra fmtrak11 | Go wait for DRQ 2515 2516 fmtrak06: move.b DSKCMD(a6),d0 | Get final status 2517 bsr errbits | Set possible error code 2518 andi.b #0x44,d0 | Check error bits 2519 rts | Return to caller with status 2520 2521 | wmult -- write multiple bytes into the track buffer 2522 | ----- ------------------------------------------ 2523 wmult: move.b d0,(a2)+ | Move a byte into the buffer 2524 dbf d1,wmult | Loop until we're done 2525 2526 rts | Return to caller 2527 2528 .page 2529 2530 | flopver -- verify sector(s) on a floppy 2531 | ------- ---------------------------- 2532 flopver: bsr change | Check for disk change 2533 moveq.l #ERR11,d0 | Set default to "read error" 2534 bsr floplock | Set parameters 2535 bsr select | Select drive and side 2536 bsr go2track | Seek 2537 bne flopfail | Jump if seek error 2538 2539 bsr verify1 | Verify the data 2540 bra flopok | Done 2541 2542 | verify1 -- Verify the data for a sector 2543 | ------- ---------------------------- 2544 verify1: move.w #ERR11,deferr(a5) | Set default = "read error" 2545 move.l cdma(a5),a2 | Pointer for bad sector list 2546 add.l #512,cdma(a5) | Update by length of a sector 2547 2548 verify01: move.w #2,retrycnt(a5) | Set retrycnt for 2 attempts 2549 move.w csect(a5),d7 | Get sector nubmer 2550 move.b d7,DSKSEC(a6) | Send to WD1772 2551 2552 verify02: moveq.l #0,d6 | Clear bad compare flag 2553 move.l cdma(a5),a0 | Get compare address 2554 move.l #0x40000,d7 | Set timeout counter 2555 move.b #FL_RS,DSKCMD(a6) | Start the read 2556 2557 verify08: btst #0,DSKCMD(a6) | Busy yet ? 2558 bne verify09 | Jump if so 2559 2560 subq.l #1,d7 | Decrement timeout counter 2561 beq verify13 | Jump if timed out 2562 2563 bra verify08 | Wait for busy some more 2564 2565 verify09: move.l #0x40000,d7 | Reset timeout counter 2566 bra verify11 | Go join main compare loop 2567 2568 verify10: subq.l #1,d7 | Decrement timeout counter 2569 beq verify13 | Jump if timed out 2570 2571 btst #0,DSKCMD(a6) | Done yet ? 2572 beq verify12 | Jump if so 2573 2574 .page 2575 2576 verify11: btst #1,DSKCMD(a6) | DRQ set ? 2577 beq verify10 | Jump if not 2578 2579 move.b DSKDAT(a6),d0 | Read data 2580 bra verify10 | Continue reading 2581 2582 verify12: move.b DSKCMD(a6),d0 | Get final status 2583 bsr errbits | Determine error code 2584 and.b #0x1C,d0 | Mask RNF, CRC, LOST 2585 bne verify06 | Jump to re-try if any set 2586 2587 verify05: addq.w #1,csect(a5) | Update sector number 2588 subq.w #1,ccount(a5) | Update sector count 2589 bne verify01 | Jump if more to do 2590 2591 sub.l #512,cdma(a5) | Reset DMA pointer 2592 clr.w (a2) | Set NIL in bad sector list 2593 rts | Return to caller 2594 2595 verify06: cmp.w #1,retrycnt(a5) | Is it the 2nd attempt ? 2596 bne verify07 | Jump if not 2597 2598 bsr reseek | Restore and re-seek 2599 2600 verify07: subq.w #1,retrycnt(a5) | Decrement retry count 2601 bpl verify02 | Re-try if still positive 2602 2603 move.w csect(a5),(a2)+ | Add to bad sector list 2604 bra verify05 | Go do next sector 2605 2606 verify13: move.w #ERR02,curerr(a5) | Set timeout error code 2607 bsr rs1772 | Reset WD1772 2608 bra verify06 | See if we can retry it 2609 2610 .page 2611 2612 | flopvbl -- Floppy VBL timer interrupt handling 2613 | ------- ----------------------------------- 2614 flopvbl: movem.l d0-d1/a0-a1/a5-a6,-(a7) | Save registers 2615 sub.l a5,a5 | Clear a5 for use as RAM base 2616 lea FLOPPY,a6 | Base of floppy regs 2617 st motoron(a5) | Set motoron flag 2618 move.l frclock(a5),d0 | Get interrupt count 2619 move.b d0,d1 | ... 2620 and.b #7,d1 | ... MOD 8 2621 bne flopvb02 | Jump if not 8th int 2622 2623 move.w sr,-(a7) | Save interrupt level 2624 ori.w #IPL7,sr | Mask off interrupts 2625 clr.w deslflag(a5) | Clear deselect flag 2626 move.b mc1iorec+cfr1,d0 | Get port status 2627 ori.b #1,d0 | Set drive select bit 2628 move.b d0,MC1ACIA+ACIA_CFR | Send drive select to port 2629 move.b d0,mc1iorec+cfr1 | Store updated port status 2630 move.w (a7)+,sr | Restore interrupt level 2631 lea wpstatus(a5),a0 | Point at wpstatus for drive 2632 lea dsb0(a5),a1 | Point at dsb0 2633 move.b DSKCMD(a6),d0 | Read WD1772 status 2634 btst #6,d0 | Test write protect bit 2635 sne (a0) | ... and save 2636 2637 .page 2638 2639 flopvb02: move.w wpstatus(a5),d0 | Get wpstatus of drive A 2640 or.w d0,wplatch(a5) | OR into wplatch 2641 tst.w deslflag(a5) | Floppies already deselected ? 2642 bne flopvb03 | Jump if so 2643 2644 move.b DSKCMD(a6),d0 | Read WD1772 status 2645 btst #7,d0 | Motor-on bit set ? 2646 bne flopvb04 | Don't de-select if it is 2647 2648 move.w sr,-(a7) | Save sr 2649 ori.w #IPL7,sr | Disable interrupts 2650 move.b mc1iorec+cfr1,d0 | Get cfr1 image 2651 bclr #0,d0 | Clear d0 (drive select) 2652 move.b d0,mc1iorec+cfr1 | Save new value 2653 move.b d0,MC1ACIA+ACIA_CFR | Send to hardware 2654 move.w (a7)+,sr | Restore sr (enable ints) 2655 move.w #1,deslflag(a5) | Set the deselect flag 2656 2657 flopvb03: clr.w motoron(a5) | Clear motoron flag 2658 2659 flopvb04: movem.l (a7)+,d0-d1/a0-a1/a5-a6 | Restore registers 2660 rts | Return to caller 2661 2662 .page 2663 2664 | floplock -- Setup floppy parameters 2665 | -------- ----------------------- 2666 floplock: movem.l d3-d7/a3-a6,flpregs | Save registers 2667 move.w sr,flpsrsv | Save sr 2668 ori.w #IPL7,sr | Disable ints 2669 sub.l a5,a5 | Clear a5 2670 lea FLOPPY,a6 | Base of floppy registers 2671 st motoron(a5) | Set motoron flag 2672 move.w d0,deferr(a5) | Set default error code 2673 move.w d0,curerr(a5) | ... current error code 2674 move.w #1,flock(a5) | Disable flopvbl routine 2675 move.l 8(a7),cdma(a5) | Set cdma 2676 move.w 16(a7),cdev(a5) | ... cdev 2677 move.w 18(a7),csect(a5) | ... csect 2678 move.w 20(a7),ctrack(a5) | ... ctrack 2679 move.w 22(a7),cside(a5) | ... cside 2680 move.w 24(a7),ccount(a5) | ... ccount 2681 move.w #2,retrycnt(a5) | ... retrycnt 2682 lea dsb0(a5),a1 | Address of dsb0 2683 tst.w cdev(a5) | Drive A ? 2684 beq floplk01 | Jump if so 2685 2686 lea dsb1(a5),a1 | Drive B, use dsb1 2687 2688 floplk01: moveq.l #0,d7 | Clear out d7 2689 move.w ccount(a5),d7 | Get ccount 2690 lsl.w #8,d7 | ... | sector length (512) 2691 lsl.w #1,d7 | ... 2692 move.l cdma(a5),a0 | Get DMA start address 2693 add.l d7,a0 | Add length of sectors 2694 move.l a0,edma(a5) | Set edma (end DMA address) 2695 tst.w 0(a1) | Check current track 2696 bpl floplk03 | Jump if >= 0 2697 2698 bsr select | Select the drive 2699 clr.w 0(a1) | Set current track to 0 2700 bsr restore | Restore drive to track 0 2701 beq floplk03 | Jump if OK 2702 2703 moveq.l #10,d7 | Seek out to track 10 2704 bsr hseek1 | ... 2705 bne floplk02 | Jump if an error occurred 2706 2707 bsr restore | Try the restore again 2708 beq floplk03 | Jump if OK 2709 2710 floplk02: move.w #0xFF00,0(a1) | Recalibrate error 2711 2712 floplk03: rts | Return to caller 2713 2714 .page 2715 2716 | flopfail -- Floppy I/O failure exit 2717 | -------- ----------------------- 2718 flopfail: moveq.l #1,d0 | Set media change to "unsure" 2719 bsr setdmode | ... 2720 move.w curerr(a5),d0 | Get curerr 2721 ext.l d0 | ... 2722 bra flopok1 | Go set end status 2723 2724 | flopok -- Floppy I/O success exit 2725 | ------ ----------------------- 2726 flopok: clr.l d0 | Set error code = 0 (no error) 2727 2728 flopok1: move.l d0,-(a7) | Push code onto stack 2729 move.w 0(a1),d7 | Get track number 2730 move.b d7,DSKDAT(a6) | Send to WD1772 2731 move.w #FL_SK,d6 | Seek command to d6 2732 bsr flopcmds | Send command 2733 move.w cdev(a5),d0 | Get drive number 2734 lsl.w #2,d0 | Use as index 2735 lea acctim(a5),a0 | ... into acctim 2736 move.l _hz_200(a5),0(a0,d0) | Set last access time 2737 2737 cmp.w #1,nflops(a5) 2738 2738 bne flopok01 2739 * 2740 move.l _hz_200(a5),4(a0) *Time for other drive2741 * 2742 flopok01: move.w flpsrsv,sr *Restore sr (enable ints)2743 move.l (a7)+,d0 *Restore error number to d02744 movem.l flpregs,d3-d7/a3-a6 *Restore registers2745 clr.w flock *Release flopvbl routine2746 rts *Return to caller2747 * 2748 .page 2749 * 2750 *hseek -- seek to track in ctrack2751 *----- -----------------------2752 hseek: move.w ctrack,d7 *Get ctrack2753 * 2754 *hseek1 -- seek to track in d72755 *------ -------------------2756 hseek1: move.w #ERR10,curerr *Set curerr = "seek error"2757 move.b d7,DSKDAT(a6) *Send track number to WD17722758 move.w #FL_SK,d6 *Seek command2759 bra flopcmds *Go send command to WD17722760 * 2761 *reseek -- Restore, then re-seek2762 *------ ---------------------2763 reseek: move.w #ERR10,curerr *Set curerr = "seek error"2764 bsr restore *Restore2765 bne reseek01 *Jump if error occurred2766 * 2767 clr.w 0(a1) *Clear current track to 02768 move.b #0,DSKTRK(a6) *Send track to WD17722769 move.b #5,DSKDAT(a6) *Setup to seek to track 52770 move.w #FL_SK,d6 *Seek command2771 bsr flopcmds *Seek2772 bne reseek01 *Jump if error2773 * 2774 move.w #5,0(a1) *Update current track = 52775 * 2776 *go2track -- seek with verify2777 *-------- ----------------2778 go2track: move.w #ERR10,curerr(a5) *Set curerr = "seek error"2779 move.w ctrack(a5),d7 *Put track # in d72780 move.b d7,DSKDAT(a6) *Send track to WD17722781 moveq.l #FL_SV,d6 *Seek/verify command2782 bsr flopcmds *Send command to floppy2783 bne reseek01 *Jump if error occurred2784 * 2785 move.w ctrack(a5),0(a1) *Update track number in dsb2786 and.b # $18,d7 *Test for RNF, CRC, LOST2787 * 2788 reseek01: rts *Return to caller2789 * 2790 .page 2791 * 2792 *restore -- Restore to track 02793 *------- ------------------2794 restore: clr.w d6 *Restore command2795 bsr flopcmds *Send to WD17722796 bne restor01 *Jump if an error occurred2797 * 2798 btst #2,d7 *Check track 0 bit2799 eori #0004,sr *Invert Z flag in 680000 sr2800 bne restor01 *Jump if not track 02801 * 2802 clr.w 0(a1) *Set track = 0 in dsb2803 * 2804 restor01: rts *Return to caller2805 * 2806 *flopcmds -- Send command to WD1772 floppy controller2807 *-------- ----------------------------------------2808 flopcmds: move.w 2(a1),d0 *Get seek rate from dsb2809 and.b # $3,d0 *...2810 or.b d0,d6 *OR into command word2811 move.l # $40000,d7 *Set timeout counter2812 btst #7,DSKCMD(a6) *Motor on ?2813 bne flopcm01 *Jump if so2814 * 2815 move.l # $60000,d7 *Set longer timeout count2816 * 2817 flopcm01: move.b d6,DSKCMD(a6) *Write command from d62818 * 2819 move.l # $1000,d0 *Set initial busy timeout in d02820 * 2821 flopcm04: btst #0,DSKCMD(a6) *Controller busy yet ?2822 bne flopcm02 *Jump if so2823 * 2824 subq.l #1,d0 *Decrement timeout counter2825 beq flopcm03 *Jump if timed out2826 * 2827 bra flopcm04 *Wait for busy some more2828 * 2829 flopcm02: subq.l #1,d7 *Decrement timeout counter2830 beq flopcm03 *Jump if timed out2831 * 2832 btst #0,DSKCMD(a6) *WD1772 done ?2833 bne flopcm02 *Jump if not2834 * 2835 clr.l d7 *Clear out upper bits of d72836 move.b DSKCMD(a6),d7 *Read status into LS byte of d72837 clr.l d6 *Clear error flag in d62838 rts *Return to caller2839 * 2840 flopcm03: bsr rs1772 *Reset WD1772 (end transfer)2841 moveq.l #1,d6 *Set error flag in d62842 rts *Return to caller2843 * 2844 .page 2845 * 2846 *rs1772 -- Reset WD1772 floppy controller2847 *------ ------------------------------2848 rs1772: move.b #FL_FR,DSKCMD(a6) *Send reset to WD17722849 move.w #15,d7 *Set delay count2850 * 2851 rs1772a: dbf d7,rs1772a *Delay a while2852 rts *Return to caller2853 * 2854 *select -- Select drive and side2855 *------ ----------------------2856 select: move.w sr,-(a7) *Save sr on stack2857 ori.w #IPL7,sr *Disable interrupts2858 clr.w deslflag(a5) *Clear deselect flag2859 move.b mc1iorec+cfr1,d0 *Get current MC1 cfr1 image2860 ori.b #1,d0 *Select drive (we only have 1)2861 move.b d0,mc1iorec+cfr1 *Store updated image2862 move.b d0,MC1ACIA+ACIA_CFR *Send it to the MC1 ACIA2863 move.w cside(a5),d0 *Get side number (LS bit)2864 and.w #1,d0 *Mask off garbage bits2865 andi.b # $FE,mc2iorec+cfr1 *Mask off D0 in MC2 cfr1 image2866 or.b mc2iorec+cfr1,d0 *OR side with mc2iorec cfr12867 move.b d0,mc2iorec+cfr1 *Store updated cfr1 image2868 move.b d0,MC2ACIA+ACIA_CFR *Send it to the MC2 ACIA2869 move.w (a7)+,sr *Restore interrupts2870 move.w 0(a1),d7 *Get track from dsb2871 move.b d7,DSKTRK(a6) *Send it to the WD17722872 clr.b tmpdma(a5) *Clear bits 31..24 of tmpdma2873 * 2874 select1: move.w csect(a5),d7 *Get sector number2875 move.b d7,DSKSEC(a6) *Send it to the WD17722876 move.l cdma(a5),a0 *Setup transfer address in a02877 rts *Return to caller2878 * 2879 .page 2880 * 2881 *change -- Check for disk change status2882 *------ ----------------------------2883 change: cmp.w #1,nflops *Check # of floppies2739 2740 move.l _hz_200(a5),4(a0) | Time for other drive 2741 2742 flopok01: move.w flpsrsv,sr | Restore sr (enable ints) 2743 move.l (a7)+,d0 | Restore error number to d0 2744 movem.l flpregs,d3-d7/a3-a6 | Restore registers 2745 clr.w flock | Release flopvbl routine 2746 rts | Return to caller 2747 2748 .page 2749 2750 | hseek -- seek to track in ctrack 2751 | ----- ----------------------- 2752 hseek: move.w ctrack,d7 | Get ctrack 2753 2754 | hseek1 -- seek to track in d7 2755 | ------ ------------------- 2756 hseek1: move.w #ERR10,curerr | Set curerr = "seek error" 2757 move.b d7,DSKDAT(a6) | Send track number to WD1772 2758 move.w #FL_SK,d6 | Seek command 2759 bra flopcmds | Go send command to WD1772 2760 2761 | reseek -- Restore, then re-seek 2762 | ------ --------------------- 2763 reseek: move.w #ERR10,curerr | Set curerr = "seek error" 2764 bsr restore | Restore 2765 bne reseek01 | Jump if error occurred 2766 2767 clr.w 0(a1) | Clear current track to 0 2768 move.b #0,DSKTRK(a6) | Send track to WD1772 2769 move.b #5,DSKDAT(a6) | Setup to seek to track 5 2770 move.w #FL_SK,d6 | Seek command 2771 bsr flopcmds | Seek 2772 bne reseek01 | Jump if error 2773 2774 move.w #5,0(a1) | Update current track = 5 2775 2776 | go2track -- seek with verify 2777 | -------- ---------------- 2778 go2track: move.w #ERR10,curerr(a5) | Set curerr = "seek error" 2779 move.w ctrack(a5),d7 | Put track # in d7 2780 move.b d7,DSKDAT(a6) | Send track to WD1772 2781 moveq.l #FL_SV,d6 | Seek/verify command 2782 bsr flopcmds | Send command to floppy 2783 bne reseek01 | Jump if error occurred 2784 2785 move.w ctrack(a5),0(a1) | Update track number in dsb 2786 and.b #0x18,d7 | Test for RNF, CRC, LOST 2787 2788 reseek01: rts | Return to caller 2789 2790 .page 2791 2792 | restore -- Restore to track 0 2793 | ------- ------------------ 2794 restore: clr.w d6 | Restore command 2795 bsr flopcmds | Send to WD1772 2796 bne restor01 | Jump if an error occurred 2797 2798 btst #2,d7 | Check track 0 bit 2799 eori #0004,sr | Invert Z flag in 680000 sr 2800 bne restor01 | Jump if not track 0 2801 2802 clr.w 0(a1) | Set track = 0 in dsb 2803 2804 restor01: rts | Return to caller 2805 2806 | flopcmds -- Send command to WD1772 floppy controller 2807 | -------- ---------------------------------------- 2808 flopcmds: move.w 2(a1),d0 | Get seek rate from dsb 2809 and.b #0x3,d0 | ... 2810 or.b d0,d6 | OR into command word 2811 move.l #0x40000,d7 | Set timeout counter 2812 btst #7,DSKCMD(a6) | Motor on ? 2813 bne flopcm01 | Jump if so 2814 2815 move.l #0x60000,d7 | Set longer timeout count 2816 2817 flopcm01: move.b d6,DSKCMD(a6) | Write command from d6 2818 2819 move.l #0x1000,d0 | Set initial busy timeout in d0 2820 2821 flopcm04: btst #0,DSKCMD(a6) | Controller busy yet ? 2822 bne flopcm02 | Jump if so 2823 2824 subq.l #1,d0 | Decrement timeout counter 2825 beq flopcm03 | Jump if timed out 2826 2827 bra flopcm04 | Wait for busy some more 2828 2829 flopcm02: subq.l #1,d7 | Decrement timeout counter 2830 beq flopcm03 | Jump if timed out 2831 2832 btst #0,DSKCMD(a6) | WD1772 done ? 2833 bne flopcm02 | Jump if not 2834 2835 clr.l d7 | Clear out upper bits of d7 2836 move.b DSKCMD(a6),d7 | Read status into LS byte of d7 2837 clr.l d6 | Clear error flag in d6 2838 rts | Return to caller 2839 2840 flopcm03: bsr rs1772 | Reset WD1772 (end transfer) 2841 moveq.l #1,d6 | Set error flag in d6 2842 rts | Return to caller 2843 2844 .page 2845 2846 | rs1772 -- Reset WD1772 floppy controller 2847 | ------ ------------------------------ 2848 rs1772: move.b #FL_FR,DSKCMD(a6) | Send reset to WD1772 2849 move.w #15,d7 | Set delay count 2850 2851 rs1772a: dbf d7,rs1772a | Delay a while 2852 rts | Return to caller 2853 2854 | select -- Select drive and side 2855 | ------ ---------------------- 2856 select: move.w sr,-(a7) | Save sr on stack 2857 ori.w #IPL7,sr | Disable interrupts 2858 clr.w deslflag(a5) | Clear deselect flag 2859 move.b mc1iorec+cfr1,d0 | Get current MC1 cfr1 image 2860 ori.b #1,d0 | Select drive (we only have 1) 2861 move.b d0,mc1iorec+cfr1 | Store updated image 2862 move.b d0,MC1ACIA+ACIA_CFR | Send it to the MC1 ACIA 2863 move.w cside(a5),d0 | Get side number (LS bit) 2864 and.w #1,d0 | Mask off garbage bits 2865 andi.b #0xFE,mc2iorec+cfr1 | Mask off D0 in MC2 cfr1 image 2866 or.b mc2iorec+cfr1,d0 | OR side with mc2iorec cfr1 2867 move.b d0,mc2iorec+cfr1 | Store updated cfr1 image 2868 move.b d0,MC2ACIA+ACIA_CFR | Send it to the MC2 ACIA 2869 move.w (a7)+,sr | Restore interrupts 2870 move.w 0(a1),d7 | Get track from dsb 2871 move.b d7,DSKTRK(a6) | Send it to the WD1772 2872 clr.b tmpdma(a5) | Clear bits 31..24 of tmpdma 2873 2874 select1: move.w csect(a5),d7 | Get sector number 2875 move.b d7,DSKSEC(a6) | Send it to the WD1772 2876 move.l cdma(a5),a0 | Setup transfer address in a0 2877 rts | Return to caller 2878 2879 .page 2880 2881 | change -- Check for disk change status 2882 | ------ ---------------------------- 2883 change: cmp.w #1,nflops | Check # of floppies 2884 2884 bne change02 2885 * 2886 move.w 16(a7),d0 *Drive number to d02885 2886 move.w 16(a7),d0 | Drive number to d0 2887 2887 cmp.w disknum,d0 2888 beq change01 *Jump if =2889 * 2890 move.w d0,-(a7) *Stack drive number2891 move.w #ERR17,-(a7) *Stack error code2892 bsr criter *Do critical error routine2893 addq.w #4,a7 *Cleanup stack2894 move.w # $FFFF,wplatch *Status for drives = "unsure"2895 move.w 16(a7),disknum *Save disk number2896 * 2897 change01: clr.w 16(a7) *Clear disk number2898 * 2899 change02: rts *Return to caller2900 * 2901 *setdmode -- Set drive change mode2902 *-------- ---------------------2903 setdmode: lea dskmode,a0 *Point at disk mode table2904 move.b d0,-(a7) *Save mode on stack2905 move.w cdev(a5),d0 *Get drive number2906 move.b (a7)+,0(a0,d0) *Set drive mode / cleanup stack2907 rts *Return to caller2908 * 2909 .page 2910 * 2911 *bootload -- Load boot sector2912 *-------- ----------------2913 bootload: link a6,#0 *Link stack frames2914 movem.l d6-d7,-(a7) *Save registers2915 jsr _hdvini *Init drive2916 tst.w nflops *See if any connected2917 beq bootld01 *Jump if drive there2918 * 2919 moveq.l #1,d0 *"couldn't load"2888 beq change01 | Jump if = 2889 2890 move.w d0,-(a7) | Stack drive number 2891 move.w #ERR17,-(a7) | Stack error code 2892 bsr criter | Do critical error routine 2893 addq.w #4,a7 | Cleanup stack 2894 move.w #0xFFFF,wplatch | Status for drives = "unsure" 2895 move.w 16(a7),disknum | Save disk number 2896 2897 change01: clr.w 16(a7) | Clear disk number 2898 2899 change02: rts | Return to caller 2900 2901 | setdmode -- Set drive change mode 2902 | -------- --------------------- 2903 setdmode: lea dskmode,a0 | Point at disk mode table 2904 move.b d0,-(a7) | Save mode on stack 2905 move.w cdev(a5),d0 | Get drive number 2906 move.b (a7)+,0(a0,d0) | Set drive mode / cleanup stack 2907 rts | Return to caller 2908 2909 .page 2910 2911 | bootload -- Load boot sector 2912 | -------- ---------------- 2913 bootload: link a6,#0 | Link stack frames 2914 movem.l d6-d7,-(a7) | Save registers 2915 jsr _hdvini | Init drive 2916 tst.w nflops | See if any connected 2917 beq bootld01 | Jump if drive there 2918 2919 moveq.l #1,d0 | "couldn't load" 2920 2920 bra bootld02 2921 * 2922 bootld01: moveq.l #2,d0 *"no drive connected"2923 * 2924 bootld02: move.w d0,d7 *Save possible error in d72921 2922 bootld01: moveq.l #2,d0 | "no drive connected" 2923 2924 bootld02: move.w d0,d7 | Save possible error in d7 2925 2925 tst.w nflops 2926 2926 beq bootld04 2927 * 2927 2928 2928 cmp.w #2,bootdev 2929 2929 bge bootld04 2930 * 2931 move.w #1,(a7) *Sector count = 1,2932 clr.w -(a7) *... side = 0,2933 clr.w -(a7) *... track = 0,2934 move.w #1,-(a7) *... sector = 1,2935 move.w bootdev,-(a7) *... drive = bootdev,2936 clr.l -(a7) *... filler,2937 move.l #buffer,-(a7) *... buffer address2938 jsr floprd *Read the sector2939 add.l #16,a7 *Cleanup stack2940 tst.l d0 *Error ?2941 bne bootld03 *Jump if not2942 * 2930 2931 move.w #1,(a7) | Sector count = 1, 2932 clr.w -(a7) | ... side = 0, 2933 clr.w -(a7) | ... track = 0, 2934 move.w #1,-(a7) | ... sector = 1, 2935 move.w bootdev,-(a7) | ... drive = bootdev, 2936 clr.l -(a7) | ... filler, 2937 move.l #buffer,-(a7) | ... buffer address 2938 jsr floprd | Read the sector 2939 add.l #16,a7 | Cleanup stack 2940 tst.l d0 | Error ? 2941 bne bootld03 | Jump if not 2942 2943 2943 clr.w d7 2944 2944 bra bootld04 2945 * 2945 2946 2946 bootld03: tst.b wpstatus 2947 2947 bne bootld04 2948 * 2949 moveq.l #3,d0 *"unreadable"2948 2949 moveq.l #3,d0 | "unreadable" 2950 2950 bra bootld07 2951 * 2951 2952 2952 bootld04: tst.w d7 2953 2953 beq bootld05 2954 * 2955 move.w d7,d0 *Get old error code2954 2955 move.w d7,d0 | Get old error code 2956 2956 bra bootld07 2957 * 2958 .page 2959 * 2960 bootld05: move.w #256,(a7) *Set count for 256 words2961 move.l #buffer,-(a7) *Point at buffer2962 bsr chksum *Calculate checksum2963 addq.l #4,a7 *Cleanup stack2964 cmp.w # $1234,d0 *Boot sector checksum ?2965 bne bootld06 *Jump if not2966 * 2967 clr.w d0 *Set flag for OK2968 move.w bootdev,booted *Save last boot device2957 2958 .page 2959 2960 bootld05: move.w #256,(a7) | Set count for 256 words 2961 move.l #buffer,-(a7) | Point at buffer 2962 bsr chksum | Calculate checksum 2963 addq.l #4,a7 | Cleanup stack 2964 cmp.w #0x1234,d0 | Boot sector checksum ? 2965 bne bootld06 | Jump if not 2966 2967 clr.w d0 | Set flag for OK 2968 move.w bootdev,booted | Save last boot device 2969 2969 bra bootld07 2970 * 2971 bootld06: moveq.l #4,d0 *"not valid boot sector"2972 * 2970 2971 bootld06: moveq.l #4,d0 | "not valid boot sector" 2972 2973 2973 bootld07: tst.l (a7)+ 2974 movem.l (a7)+,d7 *Restore registers2974 movem.l (a7)+,d7 | Restore registers 2975 2975 unlk a6 2976 rts *Return to caller2977 * 2978 .page 2979 * 2980 *chksum -- caluculate checksum2981 *------ -------------------2976 rts | Return to caller 2977 2978 .page 2979 2980 | chksum -- caluculate checksum 2981 | ------ ------------------- 2982 2982 chksum: link a6,#0 2983 movem.l d6-d7,-(a7) *Preserve registers2984 clr.w d7 *Clear sum2985 bra chksum02 *Jump into loop2986 * 2987 chksum01: move.l 8(a6),a0 *Get buffer address2988 move.w (a0),d0 *Get word2989 add.w d0,d7 *Add to checksum in d72990 addq.l #2,8(a6) *Update buffer address2991 * 2992 chksum02: move.w 12(a6),d0 *Get word count2993 subq.w #1,12(a6) *Decrement it2994 tst.w d0 *Done ?2995 bne chksum01 *Loop if not2996 * 2997 move.w d7,d0 *Put result in d02983 movem.l d6-d7,-(a7) | Preserve registers 2984 clr.w d7 | Clear sum 2985 bra chksum02 | Jump into loop 2986 2987 chksum01: move.l 8(a6),a0 | Get buffer address 2988 move.w (a0),d0 | Get word 2989 add.w d0,d7 | Add to checksum in d7 2990 addq.l #2,8(a6) | Update buffer address 2991 2992 chksum02: move.w 12(a6),d0 | Get word count 2993 subq.w #1,12(a6) | Decrement it 2994 tst.w d0 | Done ? 2995 bne chksum01 | Loop if not 2996 2997 move.w d7,d0 | Put result in d0 2998 2998 tst.l (a7)+ 2999 movem.l (a7)+,d7 *Restore registers2999 movem.l (a7)+,d7 | Restore registers 3000 3000 unlk a6 3001 rts *Return to caller3002 * 3003 .page 3004 * 3005 *mult32 -- 32 bit signed multiply3006 *------ ----------------------3001 rts | Return to caller 3002 3003 .page 3004 3005 | mult32 -- 32 bit signed multiply 3006 | ------ ---------------------- 3007 3007 mult32: link a6,#-4 3008 3008 clr.w d2 3009 3009 tst.l 8(a6) 3010 3010 bge mult32a 3011 * 3011 3012 3012 neg.l 8(a6) 3013 3013 addq.w #1,d2 3014 * 3014 3015 3015 mult32a: tst.l 12(a6) 3016 3016 bge mult32b 3017 * 3017 3018 3018 neg.l 12(a6) 3019 3019 addq.w #1,d2 3020 * 3020 3021 3021 mult32b: move.w 10(a6),d0 3022 3022 mulu 14(a6),d0 … … 3032 3032 btst #0,d2 3033 3033 beq mult32c 3034 * 3034 3035 3035 neg.l d0 3036 * 3036 3037 3037 mult32c: unlk a6 3038 3038 rts 3039 * 3040 .page 3041 * 3042 *rand -- Generate a random number3043 *---- ------------------------3044 rand: link a6,#-4 *Reserve stack for temps3045 tst.l rseed *See if the seed is zero3046 bne rand01 *Jump if not3047 * 3048 move.l _hz_200,d0 *Pick up the 200 Hz clock3049 moveq.l #16,d1 *Shift it left3050 asl.l d1,d0 *...3051 or.l _hz_200,d0 *OR in current 200 Hz clock3052 move.l d0,rseed *Use that as the seed3053 * 3054 rand01: move.l # $BB40E62D,-(a7) *Put PI on the stack3055 move.l rseed,-(a7) *... and rseed, too3056 bsr mult32 *Multiply them3057 addq.l #8,a7 *Cleanup stack3058 addq.l #1,d0 *Add 1 to the result3059 move.l d0,rseed *Save as new seed3039 3040 .page 3041 3042 | rand -- Generate a random number 3043 | ---- ------------------------ 3044 rand: link a6,#-4 | Reserve stack for temps 3045 tst.l rseed | See if the seed is zero 3046 bne rand01 | Jump if not 3047 3048 move.l _hz_200,d0 | Pick up the 200 Hz clock 3049 moveq.l #16,d1 | Shift it left 3050 asl.l d1,d0 | ... 3051 or.l _hz_200,d0 | OR in current 200 Hz clock 3052 move.l d0,rseed | Use that as the seed 3053 3054 rand01: move.l #0xBB40E62D,-(a7) | Put PI on the stack 3055 move.l rseed,-(a7) | ... and rseed, too 3056 bsr mult32 | Multiply them 3057 addq.l #8,a7 | Cleanup stack 3058 addq.l #1,d0 | Add 1 to the result 3059 move.l d0,rseed | Save as new seed 3060 3060 move.l rseed,d0 3061 asr.l #8,d0 *Make it a 24 bit number3062 and.l # $FFFFFF,d0 *...3063 unlk a6 *Release stack3064 rts *Return to caller3065 * 3066 .page 3067 * 3068 *protobt -- Generate a prototype boot sector3069 *------- --------------------------------3061 asr.l #8,d0 | Make it a 24 bit number 3062 and.l #0xFFFFFF,d0 | ... 3063 unlk a6 | Release stack 3064 rts | Return to caller 3065 3066 .page 3067 3068 | protobt -- Generate a prototype boot sector 3069 | ------- -------------------------------- 3070 3070 protobt: link a6,#-6 3071 movem.l d5-d7/a5,-(a7) *Save registers3072 tst.w 18(a6) *Test execflg3073 bge protbt03 *Jump if set3074 * 3075 move.w #256,(a7) *Count = 256 words3076 move.l 8(a6),-(a7) *Address of buffer3077 bsr chksum *Calculate checksum3078 addq.l #4,a7 *Cleanup stack3079 cmp.w # $1234,d0 *Boot checksum ?3080 beq protbt01 *Jump if so3081 * 3082 clr.w d0 *Not executable3071 movem.l d5-d7/a5,-(a7) | Save registers 3072 tst.w 18(a6) | Test execflg 3073 bge protbt03 | Jump if set 3074 3075 move.w #256,(a7) | Count = 256 words 3076 move.l 8(a6),-(a7) | Address of buffer 3077 bsr chksum | Calculate checksum 3078 addq.l #4,a7 | Cleanup stack 3079 cmp.w #0x1234,d0 | Boot checksum ? 3080 beq protbt01 | Jump if so 3081 3082 clr.w d0 | Not executable 3083 3083 bra protbt02 3084 * 3085 protbt01: moveq.l #1,d0 *Executable3086 * 3087 protbt02: move.w d0,18(a6) *Set execflg3088 * 3089 protbt03: tst.l 12(a6) *Serial number ?3090 blt protbt07 *Jump if not to be changed3091 * 3092 move.l 12(a6),d0 *Get it into d03093 cmp.l # $FFFFFF,d0 * > $FFFFFF3094 ble protbt04 *Jump if not3095 * 3096 bsr rand *Generate a random number3097 move.l d0,12(a6) *Save as s/n3098 * 3099 protbt04: clr.w d7 *Clear counter3100 bra protbt06 *Enter move loop3101 * 3102 .page 3103 * 3104 protbt05: move.l 12(a6),d0 *Get s/n3105 and.l # $FF,d0 *Isolate low 8 bits3106 move.w d7,a1 *Point to next byte3107 add.l 8(a6),a1 *...3108 move.b d0,8(a1) *Write byte in buffer3109 move.l 12(a6),d0 *Get s/n3110 asr.l #8,d0 *Shift right 8 bits3111 move.l d0,12(a6) *Save shifted value3112 addq.w #1,d7 *Update counter3113 * 3114 protbt06: cmp.w #3,d7 *See if we're done3115 blt protbt05 *Loop if not3116 * 3117 protbt07: tst.w 16(a6) *Diskette size ?3118 blt protbt10 *Jump if not to be changed3119 * 3120 move.w 16(a6),d6 *Get diskette size3121 muls.w #19,d6 *... times 19 as pointer3122 clr.w d7 *Clear counter3123 bra protbt09 *Go move in BPB3124 * 3125 protbt08: move.w d7,a0 *Get counter3126 add.l 8(a6),a0 *Add base of buffer3127 move.w d6,a1 *Get BPB pointer3128 add.l #pbpbtab,a1 *Add base of prototype BPB's3129 move.b (a1),11(a0) *Copy BPB data3130 addq.w #1,d6 *Update pointer3131 addq.w #1,d7 *Update counter3132 * 3133 protbt09: cmp.w #19,d7 *Done ?3134 blt protbt08 *Loop if not3135 * 3084 3085 protbt01: moveq.l #1,d0 | Executable 3086 3087 protbt02: move.w d0,18(a6) | Set execflg 3088 3089 protbt03: tst.l 12(a6) | Serial number ? 3090 blt protbt07 | Jump if not to be changed 3091 3092 move.l 12(a6),d0 | Get it into d0 3093 cmp.l #0xFFFFFF,d0 | > 0xFFFFFF 3094 ble protbt04 | Jump if not 3095 3096 bsr rand | Generate a random number 3097 move.l d0,12(a6) | Save as s/n 3098 3099 protbt04: clr.w d7 | Clear counter 3100 bra protbt06 | Enter move loop 3101 3102 .page 3103 3104 protbt05: move.l 12(a6),d0 | Get s/n 3105 and.l #0xFF,d0 | Isolate low 8 bits 3106 move.w d7,a1 | Point to next byte 3107 add.l 8(a6),a1 | ... 3108 move.b d0,8(a1) | Write byte in buffer 3109 move.l 12(a6),d0 | Get s/n 3110 asr.l #8,d0 | Shift right 8 bits 3111 move.l d0,12(a6) | Save shifted value 3112 addq.w #1,d7 | Update counter 3113 3114 protbt06: cmp.w #3,d7 | See if we're done 3115 blt protbt05 | Loop if not 3116 3117 protbt07: tst.w 16(a6) | Diskette size ? 3118 blt protbt10 | Jump if not to be changed 3119 3120 move.w 16(a6),d6 | Get diskette size 3121 muls.w #19,d6 | ... times 19 as pointer 3122 clr.w d7 | Clear counter 3123 bra protbt09 | Go move in BPB 3124 3125 protbt08: move.w d7,a0 | Get counter 3126 add.l 8(a6),a0 | Add base of buffer 3127 move.w d6,a1 | Get BPB pointer 3128 add.l #pbpbtab,a1 | Add base of prototype BPB's 3129 move.b (a1),11(a0) | Copy BPB data 3130 addq.w #1,d6 | Update pointer 3131 addq.w #1,d7 | Update counter 3132 3133 protbt09: cmp.w #19,d7 | Done ? 3134 blt protbt08 | Loop if not 3135 3136 3136 protbt10: clr.w -6(a6) 3137 3137 move.l 8(a6),-4(a6) 3138 3138 bra protbt12 3139 * 3140 .page 3141 * 3142 protbt11: move.l -4(a6),a0 *Get buffer pointer3143 move.w (a0),d0 *Get word from buffer3144 add.w d0,-6(a6) *Sum for checksum3145 addq.l #2,-4(a6) *Point at next word3146 * 3147 protbt12: move.l 8(a6),d0 *Get buffer address3148 add.l # $1FE,d0 *Plus sector length3149 cmp.l -4(a6),d0 *Done ?3150 bhi protbt11 *Loop if not3151 * 3152 move.w # $1234,d0 *Checksum for boot sector3153 sub.w -6(a6),d0 *Subtract checksum for buffer3139 3140 .page 3141 3142 protbt11: move.l -4(a6),a0 | Get buffer pointer 3143 move.w (a0),d0 | Get word from buffer 3144 add.w d0,-6(a6) | Sum for checksum 3145 addq.l #2,-4(a6) | Point at next word 3146 3147 protbt12: move.l 8(a6),d0 | Get buffer address 3148 add.l #0x1FE,d0 | Plus sector length 3149 cmp.l -4(a6),d0 | Done ? 3150 bhi protbt11 | Loop if not 3151 3152 move.w #0x1234,d0 | Checksum for boot sector 3153 sub.w -6(a6),d0 | Subtract checksum for buffer 3154 3154 move.l -4(a6),a1 3155 move.w d0,(a1) *Store checksum in buffer3156 tst.w 18(a6) *Check execflg3157 bne protbt13 *Boot sector to be executable ?3158 * 3159 move.l -4(a6),a0 *Mung checksum so it's not3155 move.w d0,(a1) | Store checksum in buffer 3156 tst.w 18(a6) | Check execflg 3157 bne protbt13 | Boot sector to be executable ? 3158 3159 move.l -4(a6),a0 | Mung checksum so it's not 3160 3160 addq.w #1,(a0) 3161 * 3161 3162 3162 protbt13: tst.l (a7)+ 3163 movem.l (a7)+,d6-d7/a5 *Restore registers3164 unlk a6 *Release stack3165 rts *Return to caller3166 * 3167 .endc 3168 * 3169 *criter -- Critical error handler3170 *------ ----------------------3171 criter: move.l critvec,-(a7) *Put error vector on stack3172 moveq.l #-1,d0 *Set default error return3173 rts *"Return" to handler3174 * 3175 .page 3176 * 3163 movem.l (a7)+,d6-d7/a5 | Restore registers 3164 unlk a6 | Release stack 3165 rts | Return to caller 3166 3167 .endc 3168 3169 | criter -- Critical error handler 3170 | ------ ---------------------- 3171 criter: move.l critvec,-(a7) | Put error vector on stack 3172 moveq.l #-1,d0 | Set default error return 3173 rts | "Return" to handler 3174 3175 .page 3176 3177 3177 .ifne BUCHLA 3178 * 3179 *api_int -- Analog processor interrupt handler3180 *------- ----------------------------------3181 api_int: movem.l d0-d1/a0-a1,-(a7) *Save registers3182 clr.l d0 *Read input port3183 move.b ANALOG,d0 *... into d0[7..0]3184 move.b d0,api_inp *... and api_inp3185 btst #7,d0 *Check for signal number flag3186 bne api_s0a *Jump if signal number read3187 * 3188 lea api_tv,a0 *Get api_tv base in a03189 clr.w d1 *Get api_sv in d13190 move.b api_sv,d1 *...3191 cmpi.b #6,d1 *Check range3192 bgt api_sve *Jump if out of range3193 * 3194 lsl.w #2,d1 *Develop jump address3195 move.l 0(a0,d1.W),a1 *... from api_tv in a13196 jmp (a1) *Jump to state handler3197 * 3198 api_s0: btst #7,d0 *Check for signal number flag3199 beq api_ret *Jump if not signal number3200 * 3201 api_s0a: clr.b api_val *Clear value byte3202 andi.b # $7F,d0 *Mask off signal number flag3203 cmpi.b #82,d0 *See if it's in range3204 bgt api_err *Jump if out of range (GT 82)3205 * 3206 move.b d0,api_sig *Store signal number3207 beq api_pub *Jump if it was "all off"3208 * 3209 lea api_tab,a0 *Get sv table base3210 move.b 0(a0,d0.W),api_sv *Set sv for next time3211 * 3212 api_ret: movem.l (a7)+,d0-d1/a0-a1 *Restore registers3213 rte *Return to interrupted code3214 * 3215 api_err: move.b d0,api_bug *Catch the bug3216 clr.b api_sv *Force state zero3217 bra api_ret *Go back to interrupted code3218 * 3219 api_sve: move.b d1,api_svb *Catch the bug3220 clr.b api_sv *Force state zero3221 bra api_ret *Go back to interrupted code3222 * 3223 .page 3224 api_s1: btst #0,d0 *See if it takes a value3225 beq api_s1a *Jump if not3226 * 3227 move.b #2,api_sv *Set sv for state 23228 bra api_ret *Go return from interrupt3229 * 3230 api_s1a: clr.b api_val *Clear value byte3231 bra api_pub *Go output to fifo3232 * 3233 api_s2: ori.b # $80,d0 *Set status = 13234 move.b d0,api_val *Set value byte3235 bra api_pub *Go output to fifo3236 * 3237 api_s3: ror.b #1,d0 *Set status in value byte3238 andi.b # $80,d0 *...3239 move.b d0,api_val *...3240 move.b #4,api_sv *Set sv for state 43241 bra api_ret *Go return from interrupt3242 * 3243 api_s4: or.b d0,api_val *Set value byte3244 bra api_pub *Go output to fifo3245 * 3246 api_s5: ror.b #1,d0 *Set status in value byte3247 andi.b # $80,d0 *...3248 * 3249 api_s6: move.b d0,api_val *Set value byte3250 * 3251 api_pub: movea.l api_fi,a0 *Get fifo input pointer in a03252 move.w api_sig,(a0)+ *Store new input3253 cmpa.l #api_fe,a0 *Wrap around ?3254 blt api_pb1 *Jump if not3255 * 3256 movea.l #api_fum,a0 *Wrap input pointer to start3257 * 3258 api_pb1: move.l a0,api_fi *Update input pointer3259 cmpa.l api_fo,a0 *Buffer full ?3260 bne api_pb3 *Jump if not3261 * 3262 movea.l api_fo,a1 *Get fifo output pointer in a13263 adda.l #2,a1 *Increment it3264 cmpa.l #api_fe,a1 *Wrap around ?3265 blt api_pb2 *Jump if not3266 * 3267 movea.l #api_fum,a1 *Wrap output pointer to start3268 * 3269 api_pb2: move.l a1,api_fo *Set new output pointer3270 * 3271 api_pb3: clr.b api_sv *Set state to 03272 bra api_ret *Return from interrupt3273 * 3274 .page 3275 * 3276 *api_get -- Get analog input3277 *------- ----------------3278 api_get: move.w sr,-(a7) *Save status register3279 ori.w #IPL3,sr *Disable ANALOG I/O interrupts3280 movea.l api_fo,a0 *Get fifo output pointer3281 cmpa.l api_fi,a0 *See if fifo is empty3282 bne api_g1 *Jump if not3283 * 3284 moveq.l #-1,d0 *Set empty-fifo value3285 move.w (a7)+,sr *Restore interrupt mask3286 rts *Return to caller3287 * 3288 api_g1: clr.l d0 *Get fifo value3289 move.w (a0)+,d0 *...3290 cmpa.l #api_fe,a0 *See if pointer wrapped3291 blt api_g2 *Jump if not3292 * 3293 movea.l #api_fum,a0 *Wrap the pointer around3294 * 3295 api_g2: move.l a0,api_fo *Update pointer3296 move.w (a7)+,sr *Restore interrupt mask3297 rts *Return to caller3298 * 3299 *api_zap -- clear analog I/O FIFO3300 *------- ---------------------3301 api_zap: move.w sr,-(a7) *Save status register3302 ori.w #IPL3,sr *Disable ANALOG I/O interrupts3303 move.l #api_fum,api_fi *Clear analog processor fifo3304 move.l #api_fum,api_fo *...3305 move.w (a7)+,sr *Restore interrupt mask3178 3179 | api_int -- Analog processor interrupt handler 3180 | ------- ---------------------------------- 3181 api_int: movem.l d0-d1/a0-a1,-(a7) | Save registers 3182 clr.l d0 | Read input port 3183 move.b ANALOG,d0 | ... into d0[7..0] 3184 move.b d0,api_inp | ... and api_inp 3185 btst #7,d0 | Check for signal number flag 3186 bne api_s0a | Jump if signal number read 3187 3188 lea api_tv,a0 | Get api_tv base in a0 3189 clr.w d1 | Get api_sv in d1 3190 move.b api_sv,d1 | ... 3191 cmpi.b #6,d1 | Check range 3192 bgt api_sve | Jump if out of range 3193 3194 lsl.w #2,d1 | Develop jump address 3195 move.l 0(a0,d1.W),a1 | ... from api_tv in a1 3196 jmp (a1) | Jump to state handler 3197 3198 api_s0: btst #7,d0 | Check for signal number flag 3199 beq api_ret | Jump if not signal number 3200 3201 api_s0a: clr.b api_val | Clear value byte 3202 andi.b #0x7F,d0 | Mask off signal number flag 3203 cmpi.b #82,d0 | See if it's in range 3204 bgt api_err | Jump if out of range (GT 82) 3205 3206 move.b d0,api_sig | Store signal number 3207 beq api_pub | Jump if it was "all off" 3208 3209 lea api_tab,a0 | Get sv table base 3210 move.b 0(a0,d0.W),api_sv | Set sv for next time 3211 3212 api_ret: movem.l (a7)+,d0-d1/a0-a1 | Restore registers 3213 rte | Return to interrupted code 3214 3215 api_err: move.b d0,api_bug | Catch the bug 3216 clr.b api_sv | Force state zero 3217 bra api_ret | Go back to interrupted code 3218 3219 api_sve: move.b d1,api_svb | Catch the bug 3220 clr.b api_sv | Force state zero 3221 bra api_ret | Go back to interrupted code 3222 3223 .page 3224 api_s1: btst #0,d0 | See if it takes a value 3225 beq api_s1a | Jump if not 3226 3227 move.b #2,api_sv | Set sv for state 2 3228 bra api_ret | Go return from interrupt 3229 3230 api_s1a: clr.b api_val | Clear value byte 3231 bra api_pub | Go output to fifo 3232 3233 api_s2: ori.b #0x80,d0 | Set status = 1 3234 move.b d0,api_val | Set value byte 3235 bra api_pub | Go output to fifo 3236 3237 api_s3: ror.b #1,d0 | Set status in value byte 3238 andi.b #0x80,d0 | ... 3239 move.b d0,api_val | ... 3240 move.b #4,api_sv | Set sv for state 4 3241 bra api_ret | Go return from interrupt 3242 3243 api_s4: or.b d0,api_val | Set value byte 3244 bra api_pub | Go output to fifo 3245 3246 api_s5: ror.b #1,d0 | Set status in value byte 3247 andi.b #0x80,d0 | ... 3248 3249 api_s6: move.b d0,api_val | Set value byte 3250 3251 api_pub: movea.l api_fi,a0 | Get fifo input pointer in a0 3252 move.w api_sig,(a0)+ | Store new input 3253 cmpa.l #api_fe,a0 | Wrap around ? 3254 blt api_pb1 | Jump if not 3255 3256 movea.l #api_fum,a0 | Wrap input pointer to start 3257 3258 api_pb1: move.l a0,api_fi | Update input pointer 3259 cmpa.l api_fo,a0 | Buffer full ? 3260 bne api_pb3 | Jump if not 3261 3262 movea.l api_fo,a1 | Get fifo output pointer in a1 3263 adda.l #2,a1 | Increment it 3264 cmpa.l #api_fe,a1 | Wrap around ? 3265 blt api_pb2 | Jump if not 3266 3267 movea.l #api_fum,a1 | Wrap output pointer to start 3268 3269 api_pb2: move.l a1,api_fo | Set new output pointer 3270 3271 api_pb3: clr.b api_sv | Set state to 0 3272 bra api_ret | Return from interrupt 3273 3274 .page 3275 3276 | api_get -- Get analog input 3277 | ------- ---------------- 3278 api_get: move.w sr,-(a7) | Save status register 3279 ori.w #IPL3,sr | Disable ANALOG I/O interrupts 3280 movea.l api_fo,a0 | Get fifo output pointer 3281 cmpa.l api_fi,a0 | See if fifo is empty 3282 bne api_g1 | Jump if not 3283 3284 moveq.l #-1,d0 | Set empty-fifo value 3285 move.w (a7)+,sr | Restore interrupt mask 3286 rts | Return to caller 3287 3288 api_g1: clr.l d0 | Get fifo value 3289 move.w (a0)+,d0 | ... 3290 cmpa.l #api_fe,a0 | See if pointer wrapped 3291 blt api_g2 | Jump if not 3292 3293 movea.l #api_fum,a0 | Wrap the pointer around 3294 3295 api_g2: move.l a0,api_fo | Update pointer 3296 move.w (a7)+,sr | Restore interrupt mask 3297 rts | Return to caller 3298 3299 | api_zap -- clear analog I/O FIFO 3300 | ------- --------------------- 3301 api_zap: move.w sr,-(a7) | Save status register 3302 ori.w #IPL3,sr | Disable ANALOG I/O interrupts 3303 move.l #api_fum,api_fi | Clear analog processor fifo 3304 move.l #api_fum,api_fo | ... 3305 move.w (a7)+,sr | Restore interrupt mask 3306 3306 rts 3307 * 3308 .endc 3309 * 3310 .page 3311 ************************************************************************* 3312 * * 3313 * Constant definitions * 3314 * -------------------- * 3315 ************************************************************************* 3316 * 3307 3308 .endc 3309 3310 .page 3311 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 3312 | | 3313 | Constant definitions | 3314 | -------------------- | 3315 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 3316 3317 3317 .even 3318 * 3318 3319 3319 .ifne BUCHLA 3320 * 3321 *Buchla 700 tables:3322 * 3323 *t13tab -- Trap-13 pointer table -- Primary BIOS functions3324 *------ -----------------------------------------------3325 t13tab: dc.w 12 *Number of Trap-13 routines3326 * 3327 dc.l nullrts *0 - (getmpb)3328 dc.l bconstat *1 - bconstat3329 dc.l bconin *2 - bconin3330 dc.l bconout *3 - bconout3331 dc.l rwabs *4 - rwabs3332 dc.l setexec *5 - setexec3333 dc.l nullrts *6 - (tickcal)3334 dc.l getbpb *7 - getbpb3335 dc.l bcostat *8 - bcostat3336 dc.l mediach *9 - mediach3337 dc.l drvmap *10 - drvmap3338 dc.l nullrts *11 - (shift)3339 * 3340 .page 3341 * 3342 *t14tab -- Trap-14 pointer table -- Extended BIOS functions (Buchla 700 only)3343 *------ ------------------------------------------------------------------3344 t14tab: dc.w 10 *Number of trap14 routines3345 * 3346 dc.l piorec *0 - Get iorec address3347 dc.l setport *1 - Set ACIA parameters3348 dc.l floprd *2 - Read floppy3349 dc.l flopwr *3 - Write floppy3350 dc.l flopfmt *4 - Format floppy3351 dc.l flopver *5 - Verify floppy3352 dc.l protobt *6 - Create prototype boot sec.3353 dc.l rand *7 - Generate random number3354 dc.l api_get *8 - Get analog input3355 dc.l api_zap *9 - Clear analog FIFO3356 * 3357 .endc 3358 * 3320 3321 | Buchla 700 tables: 3322 3323 | t13tab -- Trap-13 pointer table -- Primary BIOS functions 3324 | ------ ----------------------------------------------- 3325 t13tab: dc.w 12 | Number of Trap-13 routines 3326 3327 dc.l nullrts | 0 - (getmpb) 3328 dc.l bconstat | 1 - bconstat 3329 dc.l bconin | 2 - bconin 3330 dc.l bconout | 3 - bconout 3331 dc.l rwabs | 4 - rwabs 3332 dc.l setexec | 5 - setexec 3333 dc.l nullrts | 6 - (tickcal) 3334 dc.l getbpb | 7 - getbpb 3335 dc.l bcostat | 8 - bcostat 3336 dc.l mediach | 9 - mediach 3337 dc.l drvmap | 10 - drvmap 3338 dc.l nullrts | 11 - (shift) 3339 3340 .page 3341 3342 | t14tab -- Trap-14 pointer table -- Extended BIOS functions (Buchla 700 only) 3343 | ------ ------------------------------------------------------------------ 3344 t14tab: dc.w 10 | Number of trap14 routines 3345 3346 dc.l piorec | 0 - Get iorec address 3347 dc.l setport | 1 - Set ACIA parameters 3348 dc.l floprd | 2 - Read floppy 3349 dc.l flopwr | 3 - Write floppy 3350 dc.l flopfmt | 4 - Format floppy 3351 dc.l flopver | 5 - Verify floppy 3352 dc.l protobt | 6 - Create prototype boot sec. 3353 dc.l rand | 7 - Generate random number 3354 dc.l api_get | 8 - Get analog input 3355 dc.l api_zap | 9 - Clear analog FIFO 3356 3357 .endc 3358 3359 3359 .even 3360 * 3360 3361 3361 .ifeq BUCHLA 3362 * 3363 *NASA 3D Helmet tables:3364 * 3365 *t13tab -- Trap-13 pointer table -- Primary BIOS functions3366 *------ -----------------------------------------------3367 t13tab: dc.w 12 *Number of Trap-13 routines3368 * 3369 dc.l nullrts *0 - (getmpb)3370 dc.l bconstat *1 - bconstat3371 dc.l bconin *2 - bconin3372 dc.l bconout *3 - bconout3373 dc.l nullrts *4 - (rwabs)3374 dc.l setexec *5 - setexec3375 dc.l nullrts *6 - (tickcal)3376 dc.l nullrts *7 - (getbpb)3377 dc.l bcostat *8 - bcostat3378 dc.l nullrts *9 - (mediach)3379 dc.l nullrts *10 - (drvmap)3380 dc.l nullrts *11 - (shift)3381 * 3382 .page 3383 * 3384 *t14tab -- Trap-14 pointer table -- Extended BIOS functions (Buchla 700 only)3385 *------ ------------------------------------------------------------------3386 t14tab: dc.w 10 *Number of trap14 routines3387 * 3388 dc.l piorec *0 - Get iorec address3389 dc.l setport *1 - Set ACIA parameters3390 dc.l nullrts *2 - (Read floppy)3391 dc.l nullrts *3 - (Write floppy)3392 dc.l nullrts *4 - (Format floppy)3393 dc.l nullrts *5 - (Verify floppy)3394 dc.l nullrts *6 - (Create prototype boot sec.)3395 dc.l nullrts *7 - (Generate random number)3396 dc.l nullrts *8 - (Get analog input)3397 dc.l nullrts *9 - (Clear analog FIFO)3398 * 3399 .endc 3400 * 3401 .page 3402 * 3403 *cdt01 -- Character device dispatch table #1 -- input status3404 *----- --------------------------------------------------3405 cdt01: dc.l sr1ist *0 - PRT -- Printer3406 dc.l sr2ist *1 - AUX -- Serial-23407 dc.l sr2ist *2 - CON -- Console3408 * 3362 3363 | NASA 3D Helmet tables: 3364 3365 | t13tab -- Trap-13 pointer table -- Primary BIOS functions 3366 | ------ ----------------------------------------------- 3367 t13tab: dc.w 12 | Number of Trap-13 routines 3368 3369 dc.l nullrts | 0 - (getmpb) 3370 dc.l bconstat | 1 - bconstat 3371 dc.l bconin | 2 - bconin 3372 dc.l bconout | 3 - bconout 3373 dc.l nullrts | 4 - (rwabs) 3374 dc.l setexec | 5 - setexec 3375 dc.l nullrts | 6 - (tickcal) 3376 dc.l nullrts | 7 - (getbpb) 3377 dc.l bcostat | 8 - bcostat 3378 dc.l nullrts | 9 - (mediach) 3379 dc.l nullrts | 10 - (drvmap) 3380 dc.l nullrts | 11 - (shift) 3381 3382 .page 3383 3384 | t14tab -- Trap-14 pointer table -- Extended BIOS functions (Buchla 700 only) 3385 | ------ ------------------------------------------------------------------ 3386 t14tab: dc.w 10 | Number of trap14 routines 3387 3388 dc.l piorec | 0 - Get iorec address 3389 dc.l setport | 1 - Set ACIA parameters 3390 dc.l nullrts | 2 - (Read floppy) 3391 dc.l nullrts | 3 - (Write floppy) 3392 dc.l nullrts | 4 - (Format floppy) 3393 dc.l nullrts | 5 - (Verify floppy) 3394 dc.l nullrts | 6 - (Create prototype boot sec.) 3395 dc.l nullrts | 7 - (Generate random number) 3396 dc.l nullrts | 8 - (Get analog input) 3397 dc.l nullrts | 9 - (Clear analog FIFO) 3398 3399 .endc 3400 3401 .page 3402 3403 | cdt01 -- Character device dispatch table #1 -- input status 3404 | ----- -------------------------------------------------- 3405 cdt01: dc.l sr1ist | 0 - PRT -- Printer 3406 dc.l sr2ist | 1 - AUX -- Serial-2 3407 dc.l sr2ist | 2 - CON -- Console 3408 3409 3409 .ifne BUCHLA 3410 * 3411 dc.l mc1ist *3 - MC1 -- MIDI-13412 dc.l mc2ist *4 - MC2 -- MIDI-23413 * 3414 .endc 3415 * 3416 *cdt02 -- Character device dispatch table #2 -- input3417 *----- -------------------------------------------3418 cdt02: dc.l sr1inp *0 - PRT -- Printer3419 dc.l sr2inp *1 - AUX -- Serial-23420 dc.l sr2inp *2 - CON -- Console3421 * 3410 3411 dc.l mc1ist | 3 - MC1 -- MIDI-1 3412 dc.l mc2ist | 4 - MC2 -- MIDI-2 3413 3414 .endc 3415 3416 | cdt02 -- Character device dispatch table #2 -- input 3417 | ----- ------------------------------------------- 3418 cdt02: dc.l sr1inp | 0 - PRT -- Printer 3419 dc.l sr2inp | 1 - AUX -- Serial-2 3420 dc.l sr2inp | 2 - CON -- Console 3421 3422 3422 .ifne BUCHLA 3423 * 3424 dc.l mc1inp *3 - MC1 -- MIDI-13425 dc.l mc2inp *4 - MC2 -- MIDI-23426 * 3427 .endc 3428 * 3429 *cdt03 -- Character device dispatch table #3 -- output3430 *----- --------------------------------------------3431 cdt03: dc.l sr1out *0 - PRT -- Printer3432 dc.l sr2out *1 - AUX -- Serial-23433 dc.l sr2out *2 - CON -- Console3423 3424 dc.l mc1inp | 3 - MC1 -- MIDI-1 3425 dc.l mc2inp | 4 - MC2 -- MIDI-2 3426 3427 .endc 3428 3429 | cdt03 -- Character device dispatch table #3 -- output 3430 | ----- -------------------------------------------- 3431 cdt03: dc.l sr1out | 0 - PRT -- Printer 3432 dc.l sr2out | 1 - AUX -- Serial-2 3433 dc.l sr2out | 2 - CON -- Console 3434 3434 .ifne BUCHLA 3435 * 3436 dc.l mc1out *3 - MC1 -- MIDI-13437 dc.l mc2out *4 - MC2 -- MIDI-23438 * 3439 .endc 3440 * 3441 *cdt04 -- Character device dispatch table #4 -- output status3442 *----- ---------------------------------------------------3443 cdt04: dc.l sr1ost *0 - PRT -- Printer3444 dc.l sr2ost *1 - AUX -- Serial-23445 dc.l sr2ost *2 - CON -- Console3435 3436 dc.l mc1out | 3 - MC1 -- MIDI-1 3437 dc.l mc2out | 4 - MC2 -- MIDI-2 3438 3439 .endc 3440 3441 | cdt04 -- Character device dispatch table #4 -- output status 3442 | ----- --------------------------------------------------- 3443 cdt04: dc.l sr1ost | 0 - PRT -- Printer 3444 dc.l sr2ost | 1 - AUX -- Serial-2 3445 dc.l sr2ost | 2 - CON -- Console 3446 3446 .ifne BUCHLA 3447 * 3448 dc.l mc1ost *3 - MC1 -- MIDI-13449 dc.l mc2ost *4 - MC2 -- MIDI-23450 * 3451 .endc 3452 * 3453 .page 3454 * 3455 *iorec defaults:3456 *---------------3457 *Serial-1:3458 *---------3447 3448 dc.l mc1ost | 3 - MC1 -- MIDI-1 3449 dc.l mc2ost | 4 - MC2 -- MIDI-2 3450 3451 .endc 3452 3453 .page 3454 3455 | iorec defaults: 3456 | --------------- 3457 | Serial-1: 3458 | --------- 3459 3459 sr1dflt: dc.l sr1ibuf 3460 3460 dc.w SR1IBS … … 3472 3472 dc.b 0,0 3473 3473 dc.w 0,0 3474 * 3475 *Serial-2:3476 *---------3474 3475 | Serial-2: 3476 | --------- 3477 3477 sr2dflt: dc.l sr2ibuf 3478 3478 dc.w SR2IBS … … 3490 3490 dc.b 0,0 3491 3491 dc.w 0,0 3492 * 3493 .page 3494 * 3492 3493 .page 3494 3495 3495 .ifne BUCHLA 3496 * 3497 *MIDI-1:3498 *-------3496 3497 | MIDI-1: 3498 | ------- 3499 3499 mc1dflt: dc.l mc1ibuf 3500 3500 dc.w MC1IBS … … 3512 3512 dc.b 0,0 3513 3513 dc.w 0,0 3514 * 3515 *MIDI-2:3516 *-------3514 3515 | MIDI-2: 3516 | ------- 3517 3517 mc2dflt: dc.l mc2ibuf 3518 3518 dc.w MC2IBS … … 3530 3530 dc.b 0,0 3531 3531 dc.w 0,0 3532 * 3533 .endc 3534 * 3535 .page 3536 * 3537 *brtable -- Baud rate setup table3538 *------- ---------------------3539 brtable: dc.b BR_19K2 *0 - 19200 baud3540 dc.b BR_9600 *1 - 9600 baud3541 dc.b BR_4800 *2 - 4800 baud3542 dc.b BR_3600 *3 - 3600 baud3543 dc.b BR_2400 *4 - 2400 baud3544 dc.b BR_7200 *5 - 7200 baud (2000 on Atari)3545 dc.b BR_1800 *6 - 1800 baud3546 dc.b BR_1200 *7 - 1200 baud3547 dc.b BR_600 *8 - 600 baud3548 dc.b BR_300 *9 - 300 baud3549 * 3550 *iortab -- iorec pointer table3551 *------ -------------------3552 iortab: dc.l sr1iorec *0 - PRT Serial-1 Printer3553 dc.l sr2iorec *1 - AUX Serial-2 Host3554 dc.l sr2iorec *2 - CON Serial-2 Console3555 * 3532 3533 .endc 3534 3535 .page 3536 3537 | brtable -- Baud rate setup table 3538 | ------- --------------------- 3539 brtable: dc.b BR_19K2 | 0 - 19200 baud 3540 dc.b BR_9600 | 1 - 9600 baud 3541 dc.b BR_4800 | 2 - 4800 baud 3542 dc.b BR_3600 | 3 - 3600 baud 3543 dc.b BR_2400 | 4 - 2400 baud 3544 dc.b BR_7200 | 5 - 7200 baud (2000 on Atari) 3545 dc.b BR_1800 | 6 - 1800 baud 3546 dc.b BR_1200 | 7 - 1200 baud 3547 dc.b BR_600 | 8 - 600 baud 3548 dc.b BR_300 | 9 - 300 baud 3549 3550 | iortab -- iorec pointer table 3551 | ------ ------------------- 3552 iortab: dc.l sr1iorec | 0 - PRT Serial-1 Printer 3553 dc.l sr2iorec | 1 - AUX Serial-2 Host 3554 dc.l sr2iorec | 2 - CON Serial-2 Console 3555 3556 3556 .ifne BUCHLA 3557 * 3558 dc.l mc1iorec *3 - MC1 MIDI-1 MIDI port #13559 dc.l mc2iorec *4 - MC2 MIDI-2 MIDI port #23560 * 3561 .endc 3562 * 3563 *aciatab -- iorec and ACIA pointer table3564 *------- ----------------------------3565 aciatab: dc.l sr1iorec,SR1ACIA *0 - PRT Serial-13566 dc.l sr2iorec,SR2ACIA *1 - AUX Serial-23567 dc.l sr2iorec,SR2ACIA *2 - CON Serial-23568 * 3557 3558 dc.l mc1iorec | 3 - MC1 MIDI-1 MIDI port #1 3559 dc.l mc2iorec | 4 - MC2 MIDI-2 MIDI port #2 3560 3561 .endc 3562 3563 | aciatab -- iorec and ACIA pointer table 3564 | ------- ---------------------------- 3565 aciatab: dc.l sr1iorec,SR1ACIA | 0 - PRT Serial-1 3566 dc.l sr2iorec,SR2ACIA | 1 - AUX Serial-2 3567 dc.l sr2iorec,SR2ACIA | 2 - CON Serial-2 3568 3569 3569 .ifne BUCHLA 3570 * 3571 dc.l mc1iorec,MC1ACIA *3 - MC1 MIDI-13572 dc.l mc2iorec,MC2ACIA *4 - MC2 MIDI-23573 * 3574 .endc 3575 * 3576 .page 3577 * 3570 3571 dc.l mc1iorec,MC1ACIA | 3 - MC1 MIDI-1 3572 dc.l mc2iorec,MC2ACIA | 4 - MC2 MIDI-2 3573 3574 .endc 3575 3576 .page 3577 3578 3578 .ifne BUCHLA 3579 * 3580 *pbpbtab -- Prototype BPB data table (BPS..NHID) 19 bytes per entry3581 *------- ---------------------------------------------------------3582 * 3583 *0 -- 40 tracks, single sided (180K)3584 * 3585 pbpbtab: dc.b $00,$02,$01,$01,$00,$02,$40,$003586 dc.b $68,$01,$FC,$02,$00,$09,$00,$013587 dc.b $00,$00,$003588 * 3589 *1 -- 40 tracks, double sided (360K)3590 * 3591 dc.b $00,$02,$02,$01,$00,$02,$70,$003592 dc.b $D0,$02,$FD,$02,$00,$09,$00,$023593 dc.b $00,$00,$003594 * 3595 *2 -- 80 tracks, single sided (360K)3596 * 3597 dc.b $00,$02,$02,$01,$00,$02,$70,$003598 dc.b $D0,$02,$F8,$05,$00,$09,$00,$013599 dc.b $00,$00,$003600 * 3601 *3 -- 80 tracks, double sided (720K)3602 * 3603 dc.b $00,$02,$02,$01,$00,$02,$70,$003604 dc.b $A0,$05,$F9,$05,$00,$09,$00,$023605 dc.b $00,$00,$003606 * 3607 *VSDD initialization table3608 * 3579 3580 | pbpbtab -- Prototype BPB data table (BPS..NHID) 19 bytes per entry 3581 | ------- --------------------------------------------------------- 3582 3583 | 0 -- 40 tracks, single sided (180K) 3584 3585 pbpbtab: dc.b 0x00,0x02,0x01,0x01,0x00,0x02,0x40,0x00 3586 dc.b 0x68,0x01,0xFC,0x02,0x00,0x09,0x00,0x01 3587 dc.b 0x00,0x00,0x00 3588 3589 | 1 -- 40 tracks, double sided (360K) 3590 3591 dc.b 0x00,0x02,0x02,0x01,0x00,0x02,0x70,0x00 3592 dc.b 0xD0,0x02,0xFD,0x02,0x00,0x09,0x00,0x02 3593 dc.b 0x00,0x00,0x00 3594 3595 | 2 -- 80 tracks, single sided (360K) 3596 3597 dc.b 0x00,0x02,0x02,0x01,0x00,0x02,0x70,0x00 3598 dc.b 0xD0,0x02,0xF8,0x05,0x00,0x09,0x00,0x01 3599 dc.b 0x00,0x00,0x00 3600 3601 | 3 -- 80 tracks, double sided (720K) 3602 3603 dc.b 0x00,0x02,0x02,0x01,0x00,0x02,0x70,0x00 3604 dc.b 0xA0,0x05,0xF9,0x05,0x00,0x09,0x00,0x02 3605 dc.b 0x00,0x00,0x00 3606 3607 | VSDD initialization table 3608 3609 3609 .even 3610 * 3611 vsddtab: dc.w $8252 *R0 Mode word 03612 dc.w $E474 *R1 Mode word 13613 dc.w $0006 *R2 Register window base3614 dc.w $0100 *R3 Data window base3615 dc.w $0000 *R4 Data length mask3616 dc.w $0000 *R5 Data segment base3617 dc.w $0001 *R6 Priority access count3618 dc.w $0040 *R7 ODT base3619 dc.w $0080 *R8 AT base3620 dc.w $0010 *R9 CLT base3621 dc.w $0011 *R10 CG bases3622 dc.w $0000 *R11 AT counter (R/O)3623 * 3624 dc.w $0C08 *R12 HC0 = 3, VC0 = 83625 dc.w $140A *R13 HC1 = 5, VC1 = 103626 dc.w $9568 *R14 HC2 = 37, VC2 = 3603627 dc.w $A16A *R15 HC3 = 40, VC3 = 3623628 * 3629 vsddit01: dc.w $8253 *R0 with UCF = 1, DEN = 03630 vsddit02: dc.w $825B *R0 with UCF = 1, DEN = 13631 * 3632 .page 3633 * 3634 *analog processor input state table3635 * 3636 api_tab: dc.b 0,1,1,1,1,1,1,1,1,1 *0..93637 dc.b 1,1,1,1,1,1,1,1,1,1 *10..193638 dc.b 1,1,1,1,1 *20..243639 dc.b 3,3,3,3,3 *25..293640 dc.b 3,3,3,3,3,3,3,3,3 *30..383641 dc.b 5 *393642 dc.b 5,5,5,5,5,5,5,5,5,5 *40..493643 dc.b 5,5,5 *50..523644 dc.b 3,3,3,3,3,3,3 *53..593645 dc.b 5,5,5,5,5,5,5,5,5,5 *60..693646 dc.b 5,5,5 *70..723647 dc.b 6,6,6,6,6,6,6 *73..793648 dc.b 6,6,6 *80..823649 * 3610 3611 vsddtab: dc.w 0x8252 | R0 Mode word 0 3612 dc.w 0xE474 | R1 Mode word 1 3613 dc.w 0x0006 | R2 Register window base 3614 dc.w 0x0100 | R3 Data window base 3615 dc.w 0x0000 | R4 Data length mask 3616 dc.w 0x0000 | R5 Data segment base 3617 dc.w 0x0001 | R6 Priority access count 3618 dc.w 0x0040 | R7 ODT base 3619 dc.w 0x0080 | R8 AT base 3620 dc.w 0x0010 | R9 CLT base 3621 dc.w 0x0011 | R10 CG bases 3622 dc.w 0x0000 | R11 AT counter (R/O) 3623 3624 dc.w 0x0C08 | R12 HC0 = 3, VC0 = 8 3625 dc.w 0x140A | R13 HC1 = 5, VC1 = 10 3626 dc.w 0x9568 | R14 HC2 = 37, VC2 = 360 3627 dc.w 0xA16A | R15 HC3 = 40, VC3 = 362 3628 3629 vsddit01: dc.w 0x8253 | R0 with UCF = 1, DEN = 0 3630 vsddit02: dc.w 0x825B | R0 with UCF = 1, DEN = 1 3631 3632 .page 3633 3634 | analog processor input state table 3635 3636 api_tab: dc.b 0,1,1,1,1,1,1,1,1,1 | 0..9 3637 dc.b 1,1,1,1,1,1,1,1,1,1 | 10..19 3638 dc.b 1,1,1,1,1 | 20..24 3639 dc.b 3,3,3,3,3 | 25..29 3640 dc.b 3,3,3,3,3,3,3,3,3 | 30..38 3641 dc.b 5 | 39 3642 dc.b 5,5,5,5,5,5,5,5,5,5 | 40..49 3643 dc.b 5,5,5 | 50..52 3644 dc.b 3,3,3,3,3,3,3 | 53..59 3645 dc.b 5,5,5,5,5,5,5,5,5,5 | 60..69 3646 dc.b 5,5,5 | 70..72 3647 dc.b 6,6,6,6,6,6,6 | 73..79 3648 dc.b 6,6,6 | 80..82 3649 3650 3650 .even 3651 * 3652 *analog processor state transfer vector3653 * 3651 3652 | analog processor state transfer vector 3653 3654 3654 api_tv: dc.l api_s0,api_s1,api_s2,api_s3 3655 3655 dc.l api_s4,api_s5,api_s6 3656 * 3657 .endc 3658 * 3659 .page 3660 ************************************************************************* 3661 * * 3662 * RAM storage definitions * 3663 * ----------------------- * 3664 ************************************************************************* 3665 * 3656 3657 .endc 3658 3659 .page 3660 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 3661 | | 3662 | RAM storage definitions | 3663 | ----------------------- | 3664 ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| 3665 3666 3666 .bss 3667 3667 .even 3668 * 3669 *RAM data area3670 *-------------3671 *WARNING:3672 *--------3673 *The variables from timevec through rsarea are permanently assigned so3674 *that we can link to certain bios variables without having to link to the3675 *bios object file itself. Some of these get defined in hwdefs.s and in3676 *hwdefs.s so beware of changing them.3677 * 3678 timevec: ds.l 1 *System timer trap vector3679 critvec: ds.l 1 *Critical error handler vector3680 termvec: ds.l 1 *Process terminate hook vector3681 resvec3: ds.l 1 *Reserved vector 33682 resvec4: ds.l 1 *Reserved vector 43683 resvec5: ds.l 1 *Reserved vector 53684 resvec6: ds.l 1 *Reserved vector 63685 resvec7: ds.l 1 *Reserved vector 73686 * 3687 fc_sw: ds.w 1 *Frame clock switch (<0=dn, 0=off, >0=up)3688 fc_val: ds.l 1 *Frame clock value (0..FCMAX)3689 * 3690 _wzcrsh: ds.w 1 *Crash area: flag for ROMP3691 _crshsr: ds.w 1 *Crash area: SR3692 _crshpc: ds.l 1 *Crash area: PC3693 _crshsp: ds.l 1 *Crash area: SP3694 _crshus: ds.l 1 *Crash area: USP3695 _crshvc: ds.l 1 *Crash area: vector # in MS byte3696 _crshrg: ds.l 16 *Crash area: registers3697 _crshst: ds.w 16 *Crash area: top 16 words of stack3698 * 3699 *The area from biosram to SSTACK-1 is cleared on reset.3700 *------------------------------------------------------3701 biosram .equ * *Start of BIOS RAM variables3702 * 3668 3669 | RAM data area 3670 | ------------- 3671 | WARNING: 3672 | -------- 3673 | The variables from timevec through rsarea are permanently assigned so 3674 | that we can link to certain bios variables without having to link to the 3675 | bios object file itself. Some of these get defined in hwdefs.s and in 3676 | hwdefs.s so beware of changing them. 3677 3678 timevec: ds.l 1 | System timer trap vector 3679 critvec: ds.l 1 | Critical error handler vector 3680 termvec: ds.l 1 | Process terminate hook vector 3681 resvec3: ds.l 1 | Reserved vector 3 3682 resvec4: ds.l 1 | Reserved vector 4 3683 resvec5: ds.l 1 | Reserved vector 5 3684 resvec6: ds.l 1 | Reserved vector 6 3685 resvec7: ds.l 1 | Reserved vector 7 3686 3687 fc_sw: ds.w 1 | Frame clock switch (<0=dn, 0=off, >0=up) 3688 fc_val: ds.l 1 | Frame clock value (0..FCMAX) 3689 3690 _wzcrsh: ds.w 1 | Crash area: flag for ROMP 3691 _crshsr: ds.w 1 | Crash area: SR 3692 _crshpc: ds.l 1 | Crash area: PC 3693 _crshsp: ds.l 1 | Crash area: SP 3694 _crshus: ds.l 1 | Crash area: USP 3695 _crshvc: ds.l 1 | Crash area: vector # in MS byte 3696 _crshrg: ds.l 16 | Crash area: registers 3697 _crshst: ds.w 16 | Crash area: top 16 words of stack 3698 3699 | The area from biosram to SSTACK-1 is cleared on reset. 3700 | ------------------------------------------------------ 3701 biosram: | Start of BIOS RAM variables 3702 3703 3703 .ifne BUCHLA 3704 * 3705 _hz_1k: ds.l 1 *1000 Hz clock3706 _hz_200: ds.l 1 *200 Hz clock3707 frclock: ds.l 1 *50 Hz clock3708 t1count: ds.w 1 *Timer 1 count3709 t2count: ds.w 1 *Timer 2 count3710 t3count: ds.w 1 *Timer 3 count3711 * 3712 seekrate: ds.w 1 *Seek rate3713 cdev: ds.w 1 *Current drive3714 ctrack: ds.w 1 *Current track3715 csect: ds.w 1 *Current sector3716 cside: ds.w 1 *Current side3717 ccount: ds.w 1 *Current sector count3718 spt: ds.w 1 *Sectors per track3719 interlv: ds.w 1 *Sector interleave count3720 virgin: ds.w 1 *Initial formatting data3721 deferr: ds.w 1 *Default error number3722 curerr: ds.w 1 *Current error number3723 * 3724 cdma: ds.l 1 *Current DMA address3725 edma: ds.l 1 *Ending DMA address3726 tmpdma: ds.l 1 *Temporary DMA address3727 * 3728 .endc 3729 * 3730 rseed: ds.l 1 *Random number seed3731 * 3732 savptr: ds.l 1 *Pointer to register save area3733 * 3734 _rsflag: ds.l 1 *Register save area overflow flag3735 ds.l 18 *32 *Register save area (32 levels)3736 rsarea: ds.l 1 *Dummy long word at top of save area3737 * 3738 * ***** end of the permanently assigned bios variables ***** 3739 * 3740 .page 3741 * 3704 3705 _hz_1k: ds.l 1 | 1000 Hz clock 3706 _hz_200: ds.l 1 | 200 Hz clock 3707 frclock: ds.l 1 | 50 Hz clock 3708 t1count: ds.w 1 | Timer 1 count 3709 t2count: ds.w 1 | Timer 2 count 3710 t3count: ds.w 1 | Timer 3 count 3711 3712 seekrate: ds.w 1 | Seek rate 3713 cdev: ds.w 1 | Current drive 3714 ctrack: ds.w 1 | Current track 3715 csect: ds.w 1 | Current sector 3716 cside: ds.w 1 | Current side 3717 ccount: ds.w 1 | Current sector count 3718 spt: ds.w 1 | Sectors per track 3719 interlv: ds.w 1 | Sector interleave count 3720 virgin: ds.w 1 | Initial formatting data 3721 deferr: ds.w 1 | Default error number 3722 curerr: ds.w 1 | Current error number 3723 3724 cdma: ds.l 1 | Current DMA address 3725 edma: ds.l 1 | Ending DMA address 3726 tmpdma: ds.l 1 | Temporary DMA address 3727 3728 .endc 3729 3730 rseed: ds.l 1 | Random number seed 3731 3732 savptr: ds.l 1 | Pointer to register save area 3733 3734 _rsflag: ds.l 1 | Register save area overflow flag 3735 ds.l 18|32 | Register save area (32 levels) 3736 rsarea: ds.l 1 | Dummy long word at top of save area 3737 3738 | ||||| end of the permanently assigned bios variables ||||| 3739 3740 .page 3741 3742 3742 .ifne BUCHLA 3743 * 3744 acctim: ds.l 2 *Accumulated disk time table3745 maxactim: ds.l 1 *Maximum acctim value3746 hdv_init: ds.l 1 *Disk init vector3747 hdv_bpb: ds.l 1 *Disk get bpb vector3748 hdv_rw: ds.l 1 *Disk r/w vector3749 hdv_boot: ds.l 1 *Disk boot vector3750 hdv_mchg: ds.l 1 *Disk media change vector3751 drvbits: ds.l 1 *Drive map bits3752 dskbufp: ds.l 1 *Disk buffer pointer3753 .page 3754 nflops: ds.w 1 *Number of drives3755 disknum: ds.w 1 *Current disk number3756 booted: ds.w 1 *Most recent boot device or -13757 flock: ds.w 1 *Floppy semaphore3758 fverify: ds.w 1 *Floppy verify flag3759 * 3760 tdiv1: ds.w 1 *Timer divider 1 (divides _hz_1k)3761 tdiv2: ds.w 1 *Timer divider 2 (divides _hz_200)3762 * 3763 retrycnt: ds.w 1 *Re-try count3764 wpstatus: ds.w 1 *Write protect status table3765 wplatch: ds.w 1 *Write protect latch table3766 bootdev: ds.w 1 *Boot device number3767 * 3768 motoron: ds.w 1 *Motor-on flag3769 deslflag: ds.w 1 *Drive deselect flag3770 * 3771 .endc 3772 * 3773 flpsrsv: ds.w 1 *Status register save area3774 flpregs: ds.l 16 *Register save area3775 * 3743 3744 acctim: ds.l 2 | Accumulated disk time table 3745 maxactim: ds.l 1 | Maximum acctim value 3746 hdv_init: ds.l 1 | Disk init vector 3747 hdv_bpb: ds.l 1 | Disk get bpb vector 3748 hdv_rw: ds.l 1 | Disk r/w vector 3749 hdv_boot: ds.l 1 | Disk boot vector 3750 hdv_mchg: ds.l 1 | Disk media change vector 3751 drvbits: ds.l 1 | Drive map bits 3752 dskbufp: ds.l 1 | Disk buffer pointer 3753 .page 3754 nflops: ds.w 1 | Number of drives 3755 disknum: ds.w 1 | Current disk number 3756 booted: ds.w 1 | Most recent boot device or -1 3757 flock: ds.w 1 | Floppy semaphore 3758 fverify: ds.w 1 | Floppy verify flag 3759 3760 tdiv1: ds.w 1 | Timer divider 1 (divides _hz_1k) 3761 tdiv2: ds.w 1 | Timer divider 2 (divides _hz_200) 3762 3763 retrycnt: ds.w 1 | Re-try count 3764 wpstatus: ds.w 1 | Write protect status table 3765 wplatch: ds.w 1 | Write protect latch table 3766 bootdev: ds.w 1 | Boot device number 3767 3768 motoron: ds.w 1 | Motor-on flag 3769 deslflag: ds.w 1 | Drive deselect flag 3770 3771 .endc 3772 3773 flpsrsv: ds.w 1 | Status register save area 3774 flpregs: ds.l 16 | Register save area 3775 3776 3776 .ifne BUCHLA 3777 * 3778 dsb0: ds.l 1 *Drive A DSB3779 dsb1: ds.l 1 *Drive B DSB3780 * 3781 dskmode: ds.b 2 *Disk change mode table3782 dskerrs: ds.w 2 *Disk error code table3783 drvbpbs: ds.w 16 *2 *Disk BPB save area3784 * 3785 .endc 3786 * 3787 .page 3788 * 3789 sr1iorec: ds.b IORECLN *Serial-1 iorec structure3790 sr2iorec: ds.b IORECLN *Serial-2 iorec structure3791 * 3777 3778 dsb0: ds.l 1 | Drive A DSB 3779 dsb1: ds.l 1 | Drive B DSB 3780 3781 dskmode: ds.b 2 | Disk change mode table 3782 dskerrs: ds.w 2 | Disk error code table 3783 drvbpbs: ds.w 16|2 | Disk BPB save area 3784 3785 .endc 3786 3787 .page 3788 3789 sr1iorec: ds.b IORECLN | Serial-1 iorec structure 3790 sr2iorec: ds.b IORECLN | Serial-2 iorec structure 3791 3792 3792 .ifne BUCHLA 3793 * 3794 mc1iorec: ds.b IORECLN *MIDI-1 iorec structure3795 mc2iorec: ds.b IORECLN *MIDI-2 iorec structure3796 * 3797 .endc 3798 * 3799 sr1ibuf: ds.b SR1IBS *Serial-1 input buffer3800 sr1obuf: ds.b SR1OBS *Serial-1 output buffer3801 sr2ibuf: ds.b SR2IBS *Serial-2 input buffer3802 sr2obuf: ds.b SR2OBS *Serial-2 output buffer3803 * 3793 3794 mc1iorec: ds.b IORECLN | MIDI-1 iorec structure 3795 mc2iorec: ds.b IORECLN | MIDI-2 iorec structure 3796 3797 .endc 3798 3799 sr1ibuf: ds.b SR1IBS | Serial-1 input buffer 3800 sr1obuf: ds.b SR1OBS | Serial-1 output buffer 3801 sr2ibuf: ds.b SR2IBS | Serial-2 input buffer 3802 sr2obuf: ds.b SR2OBS | Serial-2 output buffer 3803 3804 3804 .ifne BUCHLA 3805 * 3806 mc1ibuf: ds.b MC1IBS *MIDI-1 input buffer3807 mc1obuf: ds.b MC1OBS *MIDI-1 output buffer3808 mc2ibuf: ds.b MC2IBS *MIDI-2 input buffer3809 mc2obuf: ds.b MC2OBS *MIDI-2 output buffer3810 * 3811 api_inp: ds.b 1 *Analog processor input byte3812 api_bug: ds.b 1 *Analog processor signal # "bug trap"3813 api_sv: ds.b 1 *Analog processor state3814 api_svb: ds.b 1 *Analog processor state "bug trap"3815 * 3805 3806 mc1ibuf: ds.b MC1IBS | MIDI-1 input buffer 3807 mc1obuf: ds.b MC1OBS | MIDI-1 output buffer 3808 mc2ibuf: ds.b MC2IBS | MIDI-2 input buffer 3809 mc2obuf: ds.b MC2OBS | MIDI-2 output buffer 3810 3811 api_inp: ds.b 1 | Analog processor input byte 3812 api_bug: ds.b 1 | Analog processor signal # "bug trap" 3813 api_sv: ds.b 1 | Analog processor state 3814 api_svb: ds.b 1 | Analog processor state "bug trap" 3815 3816 3816 .even 3817 * 3818 api_sig: ds.b 1 *Analog signal number3819 api_val: ds.b 1 *Analog value3820 * 3821 api_fi: ds.l 1 *Analog processor FIFO input pointer3822 api_fo: ds.l 1 *Analog processor FIFO output pointer3823 api_fum: ds.w APISIZE *Analog processor FIFO3824 api_fe .equ * *End of analog processor FIFO3825 * 3826 .endc 3827 * 3817 3818 api_sig: ds.b 1 | Analog signal number 3819 api_val: ds.b 1 | Analog value 3820 3821 api_fi: ds.l 1 | Analog processor FIFO input pointer 3822 api_fo: ds.l 1 | Analog processor FIFO output pointer 3823 api_fum: ds.w APISIZE | Analog processor FIFO 3824 api_fe: | End of analog processor FIFO 3825 3826 .endc 3827 3828 3828 .even 3829 * 3830 basepage: ds.l 64 *Pseudo base page3831 * 3832 buffer: ds.b 1024 *Default disk buffer3833 * 3834 biostop .equ * *End of BIOS RAM3835 * 3829 3830 basepage: ds.l 64 | Pseudo base page 3831 3832 buffer: ds.b 1024 | Default disk buffer 3833 3834 biostop: | End of BIOS RAM 3835 3836 3836 .end -
rom/timeint.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *timeint.s -- timer interrupt handler3 *Version 9 -- 1988-06-20 -- D.N. Lynx Crowe4 *------------------------------------------------------------------------------5 * 6 *This code replaces the interrupt handler in bios.s, which is known to7 *have a bug in it, and adds support for the VSDD and an array of programable8 *timers with 1 Ms resolution.9 * 10 *WARNING: There are equates to addresses in the bios EPROM which may change11 *when the bios is reassembled. If the bios is reassembled be sure to update12 *the equates flagged by "<<<=====".13 * 14 *The addresses currently in the equates are for EPROMs dated 1988-04-18 or15 *1988-06-20 ONLY.16 * 17 *------------------------------------------------------------------------------18 *Hardware timer usage:19 *---------------------20 *Timer 1 PLL divider for score clock -- fixed at 6421 *Timer 2 PLL divider for score clock -- nominally 320022 *Timer 3 1 Ms Real Time Clock23 * 24 *------------------------------------------------------------------------------25 * 1 | ------------------------------------------------------------------------------ 2 | timeint.s -- timer interrupt handler 3 | Version 9 -- 1988-06-20 -- D.N. Lynx Crowe 4 | ------------------------------------------------------------------------------ 5 6 | This code replaces the interrupt handler in bios.s, which is known to 7 | have a bug in it, and adds support for the VSDD and an array of programable 8 | timers with 1 Ms resolution. 9 10 | WARNING: There are equates to addresses in the bios EPROM which may change 11 | when the bios is reassembled. If the bios is reassembled be sure to update 12 | the equates flagged by "<<<=====". 13 14 | The addresses currently in the equates are for EPROMs dated 1988-04-18 or 15 | 1988-06-20 ONLY. 16 17 | ------------------------------------------------------------------------------ 18 | Hardware timer usage: 19 | --------------------- 20 | Timer 1 PLL divider for score clock -- fixed at 64 21 | Timer 2 PLL divider for score clock -- nominally 3200 22 | Timer 3 1 Ms Real Time Clock 23 24 | ------------------------------------------------------------------------------ 25 26 26 .text 27 * 28 .xdef _tsetup *tsetup() -- timer setup function29 .xdef timeint *timer interrupt handler30 * 31 .xdef _timers *timer array -- short timers[NTIMERS]32 .xdef _vi_clk *VSDD scroll delay timer33 .xdef _vi_tag *VSDD VI tag34 .xdef line *Line we entered on35 * 36 .xref lclsadr *score object base address37 .xref lclscrl *score object scroll offset38 .xref _v_odtab *VSDD object descriptor table39 .xref _v_regs *VSDD registers40 * 41 .page 42 *==============================================================================43 * 44 *Equates to variables in bios.s:45 *-------------------------------46 *These variables are permanently assigned.47 * 48 TIMEVEC .equ $00000400 *LONG - System timer trap vector49 * 50 FC_SW .equ $00000420 *WORD - Frame clock switch51 FC_VAL .equ $00000422 *LONG - Frame clock value52 * 53 HZ_1K .equ $0000049A *LONG - 1000 Hz clock54 HZ_200 .equ $0000049E *LONG - 200 Hz clock55 FRCLOCK .equ $000004A2 *LONG - 50 Hz clock56 * 57 T3COUNT .equ $000004AA *WORD - Timer 3 count58 * 59 *------------------------------------------------------------------------------60 * 61 *WARNING: The address of "FLOCK" depends on the version of the bios EPROM.62 *The address below is for EPROMs dated 1988-04-18 ONLY.63 * 64 FLOCK .equ $00000E0C *WORD - Floppy semaphore <<<=====65 * 66 *==============================================================================67 * 68 *Equates to routines in bios.s:69 *------------------------------70 * 71 *WARNING: The address of "FLOPVBL" depends on the version of the bios EPROM.72 *The address below is for EPROMs dated 1988-04-18 ONLY.73 * 74 FLOPVBL .equ $001015EE *floppy VI handler address <<<=====75 * 76 *==============================================================================77 * 78 .page 79 * 80 *Hardware address equates:81 *-------------------------82 TI_VEC .equ $00000070 *Timer interrupt autovector83 * 84 TIMER .equ $003A0001 *Timer base address85 * 86 *------------------------------------------------------------------------------87 * 88 *Timer register equates:89 *-----------------------90 TIME_CRX .equ TIMER *Control register 1 or 391 TIME_CR2 .equ TIMER+2 *Control register 292 TIME_T1H .equ TIMER+4 *Timer 1 high byte93 TIME_T1L .equ TIMER+6 *Timer 1 low byte94 TIME_T2H .equ TIMER+8 *Timer 2 high byte95 TIME_T2L .equ TIMER+10 *Timer 2 low byte96 TIME_T3H .equ TIMER+12 *Timer 3 high byte97 TIME_T3L .equ TIMER+14 *Timer 3 low byte98 * 99 *VSDD register offsets:100 *----------------------101 VSDD_R5 .equ 10 *VSDD bank control register102 VSDD_R11 .equ 22 *VSDD access table register103 * 104 *==============================================================================105 * 106 *Miscellaneous equates:107 *----------------------108 IPL7 .equ $0700 *IPL mask for interrupt disable109 * 110 FCMAX .equ $00FFFFFF *Maximum frame counter value111 FCMIN .equ $00000000 *Minimum frame counter value112 * 113 NTIMERS .equ 8 *Number of timers in the timer array114 * 115 *==============================================================================116 * 117 .page 118 *==============================================================================119 *_tsetup -- tsetup() -- timer setup function120 *==============================================================================121 * 122 _tsetup: move.w sr,-(a7) *Save old interrupt mask123 ori.w #IPL7,sr *Disable interrupts124 * 125 clr.w FC_SW *Stop the frame clock126 clr.l FC_VAL *... and reset it127 clr.w _vi_tag *Clear VSDD VI tag128 clr.w _vi_clk *Clear VSDD delay timer129 clr.w lclsadr *Clear score scroll address130 clr.w lclscrl *Clear score scroll offset131 * 132 lea _timers,a0 *Point at timer array133 move.w #NTIMERS-1,d0 *Setup to clear timer array134 * 135 tclr: clr.w (a0)+ *Clear a timer array entry136 dbra d0,tclr *Loop until done137 * 138 move.l #nullrts,TIMEVEC *Set timer interrupt vector139 move.l #timeint,TI_VEC *Set timer trap vector140 * 141 move.b # $00,TIME_T1H *Setup timer 1 (PLL)142 move.b # $1F,TIME_T1L *... for divide by 64143 move.b # $0C,TIME_T2H *Setup timer 2 (FC)144 move.b # $7F,TIME_T2L *... for divide by 3200145 move.b # $03,TIME_T3H *Setup timer 3 (RTC)146 move.b # $20,TIME_T3L *... for 1Ms interval147 move.b # $42,TIME_CRX *Setup CR3148 move.b # $41,TIME_CR2 *Setup CR2149 move.b # $81,TIME_CRX *Setup CR1150 move.b # $80,TIME_CRX *Start the timers151 * 152 move.w (a7)+,sr *Restore interrupts153 * 154 nullrts: rts *Return to caller155 * 156 .page 157 *==============================================================================158 *timeint -- timer interrupt handler159 *==============================================================================160 * 161 timeint: movem.l d0-d7/a0-a6,-(a7) *Save registers162 move.b TIME_CR2,d0 *Get timer interrupt status163 *------------------------------------------------------------------------------164 *process 1 MS timer165 *------------------------------------------------------------------------------166 btst.l #2,d0 *Check timer 3 status167 beq tmi02 *Jump if not active168 * 169 move.b TIME_T3H,d1 *Read timer 3 count170 lsl.w #8,d1 *...171 move.b TIME_T3L,d1 *...172 move.w d1,T3COUNT *... and save it173 * 174 addq.l #1,HZ_1K *Update 1ms clock (1 KHz)175 * 176 move.l d0,-(a7) *Preserve D0177 *------------------------------------------------------------------------------178 *process VSDD timer179 *------------------------------------------------------------------------------180 tst.w _vi_tag *Does the VSDD need service ?181 beq updtime *Jump if not182 * 183 move.w _vi_clk,d0 *Get VSDD scroll delay timer184 subq.w #1,d0 *Decrement timer185 move.w d0,_vi_clk *Update timer186 bne updtime *Jump if it's not zero yet187 * 188 move.w lclsadr,_v_odtab+12 *Update scroll address189 move.w lclscrl,_v_odtab+10 *Update scroll offset190 clr.w _vi_tag *Reset the tag191 * 192 .page 193 * 194 *------------------------------------------------------------------------------195 *process programable timers196 *------------------------------------------------------------------------------197 * 198 updtime: move.w #NTIMERS-1,d0 *Setup timer array counter199 lea _timers,a0 *Point at timer array200 * 201 tdcr: move.w (a0),d1 *Get timer array entry202 beq tdcr1 *Jump if already 0203 * 204 subq.w #1,d1 *Decrement timer205 * 206 tdcr1: move.w d1,(a0)+ *Store updated timer value207 dbra d0,tdcr *Loop until done208 * 209 *------------------------------------------------------------------------------210 *process timer hook vector211 *------------------------------------------------------------------------------212 movea.l TIMEVEC,a0 *Get RTC vector213 move.w #1,-(a7) *Pass 1 msec on stack214 jsr (a0) *Process RTC vector215 addq.l #2,a7 *Clean up stack216 * 217 move.l (a7)+,d0 *Restore D0218 * 219 .page 220 *------------------------------------------------------------------------------221 *process 5 Ms clock222 *------------------------------------------------------------------------------223 move.w tdiv1,d1 *Update divider224 addq.w #1,d1 *...225 move.w d1,tdiv1 *...226 * 227 cmpi.w #5,d1 *Do we need to update HZ_200 ?228 blt tmi02 *Jump if not229 * 230 addq.l #1,HZ_200 *Update 5ms clock (200 Hz)231 *------------------------------------------------------------------------------232 *process 20 Ms floppy clock233 *------------------------------------------------------------------------------234 move.w tdiv2,d1 *Update divider235 addq.w #1,d1 *...236 move.w d1,tdiv2 *...237 * 238 cmpi.w #4,d1 *Do we need to update FRCLOCK ?239 blt tmi01 *Jump if not240 * 241 addq.l #1,FRCLOCK *Update 20 Ms clock (50 Hz)242 tst.w FLOCK *See if floppy is active243 bne tmi00 *Don't call FLOPVBL if so244 * 245 jsr FLOPVBL *Check on the floppy246 * 247 tmi00: move.w #0,tdiv2 *Reset tdiv2248 * 249 tmi01: move.w #0,tdiv1 *Reset tdiv1250 * 251 .page 252 *------------------------------------------------------------------------------253 *process PLL timers254 *------------------------------------------------------------------------------255 * 256 tmi02: btst.l #0,d0 *Check timer 1 int257 beq tmi03 *Jump if not set258 * 259 move.b TIME_T1H,d1 *Read timer 1 to clear int.260 move.b TIME_T1L,d1 *...261 * 262 tmi03: btst.l #1,d0 *Check for timer 2 int.263 beq tmi04 *Jump if not set264 * 265 move.b TIME_T2H,d1 *Read timer 2 to clear int.266 move.b TIME_T2L,d1 *...267 * 268 .page 269 *------------------------------------------------------------------------------270 *update score frame counter271 *------------------------------------------------------------------------------272 tst.w FC_SW *Should we update the frame ?273 beq tmi04 *Jump if not274 * 275 bmi tmi05 *Jump if we count down276 * 277 move.l FC_VAL,d0 *Get the frame count278 cmp.l #FCMAX,d0 *See it we've topped out279 bge tmi06 *Jump if limit was hit280 * 281 addq.l #1,d0 *Count up 1 frame282 move.l d0,FC_VAL *Store updated frame count283 bra tmi04 *Done284 * 285 tmi07: move.l #FCMIN,FC_VAL *Force hard limit, just in case286 bra tmi04 *Done287 * 288 tmi06: move.l #FCMAX,FC_VAL *Force hard limit, just in case289 bra tmi04 *Done290 * 291 tmi05: move.l FC_VAL,d0 *Get the frame count292 ble tmi07 *Done if already counted down293 * 294 subq.l #1,d0 *Count down 1 frame295 move.l d0,FC_VAL *Store udpated frame count296 bra tmi04 *Done297 * 298 nop *Filler to force equal paths299 * 300 tmi04: movem.l (a7)+,d0-d7/a0-a6 *Restore registers301 rte *Return to interrupted code302 * 303 .page 304 *==============================================================================27 28 .xdef _tsetup | tsetup() -- timer setup function 29 .xdef timeint | timer interrupt handler 30 31 .xdef _timers | timer array -- short timers[NTIMERS] 32 .xdef _vi_clk | VSDD scroll delay timer 33 .xdef _vi_tag | VSDD VI tag 34 .xdef line | Line we entered on 35 36 .xref lclsadr | score object base address 37 .xref lclscrl | score object scroll offset 38 .xref _v_odtab | VSDD object descriptor table 39 .xref _v_regs | VSDD registers 40 41 .page 42 | ============================================================================== 43 44 | Equates to variables in bios.s: 45 | ------------------------------- 46 | These variables are permanently assigned. 47 48 TIMEVEC = 0x00000400 | LONG - System timer trap vector 49 50 FC_SW = 0x00000420 | WORD - Frame clock switch 51 FC_VAL = 0x00000422 | LONG - Frame clock value 52 53 HZ_1K = 0x0000049A | LONG - 1000 Hz clock 54 HZ_200 = 0x0000049E | LONG - 200 Hz clock 55 FRCLOCK = 0x000004A2 | LONG - 50 Hz clock 56 57 T3COUNT = 0x000004AA | WORD - Timer 3 count 58 59 | ------------------------------------------------------------------------------ 60 61 | WARNING: The address of "FLOCK" depends on the version of the bios EPROM. 62 | The address below is for EPROMs dated 1988-04-18 ONLY. 63 64 FLOCK = 0x00000E0C | WORD - Floppy semaphore <<<===== 65 66 | ============================================================================== 67 68 | Equates to routines in bios.s: 69 | ------------------------------ 70 71 | WARNING: The address of "FLOPVBL" depends on the version of the bios EPROM. 72 | The address below is for EPROMs dated 1988-04-18 ONLY. 73 74 FLOPVBL = 0x001015EE | floppy VI handler address <<<===== 75 76 | ============================================================================== 77 78 .page 79 80 | Hardware address equates: 81 | ------------------------- 82 TI_VEC = 0x00000070 | Timer interrupt autovector 83 84 TIMER = 0x003A0001 | Timer base address 85 86 | ------------------------------------------------------------------------------ 87 88 | Timer register equates: 89 | ----------------------- 90 TIME_CRX = TIMER | Control register 1 or 3 91 TIME_CR2 = TIMER+2 | Control register 2 92 TIME_T1H = TIMER+4 | Timer 1 high byte 93 TIME_T1L = TIMER+6 | Timer 1 low byte 94 TIME_T2H = TIMER+8 | Timer 2 high byte 95 TIME_T2L = TIMER+10 | Timer 2 low byte 96 TIME_T3H = TIMER+12 | Timer 3 high byte 97 TIME_T3L = TIMER+14 | Timer 3 low byte 98 99 | VSDD register offsets: 100 | ---------------------- 101 VSDD_R5 = 10 | VSDD bank control register 102 VSDD_R11 = 22 | VSDD access table register 103 104 | ============================================================================== 105 106 | Miscellaneous equates: 107 | ---------------------- 108 IPL7 = 0x0700 | IPL mask for interrupt disable 109 110 FCMAX = 0x00FFFFFF | Maximum frame counter value 111 FCMIN = 0x00000000 | Minimum frame counter value 112 113 NTIMERS = 8 | Number of timers in the timer array 114 115 | ============================================================================== 116 117 .page 118 | ============================================================================== 119 | _tsetup -- tsetup() -- timer setup function 120 | ============================================================================== 121 122 _tsetup: move.w sr,-(a7) | Save old interrupt mask 123 ori.w #IPL7,sr | Disable interrupts 124 125 clr.w FC_SW | Stop the frame clock 126 clr.l FC_VAL | ... and reset it 127 clr.w _vi_tag | Clear VSDD VI tag 128 clr.w _vi_clk | Clear VSDD delay timer 129 clr.w lclsadr | Clear score scroll address 130 clr.w lclscrl | Clear score scroll offset 131 132 lea _timers,a0 | Point at timer array 133 move.w #NTIMERS-1,d0 | Setup to clear timer array 134 135 tclr: clr.w (a0)+ | Clear a timer array entry 136 dbra d0,tclr | Loop until done 137 138 move.l #nullrts,TIMEVEC | Set timer interrupt vector 139 move.l #timeint,TI_VEC | Set timer trap vector 140 141 move.b #0x00,TIME_T1H | Setup timer 1 (PLL) 142 move.b #0x1F,TIME_T1L | ... for divide by 64 143 move.b #0x0C,TIME_T2H | Setup timer 2 (FC) 144 move.b #0x7F,TIME_T2L | ... for divide by 3200 145 move.b #0x03,TIME_T3H | Setup timer 3 (RTC) 146 move.b #0x20,TIME_T3L | ... for 1Ms interval 147 move.b #0x42,TIME_CRX | Setup CR3 148 move.b #0x41,TIME_CR2 | Setup CR2 149 move.b #0x81,TIME_CRX | Setup CR1 150 move.b #0x80,TIME_CRX | Start the timers 151 152 move.w (a7)+,sr | Restore interrupts 153 154 nullrts: rts | Return to caller 155 156 .page 157 | ============================================================================== 158 | timeint -- timer interrupt handler 159 | ============================================================================== 160 161 timeint: movem.l d0-d7/a0-a6,-(a7) | Save registers 162 move.b TIME_CR2,d0 | Get timer interrupt status 163 | ------------------------------------------------------------------------------ 164 | process 1 MS timer 165 | ------------------------------------------------------------------------------ 166 btst.l #2,d0 | Check timer 3 status 167 beq tmi02 | Jump if not active 168 169 move.b TIME_T3H,d1 | Read timer 3 count 170 lsl.w #8,d1 | ... 171 move.b TIME_T3L,d1 | ... 172 move.w d1,T3COUNT | ... and save it 173 174 addq.l #1,HZ_1K | Update 1ms clock (1 KHz) 175 176 move.l d0,-(a7) | Preserve D0 177 | ------------------------------------------------------------------------------ 178 | process VSDD timer 179 | ------------------------------------------------------------------------------ 180 tst.w _vi_tag | Does the VSDD need service ? 181 beq updtime | Jump if not 182 183 move.w _vi_clk,d0 | Get VSDD scroll delay timer 184 subq.w #1,d0 | Decrement timer 185 move.w d0,_vi_clk | Update timer 186 bne updtime | Jump if it's not zero yet 187 188 move.w lclsadr,_v_odtab+12 | Update scroll address 189 move.w lclscrl,_v_odtab+10 | Update scroll offset 190 clr.w _vi_tag | Reset the tag 191 192 .page 193 194 | ------------------------------------------------------------------------------ 195 | process programable timers 196 | ------------------------------------------------------------------------------ 197 198 updtime: move.w #NTIMERS-1,d0 | Setup timer array counter 199 lea _timers,a0 | Point at timer array 200 201 tdcr: move.w (a0),d1 | Get timer array entry 202 beq tdcr1 | Jump if already 0 203 204 subq.w #1,d1 | Decrement timer 205 206 tdcr1: move.w d1,(a0)+ | Store updated timer value 207 dbra d0,tdcr | Loop until done 208 209 | ------------------------------------------------------------------------------ 210 | process timer hook vector 211 | ------------------------------------------------------------------------------ 212 movea.l TIMEVEC,a0 | Get RTC vector 213 move.w #1,-(a7) | Pass 1 msec on stack 214 jsr (a0) | Process RTC vector 215 addq.l #2,a7 | Clean up stack 216 217 move.l (a7)+,d0 | Restore D0 218 219 .page 220 | ------------------------------------------------------------------------------ 221 | process 5 Ms clock 222 | ------------------------------------------------------------------------------ 223 move.w tdiv1,d1 | Update divider 224 addq.w #1,d1 | ... 225 move.w d1,tdiv1 | ... 226 227 cmpi.w #5,d1 | Do we need to update HZ_200 ? 228 blt tmi02 | Jump if not 229 230 addq.l #1,HZ_200 | Update 5ms clock (200 Hz) 231 | ------------------------------------------------------------------------------ 232 | process 20 Ms floppy clock 233 | ------------------------------------------------------------------------------ 234 move.w tdiv2,d1 | Update divider 235 addq.w #1,d1 | ... 236 move.w d1,tdiv2 | ... 237 238 cmpi.w #4,d1 | Do we need to update FRCLOCK ? 239 blt tmi01 | Jump if not 240 241 addq.l #1,FRCLOCK | Update 20 Ms clock (50 Hz) 242 tst.w FLOCK | See if floppy is active 243 bne tmi00 | Don't call FLOPVBL if so 244 245 jsr FLOPVBL | Check on the floppy 246 247 tmi00: move.w #0,tdiv2 | Reset tdiv2 248 249 tmi01: move.w #0,tdiv1 | Reset tdiv1 250 251 .page 252 | ------------------------------------------------------------------------------ 253 | process PLL timers 254 | ------------------------------------------------------------------------------ 255 256 tmi02: btst.l #0,d0 | Check timer 1 int 257 beq tmi03 | Jump if not set 258 259 move.b TIME_T1H,d1 | Read timer 1 to clear int. 260 move.b TIME_T1L,d1 | ... 261 262 tmi03: btst.l #1,d0 | Check for timer 2 int. 263 beq tmi04 | Jump if not set 264 265 move.b TIME_T2H,d1 | Read timer 2 to clear int. 266 move.b TIME_T2L,d1 | ... 267 268 .page 269 | ------------------------------------------------------------------------------ 270 | update score frame counter 271 | ------------------------------------------------------------------------------ 272 tst.w FC_SW | Should we update the frame ? 273 beq tmi04 | Jump if not 274 275 bmi tmi05 | Jump if we count down 276 277 move.l FC_VAL,d0 | Get the frame count 278 cmp.l #FCMAX,d0 | See it we've topped out 279 bge tmi06 | Jump if limit was hit 280 281 addq.l #1,d0 | Count up 1 frame 282 move.l d0,FC_VAL | Store updated frame count 283 bra tmi04 | Done 284 285 tmi07: move.l #FCMIN,FC_VAL | Force hard limit, just in case 286 bra tmi04 | Done 287 288 tmi06: move.l #FCMAX,FC_VAL | Force hard limit, just in case 289 bra tmi04 | Done 290 291 tmi05: move.l FC_VAL,d0 | Get the frame count 292 ble tmi07 | Done if already counted down 293 294 subq.l #1,d0 | Count down 1 frame 295 move.l d0,FC_VAL | Store udpated frame count 296 bra tmi04 | Done 297 298 nop | Filler to force equal paths 299 300 tmi04: movem.l (a7)+,d0-d7/a0-a6 | Restore registers 301 rte | Return to interrupted code 302 303 .page 304 | ============================================================================== 305 305 .bss 306 *==============================================================================307 * 308 *A note on tdiv1 and tdiv2:309 *--------------------------310 * 311 *tdiv1 and tdiv2 are actually defined in the bios, but since they could move312 *we define them here and ignore the ones in the bios.313 * 314 tdiv1: ds.w 1 *Timer divider 1 (divides HZ_1K)315 tdiv2: ds.w 1 *Timer divider 2 (divides HZ_200)316 * 317 *------------------------------------------------------------------------------318 * 319 _timers: ds.w NTIMERS *Timer array -- short timers[16];320 * 321 _vi_clk: ds.w 1 *VSDD scroll delay timer322 _vi_tag: ds.w 1 *VSDD VI 'needs service' tag323 * 324 bank: ds.w 1 *VSDD bank we enterd with325 line: ds.w 1 *Line we came in on (for analysis)326 *==============================================================================327 * 306 | ============================================================================== 307 308 | A note on tdiv1 and tdiv2: 309 | -------------------------- 310 311 | tdiv1 and tdiv2 are actually defined in the bios, but since they could move 312 | we define them here and ignore the ones in the bios. 313 314 tdiv1: ds.w 1 | Timer divider 1 (divides HZ_1K) 315 tdiv2: ds.w 1 | Timer divider 2 (divides HZ_200) 316 317 | ------------------------------------------------------------------------------ 318 319 _timers: ds.w NTIMERS | Timer array -- short timers[16]; 320 321 _vi_clk: ds.w 1 | VSDD scroll delay timer 322 _vi_tag: ds.w 1 | VSDD VI 'needs service' tag 323 324 bank: ds.w 1 | VSDD bank we enterd with 325 line: ds.w 1 | Line we came in on (for analysis) 326 | ============================================================================== 327 328 328 .end -
vlib/acctrl.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *acctrl.s -- VSDD access table control functions3 *Version 6 -- 1987-04-13 -- D.N. Lynx Crowe4 *(c) Copyright 1987 -- D.N. Lynx Crowe5 *------------------------------------------------------------------------------6 * 7 *objclr(obj)8 *unsigned int obj;9 * 10 *Clear bits in access table for object 'obj'.11 *Disables object 'obj'.12 * 13 *objoff(obj, line, num)14 *unsigned int obj, line, num;15 * 16 *Disable object obj at line thru line+num.17 * 18 *objon(obj, line, num)19 *unsigned int obj, line, num;20 * 21 *Enable object obj at line thru line+num.22 * 23 * 24 *Assumes VSDD is looking at bank 0.25 *Assumes a screen height of 350 lines.26 *No error checks are done, so beware.27 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | acctrl.s -- VSDD access table control functions 3 | Version 6 -- 1987-04-13 -- D.N. Lynx Crowe 4 | (c) Copyright 1987 -- D.N. Lynx Crowe 5 | ------------------------------------------------------------------------------ 6 7 | objclr(obj) 8 | unsigned int obj; 9 10 | Clear bits in access table for object 'obj'. 11 | Disables object 'obj'. 12 13 | objoff(obj, line, num) 14 | unsigned int obj, line, num; 15 16 | Disable object obj at line thru line+num. 17 18 | objon(obj, line, num) 19 | unsigned int obj, line, num; 20 21 | Enable object obj at line thru line+num. 22 23 24 | Assumes VSDD is looking at bank 0. 25 | Assumes a screen height of 350 lines. 26 | No error checks are done, so beware. 27 | ------------------------------------------------------------------------------ 28 28 .text 29 * 29 30 30 .xdef _objclr,_objoff,_objon 31 * 31 32 32 .xref _v_actab 33 * 34 SCSIZE .equ 350 *Screen height35 * 36 OBJ .equ 8 *Object number argument offset37 LINE .equ 10 *Beginning line argument offset38 NUM .equ 12 *Object height argument offset39 *------------------------------------------------------------------------------33 34 SCSIZE = 350 | Screen height 35 36 OBJ = 8 | Object number argument offset 37 LINE = 10 | Beginning line argument offset 38 NUM = 12 | Object height argument offset 39 | ------------------------------------------------------------------------------ 40 40 .page 41 *------------------------------------------------------------------------------42 * 43 *objclr(obj)44 *unsigned int obj;45 * 46 *Disables object obj in access table by turning on47 *its bit in all words of the access table.48 *------------------------------------------------------------------------------49 _objclr: link a6,#0 *Link stack frames50 move.w OBJ(a6),d1 *Get object bit number in d151 lea _v_actab,a0 *Get base of object table in a052 move.w #SCSIZE-1,d2 *Put line count in d253 * 54 objclr1: move.w (a0),d0 *Get access table word55 bset.l d1,d0 *Set the bit56 move.w d0,(a0)+ *Update word in access table57 dbf d2,objclr1 *Loop until done58 * 59 unlk a6 *Unlink stack frame60 rts *Return to caller61 * 41 | ------------------------------------------------------------------------------ 42 43 | objclr(obj) 44 | unsigned int obj; 45 46 | Disables object obj in access table by turning on 47 | its bit in all words of the access table. 48 | ------------------------------------------------------------------------------ 49 _objclr: link a6,#0 | Link stack frames 50 move.w OBJ(a6),d1 | Get object bit number in d1 51 lea _v_actab,a0 | Get base of object table in a0 52 move.w #SCSIZE-1,d2 | Put line count in d2 53 54 objclr1: move.w (a0),d0 | Get access table word 55 bset.l d1,d0 | Set the bit 56 move.w d0,(a0)+ | Update word in access table 57 dbf d2,objclr1 | Loop until done 58 59 unlk a6 | Unlink stack frame 60 rts | Return to caller 61 62 62 .page 63 *------------------------------------------------------------------------------64 *objoff(obj, line, num)65 *unsigned int obj, line, num;66 * 67 *Turn on access table bits for object 'obj' at68 *lines 'line' through 'line'+'num'. Disables the object.69 *Assumes object bits were set at those locations.70 *------------------------------------------------------------------------------71 _objoff: link a6,#0 *Link stack frames72 move.w OBJ(a6),d1 *Get object bit number into d173 move.w LINE(a6),d2 *Get top line number74 add.w d2,d2 *Convert to word offset75 lea _v_actab,a0 *Get base address of access table76 move.w 0(a0,d2),d0 *Get top line access word77 bset.l d1,d0 *Set object bit78 move.w d0,0(a0,d2) *Update word in access table79 tst.w NUM(a6) *Number of lines = 0 ?80 beq objoff1 *Done if so81 * 82 move.w NUM(a6),d2 *Get object depth83 add.w LINE(a6),d2 *Add to top line number84 cmpi.w #SCSIZE,d2 *Bottom line >= screen height ?85 bge objoff1 *Done if so86 * 87 add.w d2,d2 *Convert to word offset88 move.w 0(a0,d2),d0 *Get bottom line access word89 bset.l d1,d0 *Set object bit90 move.w d0,0(a0,d2) *Update word in access table91 * 92 objoff1: unlk a6 *Unlink stack frame93 rts *Return to caller94 * 63 | ------------------------------------------------------------------------------ 64 | objoff(obj, line, num) 65 | unsigned int obj, line, num; 66 67 | Turn on access table bits for object 'obj' at 68 | lines 'line' through 'line'+'num'. Disables the object. 69 | Assumes object bits were set at those locations. 70 | ------------------------------------------------------------------------------ 71 _objoff: link a6,#0 | Link stack frames 72 move.w OBJ(a6),d1 | Get object bit number into d1 73 move.w LINE(a6),d2 | Get top line number 74 add.w d2,d2 | Convert to word offset 75 lea _v_actab,a0 | Get base address of access table 76 move.w 0(a0,d2),d0 | Get top line access word 77 bset.l d1,d0 | Set object bit 78 move.w d0,0(a0,d2) | Update word in access table 79 tst.w NUM(a6) | Number of lines = 0 ? 80 beq objoff1 | Done if so 81 82 move.w NUM(a6),d2 | Get object depth 83 add.w LINE(a6),d2 | Add to top line number 84 cmpi.w #SCSIZE,d2 | Bottom line >= screen height ? 85 bge objoff1 | Done if so 86 87 add.w d2,d2 | Convert to word offset 88 move.w 0(a0,d2),d0 | Get bottom line access word 89 bset.l d1,d0 | Set object bit 90 move.w d0,0(a0,d2) | Update word in access table 91 92 objoff1: unlk a6 | Unlink stack frame 93 rts | Return to caller 94 95 95 .page 96 *------------------------------------------------------------------------------97 *objon(obj, line, num)98 *unsigned int obj, line, num;99 * 100 *Turn off access table bits for object 'obj'101 *at 'line' thru 'line'+'num'. Enables the object.102 *------------------------------------------------------------------------------103 _objon: link a6,#0 *Link stack frames104 move.w OBJ(a6),d1 *Get object bit number into d1105 move.w LINE(a6),d2 *Get top line number106 add.w d2,d2 *Convert to word offset107 lea _v_actab,a0 *Get base address of access table108 move.w 0(a0,d2),d0 *Get top line access word109 bclr.l d1,d0 *Clear object bit110 move.w d0,0(a0,d2) *Update word in access table111 tst.w NUM(a6) *Number of lines = 0 ?112 beq objon1 *Done if so113 * 114 move.w NUM(a6),d2 *Get object depth115 add.w LINE(a6),d2 *Add top line number116 cmpi.w #SCSIZE,d2 *Bottom line >= screen height ?117 bge objon1 *Done if so118 * 119 add.w d2,d2 *Convert to word offset120 move.w 0(a0,d2),d0 *Get bottom line access word121 bclr.l d1,d0 *Clear object bit122 move.w d0,0(a0,d2) *Update word in access table123 * 124 objon1: unlk a6 *Unlink stack frame125 rts *Return to caller126 * 96 | ------------------------------------------------------------------------------ 97 | objon(obj, line, num) 98 | unsigned int obj, line, num; 99 100 | Turn off access table bits for object 'obj' 101 | at 'line' thru 'line'+'num'. Enables the object. 102 | ------------------------------------------------------------------------------ 103 _objon: link a6,#0 | Link stack frames 104 move.w OBJ(a6),d1 | Get object bit number into d1 105 move.w LINE(a6),d2 | Get top line number 106 add.w d2,d2 | Convert to word offset 107 lea _v_actab,a0 | Get base address of access table 108 move.w 0(a0,d2),d0 | Get top line access word 109 bclr.l d1,d0 | Clear object bit 110 move.w d0,0(a0,d2) | Update word in access table 111 tst.w NUM(a6) | Number of lines = 0 ? 112 beq objon1 | Done if so 113 114 move.w NUM(a6),d2 | Get object depth 115 add.w LINE(a6),d2 | Add top line number 116 cmpi.w #SCSIZE,d2 | Bottom line >= screen height ? 117 bge objon1 | Done if so 118 119 add.w d2,d2 | Convert to word offset 120 move.w 0(a0,d2),d0 | Get bottom line access word 121 bclr.l d1,d0 | Clear object bit 122 move.w d0,0(a0,d2) | Update word in access table 123 124 objon1: unlk a6 | Unlink stack frame 125 rts | Return to caller 126 127 127 .end -
vlib/glcplot.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *glcplot.s -- plot a pixel on the LCD display3 *Version 2 -- 1987-04-23 -- D.N. Lynx Crowe4 *(c) Copyright 1987 -- D.N. Lynx Crowe5 * 6 *GLCplot(x, y, val)7 *unsigned x, y, val);8 * 9 *Plot a pixel at ('x', 'y') using lcdbase as the plane address10 *in GLC RAM. If 'val' is zero, the pixel is cleared,11 *otherwise the pixel is cleared. No error checking is done.12 *Limits: 0 LE x LE 511, 0 LE y LE 63.13 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | glcplot.s -- plot a pixel on the LCD display 3 | Version 2 -- 1987-04-23 -- D.N. Lynx Crowe 4 | (c) Copyright 1987 -- D.N. Lynx Crowe 5 6 | GLCplot(x, y, val) 7 | unsigned x, y, val); 8 9 | Plot a pixel at ('x', 'y') using lcdbase as the plane address 10 | in GLC RAM. If 'val' is zero, the pixel is cleared, 11 | otherwise the pixel is cleared. No error checking is done. 12 | Limits: 0 LE x LE 511, 0 LE y LE 63. 13 | ------------------------------------------------------------------------------ 14 14 .text 15 * 15 16 16 .xdef _GLCplot 17 17 .xref _lcd_a0,_lcd_a1,_lcdbase 18 * 19 XLOC .equ 8 *'x' parameter offset20 YLOC .equ 10 *'y' parameter offset21 VAL .equ 12 *'val' parameter offset22 * 23 G_CRSWR .equ $46 *GLC set cursor command24 G_MWRITE .equ $42 *GLC write command25 G_MREAD .equ $43 *GLC read command26 * 18 19 XLOC = 8 | 'x' parameter offset 20 YLOC = 10 | 'y' parameter offset 21 VAL = 12 | 'val' parameter offset 22 23 G_CRSWR = 0x46 | GLC set cursor command 24 G_MWRITE = 0x42 | GLC write command 25 G_MREAD = 0x43 | GLC read command 26 27 27 .page 28 * 29 _GLCplot: link a6,#0 *Link stack frames30 moveq #63,d0 * d0 = (63-y) *8531 sub.w YLOC(a6),d0 *...32 mulu #85,d0 *...33 clr.l d1 *d1 = x/634 move.w XLOC(a6),d1 *...35 divu #6,d1 *...36 add.w d1,d0 * d0 = (63-y)*85 + (x/6)37 swap d1 *d2 = 7 - (x%6) % 838 moveq #7,d2 *...39 sub.w d1,d2 *...40 andi.w #7,d2 *...41 lsr.w #3,d1 *d1 = (x%6) / 842 add.w d1,d0 *d0 = cursor address43 add.w _lcdbase,d0 *...44 move.w d0,d1 *d1 = cursor address, too45 move.b #G_CRSWR,_lcd_a1 *Send cursor address to GLC46 move.b d0,_lcd_a0 *...47 lsr.w #8,d0 *...48 move.b d0,_lcd_a0 *...49 move.b #G_MREAD,_lcd_a1 *Read old pixel byte50 move.b _lcd_a1,d0 *... into d051 tst.w VAL(a6) *Check val for zero52 beq glcplt1 *Jump if val EQ 053 * 54 bset d2,d0 *Set the pixel to 155 bra glcplt2 *Go write pixel to GLC56 * 57 glcplt1: bclr d2,d0 *Clear the pixel to 058 * 59 glcplt2: move.b #G_CRSWR,_lcd_a1 *Send cursor address to GLC60 move.b d1,_lcd_a0 *...61 lsr.w #8,d1 *...62 move.b d1,_lcd_a0 *...63 move.b #G_MWRITE,_lcd_a1 *Setup GLC to write pixel64 move.b d0,_lcd_a0 *Write pixel65 unlk a6 *Unlink stack frames66 rts *Return to caller67 * 28 29 _GLCplot: link a6,#0 | Link stack frames 30 moveq #63,d0 | d0 = (63-y) | 85 31 sub.w YLOC(a6),d0 | ... 32 mulu #85,d0 | ... 33 clr.l d1 | d1 = x/6 34 move.w XLOC(a6),d1 | ... 35 divu #6,d1 | ... 36 add.w d1,d0 | d0 = (63-y)|85 + (x/6) 37 swap d1 | d2 = 7 - (x%6) % 8 38 moveq #7,d2 | ... 39 sub.w d1,d2 | ... 40 andi.w #7,d2 | ... 41 lsr.w #3,d1 | d1 = (x%6) / 8 42 add.w d1,d0 | d0 = cursor address 43 add.w _lcdbase,d0 | ... 44 move.w d0,d1 | d1 = cursor address, too 45 move.b #G_CRSWR,_lcd_a1 | Send cursor address to GLC 46 move.b d0,_lcd_a0 | ... 47 lsr.w #8,d0 | ... 48 move.b d0,_lcd_a0 | ... 49 move.b #G_MREAD,_lcd_a1 | Read old pixel byte 50 move.b _lcd_a1,d0 | ... into d0 51 tst.w VAL(a6) | Check val for zero 52 beq glcplt1 | Jump if val EQ 0 53 54 bset d2,d0 | Set the pixel to 1 55 bra glcplt2 | Go write pixel to GLC 56 57 glcplt1: bclr d2,d0 | Clear the pixel to 0 58 59 glcplt2: move.b #G_CRSWR,_lcd_a1 | Send cursor address to GLC 60 move.b d1,_lcd_a0 | ... 61 lsr.w #8,d1 | ... 62 move.b d1,_lcd_a0 | ... 63 move.b #G_MWRITE,_lcd_a1 | Setup GLC to write pixel 64 move.b d0,_lcd_a0 | Write pixel 65 unlk a6 | Unlink stack frames 66 rts | Return to caller 67 68 68 .end -
vlib/tsplot4.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *tsplot4.s -- output characters to a 4-bit / pixel graphics window3 *with variable vertical pitch4 *Version 1 -- 1987-08-04 -- D.N. Lynx Crowe5 *(c) Copyright 1987 -- D.N. Lynx Crowe6 *------------------------------------------------------------------------------7 * 8 *tsplot4(obase, nw, fg, row, col, str. pitch)9 * int *obase, nw, fg, row, col, pitch;10 * char *str;11 * 12 *Outputs characters from the string at 'str' to an 'nw'13 *character wide 4-bit per pixel graphics window at 'obase'14 *at ('row','col'), using 'fg' as the foreground color.15 *Uses cgtable[][256] as the VSDD formatted character16 *generator table. Assumes 12 bit high characters in the17 *cgtable. Uses 'pitch' as the vertical spacing between18 *character rows. No error checks are done.19 *The string must fit the output area (no overlaps, single line).20 * 21 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | tsplot4.s -- output characters to a 4-bit / pixel graphics window 3 | with variable vertical pitch 4 | Version 1 -- 1987-08-04 -- D.N. Lynx Crowe 5 | (c) Copyright 1987 -- D.N. Lynx Crowe 6 | ------------------------------------------------------------------------------ 7 8 | tsplot4(obase, nw, fg, row, col, str. pitch) 9 | int |obase, nw, fg, row, col, pitch; 10 | char |str; 11 12 | Outputs characters from the string at 'str' to an 'nw' 13 | character wide 4-bit per pixel graphics window at 'obase' 14 | at ('row','col'), using 'fg' as the foreground color. 15 | Uses cgtable[][256] as the VSDD formatted character 16 | generator table. Assumes 12 bit high characters in the 17 | cgtable. Uses 'pitch' as the vertical spacing between 18 | character rows. No error checks are done. 19 | The string must fit the output area (no overlaps, single line). 20 21 | ------------------------------------------------------------------------------ 22 22 .text 23 * 23 24 24 .xdef _tsplot4 25 * 25 26 26 .xref _cgtable 27 * 28 *Argument offsets from a6:29 * 30 OBASE .equ 8 *LONG - Output area base address31 NW .equ 12 *WORD - Character width of output area32 FG .equ 14 *WORD - Foreground color33 ROW .equ 16 *WORD - Row34 COL .equ 18 *WORD - Column35 STR .equ 20 *LONG - String base address36 PITCH .equ 24 *WORD - Vertical spacing between rows37 * 38 *Program constant definitions:39 * 40 HPIX .equ 8 *Character width in pixels41 VPIX .equ 12 *Character height in pixels42 HCW .equ 4 *Horizontal character width (bytes)43 PSHIFT .equ 12 *Pixel shift into MS bits44 HSHIFT .equ 4 *Pixel right shift45 * 27 28 | Argument offsets from a6: 29 30 OBASE = 8 | LONG - Output area base address 31 NW = 12 | WORD - Character width of output area 32 FG = 14 | WORD - Foreground color 33 ROW = 16 | WORD - Row 34 COL = 18 | WORD - Column 35 STR = 20 | LONG - String base address 36 PITCH = 24 | WORD - Vertical spacing between rows 37 38 | Program constant definitions: 39 40 HPIX = 8 | Character width in pixels 41 VPIX = 12 | Character height in pixels 42 HCW = 4 | Horizontal character width (bytes) 43 PSHIFT = 12 | Pixel shift into MS bits 44 HSHIFT = 4 | Pixel right shift 45 46 46 .page 47 * 48 *Register usage:49 * 50 *d0 output word and scratch51 *d1 CG word and scratch52 *d2 pixel counter53 * 54 *d3 foreground color (in the 4 ms bits)55 *d4 background color (in the 4 ms bits)56 *d5 width of the area in bytes57 *d6 scan line counter58 * 59 *a0 CG table pointer60 *a1 output area scan line pointer61 *a2 input string character pointer62 * 63 *a3 output area character base pointer64 * 65 *a6 frame pointer66 *a7 stack pointer67 * 47 48 | Register usage: 49 50 | d0 output word and scratch 51 | d1 CG word and scratch 52 | d2 pixel counter 53 54 | d3 foreground color (in the 4 ms bits) 55 | d4 background color (in the 4 ms bits) 56 | d5 width of the area in bytes 57 | d6 scan line counter 58 59 | a0 CG table pointer 60 | a1 output area scan line pointer 61 | a2 input string character pointer 62 63 | a3 output area character base pointer 64 65 | a6 frame pointer 66 | a7 stack pointer 67 68 68 .page 69 * 70 _tsplot4: link a6,#0 *Link stack frames71 movem.l d3-d6/a3,-(a7) *Save registers we use72 move.w #PSHIFT,d1 *Set shift constant73 move.w FG(a6),d3 *Setup foreground color74 lsl.w d1,d3 *... in ms 4 bits of d3.W75 move.w NW(a6),d5 *Get line width in d5.W76 lsl.w #2,d5 *Multiply width by 4 for offset77 move.w ROW(a6),d0 *Calculate output address78 move.w PITCH(a6),d1 *... PITCH79 mulu d1,d0 * ... *ROW80 add.w #VPIX-1,d0 *... + VPIX-181 mulu d5,d0 * ... *NW82 clr.l d1 *...83 move.w COL(a6),d1 * ... +84 lsl.w #2,d1 * ... COL *485 add.l d1,d0 *...86 add.l OBASE(a6),d0 *... + OBASE87 movea.l d0,a3 *Leave output address in a388 movea.l STR(a6),a2 *Put string address in a289 * 90 cgl0: clr.l d0 *Clear out upper bits of d091 move.b (a2)+,d0 *Get next character92 beq cgl5 *Done if character EQ 093 * 94 movea.l a3,a1 *Establish output pointer in a195 adda.l #HCW,a3 *Update output pointer for next char.96 lea _cgtable,a0 *Establish CG pointer in a097 lsl.w #1,d0 * ... 2 *character98 adda.w d0,a0 *... + _cgtable address99 move.w #VPIX-1,d6 *Set scan line counter in d6100 * 69 70 _tsplot4: link a6,#0 | Link stack frames 71 movem.l d3-d6/a3,-(a7) | Save registers we use 72 move.w #PSHIFT,d1 | Set shift constant 73 move.w FG(a6),d3 | Setup foreground color 74 lsl.w d1,d3 | ... in ms 4 bits of d3.W 75 move.w NW(a6),d5 | Get line width in d5.W 76 lsl.w #2,d5 | Multiply width by 4 for offset 77 move.w ROW(a6),d0 | Calculate output address 78 move.w PITCH(a6),d1 | ... PITCH 79 mulu d1,d0 | ... | ROW 80 add.w #VPIX-1,d0 | ... + VPIX-1 81 mulu d5,d0 | ... | NW 82 clr.l d1 | ... 83 move.w COL(a6),d1 | ... + 84 lsl.w #2,d1 | ... COL | 4 85 add.l d1,d0 | ... 86 add.l OBASE(a6),d0 | ... + OBASE 87 movea.l d0,a3 | Leave output address in a3 88 movea.l STR(a6),a2 | Put string address in a2 89 90 cgl0: clr.l d0 | Clear out upper bits of d0 91 move.b (a2)+,d0 | Get next character 92 beq cgl5 | Done if character EQ 0 93 94 movea.l a3,a1 | Establish output pointer in a1 95 adda.l #HCW,a3 | Update output pointer for next char. 96 lea _cgtable,a0 | Establish CG pointer in a0 97 lsl.w #1,d0 | ... 2 | character 98 adda.w d0,a0 | ... + _cgtable address 99 move.w #VPIX-1,d6 | Set scan line counter in d6 100 101 101 .page 102 cgl1: move.w (a0),d1 *Get character generator word in d1103 move.w #(HPIX/2)-1,d2 *Set pixel counter in d2104 clr.l d4 *Get old output word as background105 move.w (a1),d4 *...106 swap d4 *...107 * 108 cgl2: lsr.w #HSHIFT,d0 *Shift output word right 1 pixel109 lsr.l #HSHIFT,d4 *Shift background word 1 pixel110 andi.l # $FFFFF000,d4 *Mask for upper 4 bits of d4.W111 btst.l #0,d1 *Check CG word ls bit112 beq cgl3 *Set background color if bit EQ 0113 * 114 or.w d3,d0 *OR foreground color into output word115 bra cgl4 *Go update CG word116 * 117 cgl3: or.w d4,d0 *OR background color into output word118 * 119 cgl4: lsr.w #1,d1 *Shift CG word right 1 pixel120 dbf d2,cgl2 *Loop for first 4 pixels121 * 122 move.w d0,(a1)+ *Store first output word in scan line123 move.w #(HPIX/2)-1,d2 *Set pixel counter in d2124 clr.l d4 *Get old output word as background125 move.w (a1),d4 *...126 swap d4 *...127 * 128 cgl2a: lsr.w #HSHIFT,d0 *Shift output word right 1 pixel129 lsr.l #HSHIFT,d4 *Shift background word 1 pixel130 andi.l # $FFFFF000,d4 *Mask for upper bits of d4.W131 btst.l #0,d1 *Check CG word ls bit132 beq cgl3a *Set background color if bit EQ 0133 * 134 or.w d3,d0 *OR foreground color into output word135 bra cgl4a *Go update CG word136 * 137 cgl3a: or.w d4,d0 *OR background color into output word138 * 139 cgl4a: lsr.w #1,d1 *Shift CG word right 1 pixel140 dbf d2,cgl2a *Loop for last 4 pixels141 * 142 move.w d0,(a1) *Store second output word in scan line143 suba.w d5,a1 *Update output pointer144 suba.w #2,a1 *...145 adda.l #512,a0 *Update CG pointer for next scan line146 dbf d6,cgl1 *Loop for all scan lines147 * 148 bra cgl0 *Loop for next character149 * 150 cgl5: movem.l (a7)+,d3-d6/a3 *Restore registers151 unlk a6 *Unlink stack frames152 rts *Return to caller153 * 102 cgl1: move.w (a0),d1 | Get character generator word in d1 103 move.w #(HPIX/2)-1,d2 | Set pixel counter in d2 104 clr.l d4 | Get old output word as background 105 move.w (a1),d4 | ... 106 swap d4 | ... 107 108 cgl2: lsr.w #HSHIFT,d0 | Shift output word right 1 pixel 109 lsr.l #HSHIFT,d4 | Shift background word 1 pixel 110 andi.l #0xFFFFF000,d4 | Mask for upper 4 bits of d4.W 111 btst.l #0,d1 | Check CG word ls bit 112 beq cgl3 | Set background color if bit EQ 0 113 114 or.w d3,d0 | OR foreground color into output word 115 bra cgl4 | Go update CG word 116 117 cgl3: or.w d4,d0 | OR background color into output word 118 119 cgl4: lsr.w #1,d1 | Shift CG word right 1 pixel 120 dbf d2,cgl2 | Loop for first 4 pixels 121 122 move.w d0,(a1)+ | Store first output word in scan line 123 move.w #(HPIX/2)-1,d2 | Set pixel counter in d2 124 clr.l d4 | Get old output word as background 125 move.w (a1),d4 | ... 126 swap d4 | ... 127 128 cgl2a: lsr.w #HSHIFT,d0 | Shift output word right 1 pixel 129 lsr.l #HSHIFT,d4 | Shift background word 1 pixel 130 andi.l #0xFFFFF000,d4 | Mask for upper bits of d4.W 131 btst.l #0,d1 | Check CG word ls bit 132 beq cgl3a | Set background color if bit EQ 0 133 134 or.w d3,d0 | OR foreground color into output word 135 bra cgl4a | Go update CG word 136 137 cgl3a: or.w d4,d0 | OR background color into output word 138 139 cgl4a: lsr.w #1,d1 | Shift CG word right 1 pixel 140 dbf d2,cgl2a | Loop for last 4 pixels 141 142 move.w d0,(a1) | Store second output word in scan line 143 suba.w d5,a1 | Update output pointer 144 suba.w #2,a1 | ... 145 adda.l #512,a0 | Update CG pointer for next scan line 146 dbf d6,cgl1 | Loop for all scan lines 147 148 bra cgl0 | Loop for next character 149 150 cgl5: movem.l (a7)+,d3-d6/a3 | Restore registers 151 unlk a6 | Unlink stack frames 152 rts | Return to caller 153 154 154 .end -
vlib/vbank.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vbank.s -- VSDD bank switching control functions3 *Version 3 -- 1989-12-19 -- D.N. Lynx Crowe4 * 5 *unsigned6 *vbank(b)7 *unsigned b;8 * 9 *Set VSDD Data Segment bank to b.10 *Return old bank select value.11 * 12 * 13 *vfwait()14 * 15 *Wait for a FRAMESTOP update to transpire.16 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | vbank.s -- VSDD bank switching control functions 3 | Version 3 -- 1989-12-19 -- D.N. Lynx Crowe 4 5 | unsigned 6 | vbank(b) 7 | unsigned b; 8 9 | Set VSDD Data Segment bank to b. 10 | Return old bank select value. 11 12 13 | vfwait() 14 15 | Wait for a FRAMESTOP update to transpire. 16 | ------------------------------------------------------------------------------ 17 17 .xdef _vbank 18 18 .xdef _vfwait 19 * 19 20 20 .xref _v_regs 21 * 21 22 22 .text 23 * 24 B .equ825 * 26 OLDB .equd627 NEWB .equd728 * 29 VSDD_R5 .equ1030 VSDD_R11 .equ2231 * 32 VT_BASE .equ 128 *word offset of VSDD Access Table33 * 34 VT_1 .equ VT_BASE+300 *high time35 VT_2 .equ VT_BASE+2 *low time36 * 23 24 B = 8 25 26 OLDB = d6 27 NEWB = d7 28 29 VSDD_R5 = 10 30 VSDD_R11 = 22 31 32 VT_BASE = 128 | word offset of VSDD Access Table 33 34 VT_1 = VT_BASE+300 | high time 35 VT_2 = VT_BASE+2 | low time 36 37 37 .page 38 * ------------------------------------------------------------------------------ 39 * vbank(b) -- change VSDD Data Segment bank to b. Return old bank. 40 * Assumes a 128K byte window, sets S15..S11 to zero. 41 * ------------------------------------------------------------------------------ 42 * 38 | ------------------------------------------------------------------------------ 39 | vbank(b) -- change VSDD Data Segment bank to b. Return old bank. 40 | Assumes a 128K byte window, sets S15..S11 to zero. 41 | ------------------------------------------------------------------------------ 43 42 44 _vbank: link a6,#0 * link stack frames 45 movem.l d5-d7,-(sp) * preserve registers 46 move.w _v_regs+VSDD_R5,OLDB * get v_regs[5] 47 lsr.w #6,OLDB * extract BS bits 48 move.w OLDB,d0 * ... 49 andi.w #2,d0 * ... 50 move.w OLDB,d1 * ... 51 lsr.w #2,d1 * ... 52 andi.w #1,d1 * ... 53 or.w d1,d0 * ... 54 move.w d0,OLDB * ... 55 cmp.w B(a6),OLDB * see if they're what we want 56 bne L2 * jump if not 57 * 58 move.w B(a6),d0 * setup to return b 43 44 _vbank: link a6,#0 | link stack frames 45 movem.l d5-d7,-(sp) | preserve registers 46 move.w _v_regs+VSDD_R5,OLDB | get v_regs[5] 47 lsr.w #6,OLDB | extract BS bits 48 move.w OLDB,d0 | ... 49 andi.w #2,d0 | ... 50 move.w OLDB,d1 | ... 51 lsr.w #2,d1 | ... 52 andi.w #1,d1 | ... 53 or.w d1,d0 | ... 54 move.w d0,OLDB | ... 55 cmp.w B(a6),OLDB | see if they're what we want 56 bne L2 | jump if not 57 58 move.w B(a6),d0 | setup to return b 59 59 bra L1 60 * 61 L2: move.w B(a6),NEWB *get bank bits from b62 lsl.w #6,NEWB *shift bits from b into BS bits63 move.w NEWB,d0 *...64 andi.w #128,d0 *...65 lsl.w #2,NEWB *...66 andi.w #256,NEWB *...67 or.w NEWB,d0 *...68 move.w d0,_v_regs+VSDD_R5 *set v_regs[5] with new BS bits69 * 70 vw1b: cmp.w #VT_1,_v_regs+VSDD_R11 *wait for FRAMESTOP71 bcc vw1b *...72 * 73 vw2b: cmp.w #VT_1,_v_regs+VSDD_R11 *...74 bcs vw2b *...75 * 76 vw3b: cmp.w #VT_1,_v_regs+VSDD_R11 *...77 bcc vw3b *...78 * 79 vw4b: cmp.w #VT_2,_v_regs+VSDD_R11 *...80 bcs vw4b *...81 * 82 move.w OLDB,d0 *setup to return OLDB83 * 84 L1: tst.l (sp)+ *fixup stack85 movem.l (sp)+,OLDB-NEWB *restore registers86 unlk a6 *unlink stack frames87 rts *return to caller88 * 60 61 L2: move.w B(a6),NEWB | get bank bits from b 62 lsl.w #6,NEWB | shift bits from b into BS bits 63 move.w NEWB,d0 | ... 64 andi.w #128,d0 | ... 65 lsl.w #2,NEWB | ... 66 andi.w #256,NEWB | ... 67 or.w NEWB,d0 | ... 68 move.w d0,_v_regs+VSDD_R5 | set v_regs[5] with new BS bits 69 70 vw1b: cmp.w #VT_1,_v_regs+VSDD_R11 | wait for FRAMESTOP 71 bcc vw1b | ... 72 73 vw2b: cmp.w #VT_1,_v_regs+VSDD_R11 | ... 74 bcs vw2b | ... 75 76 vw3b: cmp.w #VT_1,_v_regs+VSDD_R11 | ... 77 bcc vw3b | ... 78 79 vw4b: cmp.w #VT_2,_v_regs+VSDD_R11 | ... 80 bcs vw4b | ... 81 82 move.w OLDB,d0 | setup to return OLDB 83 84 L1: tst.l (sp)+ | fixup stack 85 movem.l (sp)+,OLDB-NEWB | restore registers 86 unlk a6 | unlink stack frames 87 rts | return to caller 88 89 89 .page 90 * 91 *------------------------------------------------------------------------------92 *vfwait() -- Wait for a FRAMESTOP update to transpire.93 *------------------------------------------------------------------------------94 * 95 _vfwait: link a6,#0 *link stack frames96 * 97 vw1a: cmp.w #VT_1,_v_regs+VSDD_R11 *wait for FRAMESTOP98 bcc vw1a *...99 * 100 vw2a: cmp.w #VT_1,_v_regs+VSDD_R11 *...101 bcs vw2a *...102 * 103 vw3a: cmp.w #VT_1,_v_regs+VSDD_R11 *...104 bcc vw3a *...105 * 106 vw4a: cmp.w #VT_2,_v_regs+VSDD_R11 *...107 bcs vw4a *...108 * 109 unlk a6 *unlink stack frames110 rts *return to caller111 * 90 91 | ------------------------------------------------------------------------------ 92 | vfwait() -- Wait for a FRAMESTOP update to transpire. 93 | ------------------------------------------------------------------------------ 94 95 _vfwait: link a6,#0 | link stack frames 96 97 vw1a: cmp.w #VT_1,_v_regs+VSDD_R11 | wait for FRAMESTOP 98 bcc vw1a | ... 99 100 vw2a: cmp.w #VT_1,_v_regs+VSDD_R11 | ... 101 bcs vw2a | ... 102 103 vw3a: cmp.w #VT_1,_v_regs+VSDD_R11 | ... 104 bcc vw3a | ... 105 106 vw4a: cmp.w #VT_2,_v_regs+VSDD_R11 | ... 107 bcs vw4a | ... 108 109 unlk a6 | unlink stack frames 110 rts | return to caller 111 112 112 .end -
vlib/vclrav.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vclrav.s -- clear a character's attributes in video RAM3 *Version 1 -- 1988-10-11 -- D.N. Lynx Crowe4 *(c) Copyright 1988 -- D.N. Lynx Crowe5 *------------------------------------------------------------------------------6 * 7 *vclrav(adr, row, col, atr, len)8 * unsigned int *adr, row, col, atr, len;9 * 10 *Clears attribute 'atr' at ('row', 'col') in the11 *full attribute text object at 'adr'12 *using a line length of 'len'.13 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | vclrav.s -- clear a character's attributes in video RAM 3 | Version 1 -- 1988-10-11 -- D.N. Lynx Crowe 4 | (c) Copyright 1988 -- D.N. Lynx Crowe 5 | ------------------------------------------------------------------------------ 6 7 | vclrav(adr, row, col, atr, len) 8 | unsigned int |adr, row, col, atr, len; 9 10 | Clears attribute 'atr' at ('row', 'col') in the 11 | full attribute text object at 'adr' 12 | using a line length of 'len'. 13 | ------------------------------------------------------------------------------ 14 14 .text 15 * 15 16 16 .xdef _vclrav 17 * 18 P_ADR .equ819 P_ROW .equ1220 P_COL .equ1421 P_ATR .equ1622 P_LEN .equ1823 * 24 _vclrav: link a6,#0 *Link stack frame pointer25 move.w P_ROW(a6),d0 *Get row26 mulu P_LEN(a6),d0 *Multiply by len27 clr.l d1 *Clear out d128 move.w P_COL(a6),d1 *Get col29 add.l d1,d0 *Add col into d0 to get char. #30 move.l d0,d1 * Develop cw = (cn/2)*6 in d131 andi.l # $FFFFFFFE,d1 *...32 move.l d1,d2 *...33 add.l d1,d1 *...34 add.l d2,d1 *...35 add.l P_ADR(a6),d1 *Add sbase to cw36 movea.l d1,a0 *a0 points at the word with the char.37 btst.l #0,d0 *Odd char. location ?38 bne vclrav1 *Jump if so39 * 40 addq.l #2,a0 *Point at the attribute word41 bra vclravx *Go set attribute42 * 43 vclrav1: addq.l #4,a0 *Point at the attribute word44 * 45 vclravx: move.w P_ATR(a6),d0 *Get attribute mask46 not.w d0 *Complement the mask47 and.w d0,(a0) *Clear attributes in video RAM48 unlk a6 *Unlink the stack frame49 rts *Return to caller50 * 17 18 P_ADR = 8 19 P_ROW = 12 20 P_COL = 14 21 P_ATR = 16 22 P_LEN = 18 23 24 _vclrav: link a6,#0 | Link stack frame pointer 25 move.w P_ROW(a6),d0 | Get row 26 mulu P_LEN(a6),d0 | Multiply by len 27 clr.l d1 | Clear out d1 28 move.w P_COL(a6),d1 | Get col 29 add.l d1,d0 | Add col into d0 to get char. # 30 move.l d0,d1 | Develop cw = (cn/2)|6 in d1 31 andi.l #0xFFFFFFFE,d1 | ... 32 move.l d1,d2 | ... 33 add.l d1,d1 | ... 34 add.l d2,d1 | ... 35 add.l P_ADR(a6),d1 | Add sbase to cw 36 movea.l d1,a0 | a0 points at the word with the char. 37 btst.l #0,d0 | Odd char. location ? 38 bne vclrav1 | Jump if so 39 40 addq.l #2,a0 | Point at the attribute word 41 bra vclravx | Go set attribute 42 43 vclrav1: addq.l #4,a0 | Point at the attribute word 44 45 vclravx: move.w P_ATR(a6),d0 | Get attribute mask 46 not.w d0 | Complement the mask 47 and.w d0,(a0) | Clear attributes in video RAM 48 unlk a6 | Unlink the stack frame 49 rts | Return to caller 50 51 51 .end -
vlib/vcputs.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vcputs.s -- output a character string to a 4-bit per pixel graphics window3 *Version 3 -- 1987-07-31 -- D.N. Lynx Crowe4 *(c) Copyright 1987 -- D.N. Lynx Crowe5 *------------------------------------------------------------------------------6 * 7 *vcputs(obase, nw, fg, bg, row, col, str)8 * int *obase, nw, fg, bg, row, col;9 * char *str;10 * 11 *Outputs characters from the string at 'str' to an 'nw'12 *character wide 4-bit per pixel graphics window at 'obase'13 *at ('row','col'), using 'fg' as the foreground color, and14 *'bg' as the background color. Uses cgtable[][256] as the15 *VSDD formatted character generator table.16 *No error checks are done.17 * 18 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | vcputs.s -- output a character string to a 4-bit per pixel graphics window 3 | Version 3 -- 1987-07-31 -- D.N. Lynx Crowe 4 | (c) Copyright 1987 -- D.N. Lynx Crowe 5 | ------------------------------------------------------------------------------ 6 7 | vcputs(obase, nw, fg, bg, row, col, str) 8 | int |obase, nw, fg, bg, row, col; 9 | char |str; 10 11 | Outputs characters from the string at 'str' to an 'nw' 12 | character wide 4-bit per pixel graphics window at 'obase' 13 | at ('row','col'), using 'fg' as the foreground color, and 14 | 'bg' as the background color. Uses cgtable[][256] as the 15 | VSDD formatted character generator table. 16 | No error checks are done. 17 18 | ------------------------------------------------------------------------------ 19 19 .text 20 * 20 21 21 .xdef _vcputs 22 * 22 23 23 .xref _cgtable 24 * 25 *Argument offsets from a6:26 * 27 OBASE .equ 8 *Output area base address28 NW .equ 12 *Character width of output area29 FG .equ 14 *Foreground color30 BG .equ 16 *Background color31 ROW .equ 18 *Row32 COL .equ 20 *Column33 STR .equ 22 *String base address34 * 35 *Program constant definitions:36 * 37 HPIX .equ 8 *Character width in pixels38 VPIX .equ 12 *Character height in pixels39 HCW .equ 4 *Horizontal character width (bytes)40 PSHIFT .equ 12 *Pixel shift into MS bits41 HSHIFT .equ 4 *Pixel right shift42 * 24 25 | Argument offsets from a6: 26 27 OBASE = 8 | Output area base address 28 NW = 12 | Character width of output area 29 FG = 14 | Foreground color 30 BG = 16 | Background color 31 ROW = 18 | Row 32 COL = 20 | Column 33 STR = 22 | String base address 34 35 | Program constant definitions: 36 37 HPIX = 8 | Character width in pixels 38 VPIX = 12 | Character height in pixels 39 HCW = 4 | Horizontal character width (bytes) 40 PSHIFT = 12 | Pixel shift into MS bits 41 HSHIFT = 4 | Pixel right shift 42 43 43 .page 44 * 45 *Register usage:46 * 47 *d0 output word and scratch48 *d1 CG word and scratch49 *d2 pixel counter50 * 51 *d3 foreground color (in the 4 ms bits)52 *d4 background color (in the 4 ms bits)53 *d5 width of the area in bytes54 *d6 scan line counter55 * 56 *a0 CG table pointer57 *a1 output area scan line pointer58 *a2 input string character pointer59 * 60 *a3 output area character base pointer61 * 44 45 | Register usage: 46 47 | d0 output word and scratch 48 | d1 CG word and scratch 49 | d2 pixel counter 50 51 | d3 foreground color (in the 4 ms bits) 52 | d4 background color (in the 4 ms bits) 53 | d5 width of the area in bytes 54 | d6 scan line counter 55 56 | a0 CG table pointer 57 | a1 output area scan line pointer 58 | a2 input string character pointer 59 60 | a3 output area character base pointer 61 62 62 .page 63 * 64 _vcputs: link a6,#0 *Link stack frames65 movem.l d3-d6/a3,-(a7) *Save registers we use66 move.w #PSHIFT,d1 *Set shift constant67 move.w FG(a6),d3 *Setup foreground color68 lsl.w d1,d3 *... in ms 4 bits of d3.W69 move.w BG(a6),d4 *Setup background color70 lsl.w d1,d4 *... in ms 4 bits of d4.W71 move.w NW(a6),d5 *Get line width in d5.W72 lsl.w #2,d5 *Multiply width by 4 for offset73 move.w ROW(a6),d0 *Calculate output address74 move.w #VPIX,d1 *... VPIX75 mulu d1,d0 * ... *ROW76 add.w #VPIX-1,d0 *... + VPIX-177 mulu d5,d0 * ... *NW78 clr.l d1 *...79 move.w COL(a6),d1 * ... +80 lsl.w #2,d1 * ... COL *481 add.l d1,d0 *...82 add.l OBASE(a6),d0 *... + OBASE83 movea.l d0,a3 *Leave output address in a384 movea.l STR(a6),a2 *Put string address in a285 * 86 cgl0: clr.l d0 *Clear out upper bits of d087 move.b (a2)+,d0 *Get next character88 beq cgl5 *Done if character EQ 089 * 90 movea.l a3,a1 *Establish output pointer in a191 adda.l #HCW,a3 *Update output pointer for next char.92 lea _cgtable,a0 *Establish CG pointer in a093 lsl.w #1,d0 * ... 2 *character94 adda.w d0,a0 *... + _cgtable address95 move.w #VPIX-1,d6 *Set scan line counter in d696 * 63 64 _vcputs: link a6,#0 | Link stack frames 65 movem.l d3-d6/a3,-(a7) | Save registers we use 66 move.w #PSHIFT,d1 | Set shift constant 67 move.w FG(a6),d3 | Setup foreground color 68 lsl.w d1,d3 | ... in ms 4 bits of d3.W 69 move.w BG(a6),d4 | Setup background color 70 lsl.w d1,d4 | ... in ms 4 bits of d4.W 71 move.w NW(a6),d5 | Get line width in d5.W 72 lsl.w #2,d5 | Multiply width by 4 for offset 73 move.w ROW(a6),d0 | Calculate output address 74 move.w #VPIX,d1 | ... VPIX 75 mulu d1,d0 | ... | ROW 76 add.w #VPIX-1,d0 | ... + VPIX-1 77 mulu d5,d0 | ... | NW 78 clr.l d1 | ... 79 move.w COL(a6),d1 | ... + 80 lsl.w #2,d1 | ... COL | 4 81 add.l d1,d0 | ... 82 add.l OBASE(a6),d0 | ... + OBASE 83 movea.l d0,a3 | Leave output address in a3 84 movea.l STR(a6),a2 | Put string address in a2 85 86 cgl0: clr.l d0 | Clear out upper bits of d0 87 move.b (a2)+,d0 | Get next character 88 beq cgl5 | Done if character EQ 0 89 90 movea.l a3,a1 | Establish output pointer in a1 91 adda.l #HCW,a3 | Update output pointer for next char. 92 lea _cgtable,a0 | Establish CG pointer in a0 93 lsl.w #1,d0 | ... 2 | character 94 adda.w d0,a0 | ... + _cgtable address 95 move.w #VPIX-1,d6 | Set scan line counter in d6 96 97 97 .page 98 cgl1: move.w (a0),d1 *Get character generator word in d199 move.w #(HPIX/2)-1,d2 *Set pixel counter in d2100 * 101 cgl2: lsr.w #HSHIFT,d0 *Shift output word right 1 pixel102 btst.l #0,d1 *Check CG word ls bit103 beq cgl3 *Set background color if bit EQ 0104 * 105 or.w d3,d0 *OR foreground color into output word106 bra cgl4 *Go update CG word107 * 108 cgl3: or.w d4,d0 *OR background color into output word109 * 110 cgl4: lsr.w #1,d1 *Shift CG word right 1 pixel111 dbf d2,cgl2 *Loop for first 4 pixels112 * 113 move.w d0,(a1)+ *Store first output word in scan line114 move.w #(HPIX/2)-1,d2 *Set pixel counter in d2115 * 116 cgl2a: lsr.w #HSHIFT,d0 *Shift output word right 1 pixel117 btst.l #0,d1 *Check CG word ls bit118 beq cgl3a *Set background color if bit EQ 0119 * 120 or.w d3,d0 *OR foreground color into output word121 bra cgl4a *Go update CG word122 * 123 cgl3a: or.w d4,d0 *OR background color into output word124 * 125 cgl4a: lsr.w #1,d1 *Shift CG word right 1 pixel126 dbf d2,cgl2a *Loop for last 4 pixels127 * 128 move.w d0,(a1) *Store second output word in scan line129 suba.w d5,a1 *Update output pointer130 suba.w #2,a1 *...131 adda.l #512,a0 *Update CG pointer for next scan line132 dbf d6,cgl1 *Loop for all scan lines133 * 134 bra cgl0 *Loop for next character135 * 136 cgl5: movem.l (a7)+,d3-d6/a3 *Restore registers137 unlk a6 *Unlink stack frames138 rts *Return to caller139 * 98 cgl1: move.w (a0),d1 | Get character generator word in d1 99 move.w #(HPIX/2)-1,d2 | Set pixel counter in d2 100 101 cgl2: lsr.w #HSHIFT,d0 | Shift output word right 1 pixel 102 btst.l #0,d1 | Check CG word ls bit 103 beq cgl3 | Set background color if bit EQ 0 104 105 or.w d3,d0 | OR foreground color into output word 106 bra cgl4 | Go update CG word 107 108 cgl3: or.w d4,d0 | OR background color into output word 109 110 cgl4: lsr.w #1,d1 | Shift CG word right 1 pixel 111 dbf d2,cgl2 | Loop for first 4 pixels 112 113 move.w d0,(a1)+ | Store first output word in scan line 114 move.w #(HPIX/2)-1,d2 | Set pixel counter in d2 115 116 cgl2a: lsr.w #HSHIFT,d0 | Shift output word right 1 pixel 117 btst.l #0,d1 | Check CG word ls bit 118 beq cgl3a | Set background color if bit EQ 0 119 120 or.w d3,d0 | OR foreground color into output word 121 bra cgl4a | Go update CG word 122 123 cgl3a: or.w d4,d0 | OR background color into output word 124 125 cgl4a: lsr.w #1,d1 | Shift CG word right 1 pixel 126 dbf d2,cgl2a | Loop for last 4 pixels 127 128 move.w d0,(a1) | Store second output word in scan line 129 suba.w d5,a1 | Update output pointer 130 suba.w #2,a1 | ... 131 adda.l #512,a0 | Update CG pointer for next scan line 132 dbf d6,cgl1 | Loop for all scan lines 133 134 bra cgl0 | Loop for next character 135 136 cgl5: movem.l (a7)+,d3-d6/a3 | Restore registers 137 unlk a6 | Unlink stack frames 138 rts | Return to caller 139 140 140 .end -
vlib/vcputsv.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vcputsv.s -- output characters to a 4-bit / pixel graphics window3 *with variable vertical pitch4 *Version 2 -- 1987-08-03 -- D.N. Lynx Crowe5 *(c) Copyright 1987 -- D.N. Lynx Crowe6 *------------------------------------------------------------------------------7 * 8 *vcputsv(obase, nw, fg, bg, row, col, str. pitch)9 * int *obase, nw, fg, bg, row, col, pitch;10 * char *str;11 * 12 *Outputs characters from the string at 'str' to an 'nw'13 *character wide 4-bit per pixel graphics window at 'obase'14 *at ('row','col'), using 'fg' as the foreground color, and15 *'bg' as the background color. Uses cgtable[][256] as the16 *VSDD formatted character generator table. Assumes 12 bit17 *high characters in the cgtable. Uses 'pitch' as the vertical18 *spacing between character rows. No error checks are done.19 *The string must fit the output area (no overlaps, single line).20 * 21 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | vcputsv.s -- output characters to a 4-bit / pixel graphics window 3 | with variable vertical pitch 4 | Version 2 -- 1987-08-03 -- D.N. Lynx Crowe 5 | (c) Copyright 1987 -- D.N. Lynx Crowe 6 | ------------------------------------------------------------------------------ 7 8 | vcputsv(obase, nw, fg, bg, row, col, str. pitch) 9 | int |obase, nw, fg, bg, row, col, pitch; 10 | char |str; 11 12 | Outputs characters from the string at 'str' to an 'nw' 13 | character wide 4-bit per pixel graphics window at 'obase' 14 | at ('row','col'), using 'fg' as the foreground color, and 15 | 'bg' as the background color. Uses cgtable[][256] as the 16 | VSDD formatted character generator table. Assumes 12 bit 17 | high characters in the cgtable. Uses 'pitch' as the vertical 18 | spacing between character rows. No error checks are done. 19 | The string must fit the output area (no overlaps, single line). 20 21 | ------------------------------------------------------------------------------ 22 22 .text 23 * 23 24 24 .xdef _vcputsv 25 * 25 26 26 .xref _cgtable 27 * 28 *Argument offsets from a6:29 * 30 OBASE .equ 8 *LONG - Output area base address31 NW .equ 12 *WORD - Character width of output area32 FG .equ 14 *WORD - Foreground color33 BG .equ 16 *WORD - Background color34 ROW .equ 18 *WORD - Row35 COL .equ 20 *WORD - Column36 STR .equ 22 *LONG - String base address37 PITCH .equ 26 *WORD - Vertical spacing between rows38 * 39 *Program constant definitions:40 * 41 HPIX .equ 8 *Character width in pixels42 VPIX .equ 12 *Character height in pixels43 HCW .equ 4 *Horizontal character width (bytes)44 PSHIFT .equ 12 *Pixel shift into MS bits45 HSHIFT .equ 4 *Pixel right shift46 * 27 28 | Argument offsets from a6: 29 30 OBASE = 8 | LONG - Output area base address 31 NW = 12 | WORD - Character width of output area 32 FG = 14 | WORD - Foreground color 33 BG = 16 | WORD - Background color 34 ROW = 18 | WORD - Row 35 COL = 20 | WORD - Column 36 STR = 22 | LONG - String base address 37 PITCH = 26 | WORD - Vertical spacing between rows 38 39 | Program constant definitions: 40 41 HPIX = 8 | Character width in pixels 42 VPIX = 12 | Character height in pixels 43 HCW = 4 | Horizontal character width (bytes) 44 PSHIFT = 12 | Pixel shift into MS bits 45 HSHIFT = 4 | Pixel right shift 46 47 47 .page 48 * 49 *Register usage:50 * 51 *d0 output word and scratch52 *d1 CG word and scratch53 *d2 pixel counter54 * 55 *d3 foreground color (in the 4 ms bits)56 *d4 background color (in the 4 ms bits)57 *d5 width of the area in bytes58 *d6 scan line counter59 * 60 *a0 CG table pointer61 *a1 output area scan line pointer62 *a2 input string character pointer63 * 64 *a3 output area character base pointer65 * 66 *a6 frame pointer67 *a7 stack pointer68 * 48 49 | Register usage: 50 51 | d0 output word and scratch 52 | d1 CG word and scratch 53 | d2 pixel counter 54 55 | d3 foreground color (in the 4 ms bits) 56 | d4 background color (in the 4 ms bits) 57 | d5 width of the area in bytes 58 | d6 scan line counter 59 60 | a0 CG table pointer 61 | a1 output area scan line pointer 62 | a2 input string character pointer 63 64 | a3 output area character base pointer 65 66 | a6 frame pointer 67 | a7 stack pointer 68 69 69 .page 70 * 71 _vcputsv: link a6,#0 *Link stack frames72 movem.l d3-d6/a3,-(a7) *Save registers we use73 move.w #PSHIFT,d1 *Set shift constant74 move.w FG(a6),d3 *Setup foreground color75 lsl.w d1,d3 *... in ms 4 bits of d3.W76 move.w BG(a6),d4 *Setup background color77 lsl.w d1,d4 *... in ms 4 bits of d4.W78 move.w NW(a6),d5 *Get line width in d5.W79 lsl.w #2,d5 *Multiply width by 4 for offset80 move.w ROW(a6),d0 *Calculate output address81 move.w PITCH(a6),d1 *... PITCH82 mulu d1,d0 * ... *ROW83 add.w #VPIX-1,d0 *... + VPIX-184 mulu d5,d0 * ... *NW85 clr.l d1 *...86 move.w COL(a6),d1 * ... +87 lsl.w #2,d1 * ... COL *488 add.l d1,d0 *...89 add.l OBASE(a6),d0 *... + OBASE90 movea.l d0,a3 *Leave output address in a391 movea.l STR(a6),a2 *Put string address in a292 * 93 cgl0: clr.l d0 *Clear out upper bits of d094 move.b (a2)+,d0 *Get next character95 beq cgl5 *Done if character EQ 096 * 97 movea.l a3,a1 *Establish output pointer in a198 adda.l #HCW,a3 *Update output pointer for next char.99 lea _cgtable,a0 *Establish CG pointer in a0100 lsl.w #1,d0 * ... 2 *character101 adda.w d0,a0 *... + _cgtable address102 move.w #VPIX-1,d6 *Set scan line counter in d6103 * 70 71 _vcputsv: link a6,#0 | Link stack frames 72 movem.l d3-d6/a3,-(a7) | Save registers we use 73 move.w #PSHIFT,d1 | Set shift constant 74 move.w FG(a6),d3 | Setup foreground color 75 lsl.w d1,d3 | ... in ms 4 bits of d3.W 76 move.w BG(a6),d4 | Setup background color 77 lsl.w d1,d4 | ... in ms 4 bits of d4.W 78 move.w NW(a6),d5 | Get line width in d5.W 79 lsl.w #2,d5 | Multiply width by 4 for offset 80 move.w ROW(a6),d0 | Calculate output address 81 move.w PITCH(a6),d1 | ... PITCH 82 mulu d1,d0 | ... | ROW 83 add.w #VPIX-1,d0 | ... + VPIX-1 84 mulu d5,d0 | ... | NW 85 clr.l d1 | ... 86 move.w COL(a6),d1 | ... + 87 lsl.w #2,d1 | ... COL | 4 88 add.l d1,d0 | ... 89 add.l OBASE(a6),d0 | ... + OBASE 90 movea.l d0,a3 | Leave output address in a3 91 movea.l STR(a6),a2 | Put string address in a2 92 93 cgl0: clr.l d0 | Clear out upper bits of d0 94 move.b (a2)+,d0 | Get next character 95 beq cgl5 | Done if character EQ 0 96 97 movea.l a3,a1 | Establish output pointer in a1 98 adda.l #HCW,a3 | Update output pointer for next char. 99 lea _cgtable,a0 | Establish CG pointer in a0 100 lsl.w #1,d0 | ... 2 | character 101 adda.w d0,a0 | ... + _cgtable address 102 move.w #VPIX-1,d6 | Set scan line counter in d6 103 104 104 .page 105 cgl1: move.w (a0),d1 *Get character generator word in d1106 move.w #(HPIX/2)-1,d2 *Set pixel counter in d2107 * 108 cgl2: lsr.w #HSHIFT,d0 *Shift output word right 1 pixel109 btst.l #0,d1 *Check CG word ls bit110 beq cgl3 *Set background color if bit EQ 0111 * 112 or.w d3,d0 *OR foreground color into output word113 bra cgl4 *Go update CG word114 * 115 cgl3: or.w d4,d0 *OR background color into output word116 * 117 cgl4: lsr.w #1,d1 *Shift CG word right 1 pixel118 dbf d2,cgl2 *Loop for first 4 pixels119 * 120 move.w d0,(a1)+ *Store first output word in scan line121 move.w #(HPIX/2)-1,d2 *Set pixel counter in d2122 * 123 cgl2a: lsr.w #HSHIFT,d0 *Shift output word right 1 pixel124 btst.l #0,d1 *Check CG word ls bit125 beq cgl3a *Set background color if bit EQ 0126 * 127 or.w d3,d0 *OR foreground color into output word128 bra cgl4a *Go update CG word129 * 130 cgl3a: or.w d4,d0 *OR background color into output word131 * 132 cgl4a: lsr.w #1,d1 *Shift CG word right 1 pixel133 dbf d2,cgl2a *Loop for last 4 pixels134 * 135 move.w d0,(a1) *Store second output word in scan line136 suba.w d5,a1 *Update output pointer137 suba.w #2,a1 *...138 adda.l #512,a0 *Update CG pointer for next scan line139 dbf d6,cgl1 *Loop for all scan lines140 * 141 bra cgl0 *Loop for next character142 * 143 cgl5: movem.l (a7)+,d3-d6/a3 *Restore registers144 unlk a6 *Unlink stack frames145 rts *Return to caller146 * 105 cgl1: move.w (a0),d1 | Get character generator word in d1 106 move.w #(HPIX/2)-1,d2 | Set pixel counter in d2 107 108 cgl2: lsr.w #HSHIFT,d0 | Shift output word right 1 pixel 109 btst.l #0,d1 | Check CG word ls bit 110 beq cgl3 | Set background color if bit EQ 0 111 112 or.w d3,d0 | OR foreground color into output word 113 bra cgl4 | Go update CG word 114 115 cgl3: or.w d4,d0 | OR background color into output word 116 117 cgl4: lsr.w #1,d1 | Shift CG word right 1 pixel 118 dbf d2,cgl2 | Loop for first 4 pixels 119 120 move.w d0,(a1)+ | Store first output word in scan line 121 move.w #(HPIX/2)-1,d2 | Set pixel counter in d2 122 123 cgl2a: lsr.w #HSHIFT,d0 | Shift output word right 1 pixel 124 btst.l #0,d1 | Check CG word ls bit 125 beq cgl3a | Set background color if bit EQ 0 126 127 or.w d3,d0 | OR foreground color into output word 128 bra cgl4a | Go update CG word 129 130 cgl3a: or.w d4,d0 | OR background color into output word 131 132 cgl4a: lsr.w #1,d1 | Shift CG word right 1 pixel 133 dbf d2,cgl2a | Loop for last 4 pixels 134 135 move.w d0,(a1) | Store second output word in scan line 136 suba.w d5,a1 | Update output pointer 137 suba.w #2,a1 | ... 138 adda.l #512,a0 | Update CG pointer for next scan line 139 dbf d6,cgl1 | Loop for all scan lines 140 141 bra cgl0 | Loop for next character 142 143 cgl5: movem.l (a7)+,d3-d6/a3 | Restore registers 144 unlk a6 | Unlink stack frames 145 rts | Return to caller 146 147 147 .end -
vlib/viint.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *viint.s -- VSDD Vertical Interval interrupt handler for the Buchla 7003 *Version 17 -- 1989-12-19 -- D.N. Lynx Crowe4 * 5 *VIint6 * 7 *VSDD Vertical Interval interrupt handler. Enables display of8 *any object whose bit is set in vi_ctl. Bit 0 = object 0, etc.9 * 10 *SetPri() uses BIOS(B_SETV, 25, VIint) to set the interrupt11 *vector and lets VIint() enable the object. If vi_dis12 *is set, SetPri() won't enable the interrupt or set the vector13 *so that several objects can be started up at once.14 * 15 *This routine also sets the base address and scroll offset16 *for the score display object if vi_sadr is non-zero,17 *after a delay for VSDD FRAMESTOP synchronization.18 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | viint.s -- VSDD Vertical Interval interrupt handler for the Buchla 700 3 | Version 17 -- 1989-12-19 -- D.N. Lynx Crowe 4 5 | VIint 6 7 | VSDD Vertical Interval interrupt handler. Enables display of 8 | any object whose bit is set in vi_ctl. Bit 0 = object 0, etc. 9 10 | SetPri() uses BIOS(B_SETV, 25, VIint) to set the interrupt 11 | vector and lets VIint() enable the object. If vi_dis 12 | is set, SetPri() won't enable the interrupt or set the vector 13 | so that several objects can be started up at once. 14 15 | This routine also sets the base address and scroll offset 16 | for the score display object if vi_sadr is non-zero, 17 | after a delay for VSDD FRAMESTOP synchronization. 18 | ------------------------------------------------------------------------------ 19 19 .text 20 * 21 .xdef _VIint *Vertical Interval int. handler22 * 23 .xdef _vi_sadr *score object base address24 .xdef _vi_scrl *score object scroll offset25 .xdef lclsadr *local scroll address26 .xdef lclscrl *local scroll offset27 .xdef vdelay *VSDD scroll delay28 * 29 .xdef VIct1 * VSDD interrupt R1130 .xdef VIct2 * VSDD interrupt R1131 .xdef VIct3 * VSDD interrupt R1132 .xdef VIct4 * VSDD interrupt R1133 * 34 .xref _v_regs *VSDD registers35 .xref _v_odtab *VSDD object descriptor table36 * 37 .xref _vi_clk *scroll delay timer38 .xref _vi_ctl *unblank control word39 .xref _vi_tag *VSDD 'needs service' tag40 * 41 .page 42 * 43 *Miscellaneous equates:44 *----------------------45 * 46 DELAY .equ 17 *FRAMESTOP sync delay in Ms47 STACKSR .equ 32 *offset to sr on stack48 V_BLA .equ 4 *V_BLA (blank) bit number49 VSDD_R5 .equ 10 *VSDD R5 byte offset in _v_regs50 VSDD_R11 .equ 22 *VSDD R11 byte offset in _v_regs51 * 52 VT_BASE .equ 128 *word offset of VSDD Access Table53 * 54 VT_1 .equ VT_BASE+300 *high time55 VT_2 .equ VT_BASE+2 *low time56 *------------------------------------------------------------------------------57 * 58 *Stack picture after movem.l at entry:59 *-------------------------------------60 * 61 *LONG PC +3462 *WORD SR +32 STACKSR63 *LONG A6 +2864 *LONG A2 +2465 *LONG A1 +2066 *LONG A0 +1667 *LONG D3 +1268 *LONG D2 +869 *LONG D1 +470 *LONG D0 +071 * 72 *------------------------------------------------------------------------------73 * 74 .page 75 * 76 *_VIint -- Vertical interval interrupt handler77 *------ -----------------------------------78 _VIint: movem.l d0-d3/a0-a2/a6,-(a7) *save registers79 addi.w # $0100,STACKSR(a7) *raise IPL in sr on the stack80 * 81 move.w _v_regs+VSDD_R11,VIct1 *save the VSDD R11 value82 * 83 tst.w _vi_sadr *see if we should scroll84 beq viunbl *jump if not85 * 86 *------------------------------------------------------------------------------87 *setup delayed scroll parameters88 *------------------------------------------------------------------------------89 move.w _v_regs+VSDD_R5,d0 *get VSDD R590 move.w d0,d1 *save it for later91 andi.w # $0180,d0 *see if we're already in bank 092 beq dlyscrl *jump if so93 * 94 clr.w _v_regs+VSDD_R5 *set bank 095 * 96 move.w _v_regs+VSDD_R11,VIct2 *save the VSDD R11 value97 * 98 vw1a: cmp.w #VT_1,_v_regs+VSDD_R11 *wait for FRAMESTOP99 bcc vw1a *...100 * 101 vw2a: cmp.w #VT_1,_v_regs+VSDD_R11 *...102 bcs vw2a *...103 * 104 vw3a: cmp.w #VT_1,_v_regs+VSDD_R11 *...105 bcc vw3a *...106 * 107 vw4a: cmp.w #VT_2,_v_regs+VSDD_R11 *...108 bcs vw4a *...109 * 110 dlyscrl: tst.w _vi_tag *wait for previous scroll111 bne dlyscrl *...112 * 113 move.w _vi_sadr,lclsadr *save address for timeint114 move.w _vi_scrl,lclscrl *save offset for timeint115 clr.w _vi_sadr *reset for next time116 clr.w _vi_scrl *...117 move.w vdelay,_vi_clk *set the scroll delay timer118 st _vi_tag *set the 'need service' tag119 *------------------------------------------------------------------------------120 *check for unblank requests121 *------------------------------------------------------------------------------122 move.w _vi_ctl,d2 *get the unblank control word123 beq viexit *exit if nothing to unblank124 * 125 bra unblnk *go unblank some objects126 * 127 viunbl: move.w _vi_ctl,d2 *get the unblank control word128 beq vidone *exit if nothing to unblank129 * 130 move.w _v_regs+VSDD_R5,d0 *get VSDD R5131 move.w d0,d1 *save it for later132 andi.w # $0180,d0 *see if we're already in bank 0133 beq unblnk *jump if so134 * 135 clr.w _v_regs+VSDD_R5 *set bank 0136 * 137 move.w _v_regs+VSDD_R11,VIct3 *save the VSDD R11 value138 * 139 vw1b: cmp.w #VT_1,_v_regs+VSDD_R11 *wait for FRAMESTOP140 bcc vw1b *...141 * 142 vw2b: cmp.w #VT_1,_v_regs+VSDD_R11 *...143 bcs vw2b *...144 * 145 vw3b: cmp.w #VT_1,_v_regs+VSDD_R11 *...146 bcc vw3b *...147 * 148 vw4b: cmp.w #VT_2,_v_regs+VSDD_R11 *...149 bcs vw4b *...150 * 151 .page 152 * 153 *------------------------------------------------------------------------------154 *unblank objects indicated by contents of d2 (loaded earlier from _vi_ctl)155 *------------------------------------------------------------------------------156 * 157 unblnk: clr.w d3 *clear the counter158 clr.w _vi_ctl *clear the unblank control word159 lea _v_odtab,a1 *point at first object160 * 161 vicheck: btst d3,d2 *check the object bit162 beq vinext *go check next one if not set163 * 164 move.w (a1),d0 *get v_odtab[obj][0]165 bclr #V_BLA,d0 *clear the blanking bit166 move.w d0,(a1) *set v_odtab[obj][0]167 * 168 vinext: cmpi.w #15,d3 *see if we're done169 beq viexit *jump if so170 * 171 addq.l #8,a1 *point at next object172 addq.w #1,d3 *increment object counter173 bra vicheck *go check next object174 * 175 *------------------------------------------------------------------------------176 *switch back to the bank the interrupted code was using if we changed it177 *------------------------------------------------------------------------------178 * 179 viexit: move.w d1,d0 *see if we were in bank 0180 andi.w # $0180,d0 *...181 beq vidone *jump if so182 * 183 viwait: tst.w _vi_tag *wait for timer to run out184 bne viwait *... so timeint sees bank 0185 * 186 move.w d1,_v_regs+VSDD_R5 *restore v_regs[5] to old bank187 * 188 move.w _v_regs+VSDD_R11,VIct4 *save the VSDD R11 value189 * 190 vw1c: cmp.w #VT_1,_v_regs+VSDD_R11 *wait for FRAMESTOP191 bcc vw1c *...192 * 193 vw2c: cmp.w #VT_1,_v_regs+VSDD_R11 *...194 bcs vw2c *...195 * 196 vw3c: cmp.w #VT_1,_v_regs+VSDD_R11 *...197 bcc vw3c *...198 * 199 vw4c: cmp.w #VT_2,_v_regs+VSDD_R11 *...200 bcs vw4c *...201 * 202 *------------------------------------------------------------------------------203 *restore registers and return to interrupted code204 *------------------------------------------------------------------------------205 * 206 vidone: movem.l (a7)+,d0-d3/a0-a2/a6 *restore registers207 rte *return from interrupt208 * 209 .page 210 * 211 *------------------------------------------------------------------------------20 21 .xdef _VIint | Vertical Interval int. handler 22 23 .xdef _vi_sadr | score object base address 24 .xdef _vi_scrl | score object scroll offset 25 .xdef lclsadr | local scroll address 26 .xdef lclscrl | local scroll offset 27 .xdef vdelay | VSDD scroll delay 28 29 .xdef VIct1 | VSDD interrupt R11 30 .xdef VIct2 | VSDD interrupt R11 31 .xdef VIct3 | VSDD interrupt R11 32 .xdef VIct4 | VSDD interrupt R11 33 34 .xref _v_regs | VSDD registers 35 .xref _v_odtab | VSDD object descriptor table 36 37 .xref _vi_clk | scroll delay timer 38 .xref _vi_ctl | unblank control word 39 .xref _vi_tag | VSDD 'needs service' tag 40 41 .page 42 43 | Miscellaneous equates: 44 | ---------------------- 45 46 DELAY = 17 | FRAMESTOP sync delay in Ms 47 STACKSR = 32 | offset to sr on stack 48 V_BLA = 4 | V_BLA (blank) bit number 49 VSDD_R5 = 10 | VSDD R5 byte offset in _v_regs 50 VSDD_R11 = 22 | VSDD R11 byte offset in _v_regs 51 52 VT_BASE = 128 | word offset of VSDD Access Table 53 54 VT_1 = VT_BASE+300 | high time 55 VT_2 = VT_BASE+2 | low time 56 | ------------------------------------------------------------------------------ 57 58 | Stack picture after movem.l at entry: 59 | ------------------------------------- 60 61 | LONG PC +34 62 | WORD SR +32 STACKSR 63 | LONG A6 +28 64 | LONG A2 +24 65 | LONG A1 +20 66 | LONG A0 +16 67 | LONG D3 +12 68 | LONG D2 +8 69 | LONG D1 +4 70 | LONG D0 +0 71 72 | ------------------------------------------------------------------------------ 73 74 .page 75 76 | _VIint -- Vertical interval interrupt handler 77 | ------ ----------------------------------- 78 _VIint: movem.l d0-d3/a0-a2/a6,-(a7) | save registers 79 addi.w #0x0100,STACKSR(a7) | raise IPL in sr on the stack 80 81 move.w _v_regs+VSDD_R11,VIct1 | save the VSDD R11 value 82 83 tst.w _vi_sadr | see if we should scroll 84 beq viunbl | jump if not 85 86 | ------------------------------------------------------------------------------ 87 | setup delayed scroll parameters 88 | ------------------------------------------------------------------------------ 89 move.w _v_regs+VSDD_R5,d0 | get VSDD R5 90 move.w d0,d1 | save it for later 91 andi.w #0x0180,d0 | see if we're already in bank 0 92 beq dlyscrl | jump if so 93 94 clr.w _v_regs+VSDD_R5 | set bank 0 95 96 move.w _v_regs+VSDD_R11,VIct2 | save the VSDD R11 value 97 98 vw1a: cmp.w #VT_1,_v_regs+VSDD_R11 | wait for FRAMESTOP 99 bcc vw1a | ... 100 101 vw2a: cmp.w #VT_1,_v_regs+VSDD_R11 | ... 102 bcs vw2a | ... 103 104 vw3a: cmp.w #VT_1,_v_regs+VSDD_R11 | ... 105 bcc vw3a | ... 106 107 vw4a: cmp.w #VT_2,_v_regs+VSDD_R11 | ... 108 bcs vw4a | ... 109 110 dlyscrl: tst.w _vi_tag | wait for previous scroll 111 bne dlyscrl | ... 112 113 move.w _vi_sadr,lclsadr | save address for timeint 114 move.w _vi_scrl,lclscrl | save offset for timeint 115 clr.w _vi_sadr | reset for next time 116 clr.w _vi_scrl | ... 117 move.w vdelay,_vi_clk | set the scroll delay timer 118 st _vi_tag | set the 'need service' tag 119 | ------------------------------------------------------------------------------ 120 | check for unblank requests 121 | ------------------------------------------------------------------------------ 122 move.w _vi_ctl,d2 | get the unblank control word 123 beq viexit | exit if nothing to unblank 124 125 bra unblnk | go unblank some objects 126 127 viunbl: move.w _vi_ctl,d2 | get the unblank control word 128 beq vidone | exit if nothing to unblank 129 130 move.w _v_regs+VSDD_R5,d0 | get VSDD R5 131 move.w d0,d1 | save it for later 132 andi.w #0x0180,d0 | see if we're already in bank 0 133 beq unblnk | jump if so 134 135 clr.w _v_regs+VSDD_R5 | set bank 0 136 137 move.w _v_regs+VSDD_R11,VIct3 | save the VSDD R11 value 138 139 vw1b: cmp.w #VT_1,_v_regs+VSDD_R11 | wait for FRAMESTOP 140 bcc vw1b | ... 141 142 vw2b: cmp.w #VT_1,_v_regs+VSDD_R11 | ... 143 bcs vw2b | ... 144 145 vw3b: cmp.w #VT_1,_v_regs+VSDD_R11 | ... 146 bcc vw3b | ... 147 148 vw4b: cmp.w #VT_2,_v_regs+VSDD_R11 | ... 149 bcs vw4b | ... 150 151 .page 152 153 | ------------------------------------------------------------------------------ 154 | unblank objects indicated by contents of d2 (loaded earlier from _vi_ctl) 155 | ------------------------------------------------------------------------------ 156 157 unblnk: clr.w d3 | clear the counter 158 clr.w _vi_ctl | clear the unblank control word 159 lea _v_odtab,a1 | point at first object 160 161 vicheck: btst d3,d2 | check the object bit 162 beq vinext | go check next one if not set 163 164 move.w (a1),d0 | get v_odtab[obj][0] 165 bclr #V_BLA,d0 | clear the blanking bit 166 move.w d0,(a1) | set v_odtab[obj][0] 167 168 vinext: cmpi.w #15,d3 | see if we're done 169 beq viexit | jump if so 170 171 addq.l #8,a1 | point at next object 172 addq.w #1,d3 | increment object counter 173 bra vicheck | go check next object 174 175 | ------------------------------------------------------------------------------ 176 | switch back to the bank the interrupted code was using if we changed it 177 | ------------------------------------------------------------------------------ 178 179 viexit: move.w d1,d0 | see if we were in bank 0 180 andi.w #0x0180,d0 | ... 181 beq vidone | jump if so 182 183 viwait: tst.w _vi_tag | wait for timer to run out 184 bne viwait | ... so timeint sees bank 0 185 186 move.w d1,_v_regs+VSDD_R5 | restore v_regs[5] to old bank 187 188 move.w _v_regs+VSDD_R11,VIct4 | save the VSDD R11 value 189 190 vw1c: cmp.w #VT_1,_v_regs+VSDD_R11 | wait for FRAMESTOP 191 bcc vw1c | ... 192 193 vw2c: cmp.w #VT_1,_v_regs+VSDD_R11 | ... 194 bcs vw2c | ... 195 196 vw3c: cmp.w #VT_1,_v_regs+VSDD_R11 | ... 197 bcc vw3c | ... 198 199 vw4c: cmp.w #VT_2,_v_regs+VSDD_R11 | ... 200 bcs vw4c | ... 201 202 | ------------------------------------------------------------------------------ 203 | restore registers and return to interrupted code 204 | ------------------------------------------------------------------------------ 205 206 vidone: movem.l (a7)+,d0-d3/a0-a2/a6 | restore registers 207 rte | return from interrupt 208 209 .page 210 211 | ------------------------------------------------------------------------------ 212 212 .data 213 *------------------------------------------------------------------------------214 * 215 vdelay: .dc.w DELAY *VSDD scroll delay216 * 217 *------------------------------------------------------------------------------213 | ------------------------------------------------------------------------------ 214 215 vdelay: .dc.w DELAY | VSDD scroll delay 216 217 | ------------------------------------------------------------------------------ 218 218 .bss 219 *------------------------------------------------------------------------------220 * 221 _vi_sadr: .ds.w 1 *score object base address222 _vi_scrl: .ds.w 1 *score object scroll offset223 * 224 lclsadr: .ds.w 1 *local copy of vi_sadr225 lclscrl: .ds.w 1 *local copy of vi_scrl226 * 227 VIct1: .ds.w 1 *VSDD R11 value at interrupt228 VIct2: .ds.w 1 *VSDD R11 value at interrupt229 VIct3: .ds.w 1 *VSDD R11 value at interrupt230 VIct4: .ds.w 1 *VSDD R11 value at interrupt231 * 219 | ------------------------------------------------------------------------------ 220 221 _vi_sadr: .ds.w 1 | score object base address 222 _vi_scrl: .ds.w 1 | score object scroll offset 223 224 lclsadr: .ds.w 1 | local copy of vi_sadr 225 lclscrl: .ds.w 1 | local copy of vi_scrl 226 227 VIct1: .ds.w 1 | VSDD R11 value at interrupt 228 VIct2: .ds.w 1 | VSDD R11 value at interrupt 229 VIct3: .ds.w 1 | VSDD R11 value at interrupt 230 VIct4: .ds.w 1 | VSDD R11 value at interrupt 231 232 232 .end -
vlib/vputa.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vputa.s -- store character attributes in video RAM3 *Version 1 -- 1988-03-14 -- D.N. Lynx Crowe4 *(c) Copyright 1988 -- D.N. Lynx Crowe5 *------------------------------------------------------------------------------6 * 7 *vputa(sbase, row, col, attrib)8 * unsigned int *sbase, row, col, attrib;9 * 10 *Stores attribute value 'attrib' for the character11 *located at ('row','col') in VSDD RAM starting at 'sbase'.12 *Assumes a 64 character line and full character attributes.13 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | vputa.s -- store character attributes in video RAM 3 | Version 1 -- 1988-03-14 -- D.N. Lynx Crowe 4 | (c) Copyright 1988 -- D.N. Lynx Crowe 5 | ------------------------------------------------------------------------------ 6 7 | vputa(sbase, row, col, attrib) 8 | unsigned int |sbase, row, col, attrib; 9 10 | Stores attribute value 'attrib' for the character 11 | located at ('row','col') in VSDD RAM starting at 'sbase'. 12 | Assumes a 64 character line and full character attributes. 13 | ------------------------------------------------------------------------------ 14 14 .text 15 * 15 16 16 .xdef _vputa 17 * 18 SBASE .equ 8 *LONG - 'sbase'19 ROW .equ 12 *WORD - 'row'20 COL .equ 14 *WORD - 'col'21 ATTR .equ 16 *WORD - 'attrib'22 * 23 _vputa: link a6,#0 *Link stack frame pointer24 clr.l d0 *Clear out d025 move.w ROW(a6),d0 *Get row26 lsl.l #6,d0 *Multiply by 64 (shift left 6)27 move.w COL(a6),d1 *Get col28 andi.l # $0000003F,d1 *Mask down to 6 bits29 or.l d1,d0 *OR into d0 to get char. #30 move.w d0,d1 * Develop cw = (cn/2)*6 in d131 andi.l # $FFFFFFFE,d1 *...32 move.l d1,d2 *...33 add.l d1,d1 *...34 add.l d2,d1 *...35 add.l SBASE(a6),d1 *Add sbase to cw36 movea.l d1,a0 *a0 points at the word with the char.37 btst.l #0,d0 *Odd char. location ?38 bne vputa1 *Jump if so39 * 40 move.w ATTR(a6),2(a0) *Store new attribute word in video RAM41 * 42 vputax: unlk a6 *Unlink the stack frame43 rts *Done -- return to caller44 * 45 vputa1: move.w ATTR(a6),4(a0) *Store new attribute word in video RAM46 bra vputax *Done -- go return to caller47 * 17 18 SBASE = 8 | LONG - 'sbase' 19 ROW = 12 | WORD - 'row' 20 COL = 14 | WORD - 'col' 21 ATTR = 16 | WORD - 'attrib' 22 23 _vputa: link a6,#0 | Link stack frame pointer 24 clr.l d0 | Clear out d0 25 move.w ROW(a6),d0 | Get row 26 lsl.l #6,d0 | Multiply by 64 (shift left 6) 27 move.w COL(a6),d1 | Get col 28 andi.l #0x0000003F,d1 | Mask down to 6 bits 29 or.l d1,d0 | OR into d0 to get char. # 30 move.w d0,d1 | Develop cw = (cn/2)|6 in d1 31 andi.l #0xFFFFFFFE,d1 | ... 32 move.l d1,d2 | ... 33 add.l d1,d1 | ... 34 add.l d2,d1 | ... 35 add.l SBASE(a6),d1 | Add sbase to cw 36 movea.l d1,a0 | a0 points at the word with the char. 37 btst.l #0,d0 | Odd char. location ? 38 bne vputa1 | Jump if so 39 40 move.w ATTR(a6),2(a0) | Store new attribute word in video RAM 41 42 vputax: unlk a6 | Unlink the stack frame 43 rts | Done -- return to caller 44 45 vputa1: move.w ATTR(a6),4(a0) | Store new attribute word in video RAM 46 bra vputax | Done -- go return to caller 47 48 48 .end -
vlib/vputc.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vputc.s -- store a character and attributes in video RAM3 *Version 3 -- 1987-03-30 -- D.N. Lynx Crowe4 *(c) Copyright 1987 -- D.N. Lynx Crowe5 *------------------------------------------------------------------------------6 * 7 *vputc(sbase, row, col, c, attrib)8 * unsigned int *sbase, row, col, c, attrib;9 * 10 *Stores character c at (row,col) in sbase with11 *attribute value attrib.12 *------------------------------------------------------------------------------13 * 1 | ------------------------------------------------------------------------------ 2 | vputc.s -- store a character and attributes in video RAM 3 | Version 3 -- 1987-03-30 -- D.N. Lynx Crowe 4 | (c) Copyright 1987 -- D.N. Lynx Crowe 5 | ------------------------------------------------------------------------------ 6 7 | vputc(sbase, row, col, c, attrib) 8 | unsigned int |sbase, row, col, c, attrib; 9 10 | Stores character c at (row,col) in sbase with 11 | attribute value attrib. 12 | ------------------------------------------------------------------------------ 13 14 14 .text 15 * 15 16 16 .xdef _vputc 17 * 18 _vputc: link a6,#0 *Link stack frame pointer19 clr.l d0 *Clear out d020 move.w 12(a6),d0 *Get row21 lsl.l #6,d0 *Multiply by 64 (shift left 6)22 move.w 14(a6),d1 *Get col23 andi.l # $0000003F,d1 *Mask down to 6 bits24 or.l d1,d0 *OR into d0 to get char. #25 move.w d0,d1 * Develop cw = (cn/2)*6 in d126 andi.l # $FFFFFFFE,d1 *...27 move.l d1,d2 *...28 lsl.l #1,d1 *...29 add.l d2,d1 *...30 add.l 8(a6),d1 *Add sbase to cw31 movea.l d1,a0 *a0 points at the word with the char.32 btst.l #0,d0 *Odd char. location ?33 bne vputc1 *Jump if so34 * 35 move.w 16(a6),d0 *Get ch36 andi.w # $00FF,d0 *Mask off garbage bits37 move.w (a0),d1 *Get word from video RAM38 andi.w # $FF00,d1 *Mask off old even character39 or.w d0,d1 *OR in the new character40 move.w d1,(a0)+ *Store the updated word in video RAM41 move.w 18(a6),(a0) *Store new attribute word in video RAM42 * 43 vputcx: unlk a6 *Unlink the stack frame44 rts *Return to caller45 * 46 vputc1: move.w 16(a6),d0 *Get ch47 lsl.w #8,d0 *Shift to high (odd) byte48 move.w (a0),d1 *Get word from video RAM49 andi.w # $00FF,d1 *Mask off old odd character50 or.w d0,d1 *OR in the new character51 move.w d1,(a0)+ *Store the updated word in video RAM52 addq.l #2,a0 *Point at the attribute word53 move.w 18(a6),(a0) *Store new attributes in video RAM54 bra vputcx *Done -- go return to caller55 * 17 18 _vputc: link a6,#0 | Link stack frame pointer 19 clr.l d0 | Clear out d0 20 move.w 12(a6),d0 | Get row 21 lsl.l #6,d0 | Multiply by 64 (shift left 6) 22 move.w 14(a6),d1 | Get col 23 andi.l #0x0000003F,d1 | Mask down to 6 bits 24 or.l d1,d0 | OR into d0 to get char. # 25 move.w d0,d1 | Develop cw = (cn/2)|6 in d1 26 andi.l #0xFFFFFFFE,d1 | ... 27 move.l d1,d2 | ... 28 lsl.l #1,d1 | ... 29 add.l d2,d1 | ... 30 add.l 8(a6),d1 | Add sbase to cw 31 movea.l d1,a0 | a0 points at the word with the char. 32 btst.l #0,d0 | Odd char. location ? 33 bne vputc1 | Jump if so 34 35 move.w 16(a6),d0 | Get ch 36 andi.w #0x00FF,d0 | Mask off garbage bits 37 move.w (a0),d1 | Get word from video RAM 38 andi.w #0xFF00,d1 | Mask off old even character 39 or.w d0,d1 | OR in the new character 40 move.w d1,(a0)+ | Store the updated word in video RAM 41 move.w 18(a6),(a0) | Store new attribute word in video RAM 42 43 vputcx: unlk a6 | Unlink the stack frame 44 rts | Return to caller 45 46 vputc1: move.w 16(a6),d0 | Get ch 47 lsl.w #8,d0 | Shift to high (odd) byte 48 move.w (a0),d1 | Get word from video RAM 49 andi.w #0x00FF,d1 | Mask off old odd character 50 or.w d0,d1 | OR in the new character 51 move.w d1,(a0)+ | Store the updated word in video RAM 52 addq.l #2,a0 | Point at the attribute word 53 move.w 18(a6),(a0) | Store new attributes in video RAM 54 bra vputcx | Done -- go return to caller 55 56 56 .end -
vlib/vputcv.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vputcv.s -- store a character and attributes in video RAM3 *Version 1 -- 1988-10-05 -- D.N. Lynx Crowe4 *(c) Copyright 1988 -- D.N. Lynx Crowe5 *------------------------------------------------------------------------------6 * 7 *vputcv(adr, row, col, chr, atr, cols)8 * unsigned int *adr, row, col, chr, atr, cols;9 * 10 *Stores character 'chr' at ('row', 'col') in the11 *full attribute text object at 'adr' with12 *attribute value 'atr' using a line length of 'len'.13 *------------------------------------------------------------------------------14 * 1 | ------------------------------------------------------------------------------ 2 | vputcv.s -- store a character and attributes in video RAM 3 | Version 1 -- 1988-10-05 -- D.N. Lynx Crowe 4 | (c) Copyright 1988 -- D.N. Lynx Crowe 5 | ------------------------------------------------------------------------------ 6 7 | vputcv(adr, row, col, chr, atr, cols) 8 | unsigned int |adr, row, col, chr, atr, cols; 9 10 | Stores character 'chr' at ('row', 'col') in the 11 | full attribute text object at 'adr' with 12 | attribute value 'atr' using a line length of 'len'. 13 | ------------------------------------------------------------------------------ 14 15 15 .text 16 * 16 17 17 .xdef _vputcv 18 * 19 P_ADR .equ820 P_ROW .equ1221 P_COL .equ1422 P_CHR .equ1623 P_ATR .equ1824 P_LEN .equ2025 * 18 19 P_ADR = 8 20 P_ROW = 12 21 P_COL = 14 22 P_CHR = 16 23 P_ATR = 18 24 P_LEN = 20 25 26 26 .page 27 * 28 _vputcv: link a6,#0 *Link stack frame pointer29 move.w P_ROW(a6),d0 *Get row30 mulu P_LEN(a6),d0 *Multiply by len31 clr.l d1 *Clear out d132 move.w P_COL(a6),d1 *Get col33 add.l d1,d0 *Add col into d0 to get char. #34 move.l d0,d1 * Develop cw = (cn/2)*6 in d135 andi.l # $FFFFFFFE,d1 *...36 move.l d1,d2 *...37 add.l d1,d1 *...38 add.l d2,d1 *...39 add.l P_ADR(a6),d1 *Add sbase to cw40 movea.l d1,a0 *a0 points at the word with the char.41 btst.l #0,d0 *Odd char. location ?42 bne vputcv1 *Jump if so43 * 44 move.w P_CHR(a6),d0 *Get chr45 andi.w # $00FF,d0 *Mask off garbage bits46 move.w (a0),d1 *Get word from video RAM47 andi.w # $FF00,d1 *Mask off old even character48 or.w d0,d1 *OR in the new character49 move.w d1,(a0)+ *Store the updated word in video RAM50 bra vputcvx *Done -- go return to caller51 * 52 vputcv1: move.w P_CHR(a6),d0 *Get chr53 lsl.w #8,d0 *Shift to high (odd) byte54 move.w (a0),d1 *Get word from video RAM55 andi.w # $00FF,d1 *Mask off old odd character56 or.w d0,d1 *OR in the new character57 move.w d1,(a0)+ *Store the updated word in video RAM58 addq.l #2,a0 *Point at the attribute word59 * 60 vputcvx: move.w P_ATR(a6),(a0) *Store new attributes in video RAM61 unlk a6 *Unlink the stack frame62 rts *Return to caller63 * 27 28 _vputcv: link a6,#0 | Link stack frame pointer 29 move.w P_ROW(a6),d0 | Get row 30 mulu P_LEN(a6),d0 | Multiply by len 31 clr.l d1 | Clear out d1 32 move.w P_COL(a6),d1 | Get col 33 add.l d1,d0 | Add col into d0 to get char. # 34 move.l d0,d1 | Develop cw = (cn/2)|6 in d1 35 andi.l #0xFFFFFFFE,d1 | ... 36 move.l d1,d2 | ... 37 add.l d1,d1 | ... 38 add.l d2,d1 | ... 39 add.l P_ADR(a6),d1 | Add sbase to cw 40 movea.l d1,a0 | a0 points at the word with the char. 41 btst.l #0,d0 | Odd char. location ? 42 bne vputcv1 | Jump if so 43 44 move.w P_CHR(a6),d0 | Get chr 45 andi.w #0x00FF,d0 | Mask off garbage bits 46 move.w (a0),d1 | Get word from video RAM 47 andi.w #0xFF00,d1 | Mask off old even character 48 or.w d0,d1 | OR in the new character 49 move.w d1,(a0)+ | Store the updated word in video RAM 50 bra vputcvx | Done -- go return to caller 51 52 vputcv1: move.w P_CHR(a6),d0 | Get chr 53 lsl.w #8,d0 | Shift to high (odd) byte 54 move.w (a0),d1 | Get word from video RAM 55 andi.w #0x00FF,d1 | Mask off old odd character 56 or.w d0,d1 | OR in the new character 57 move.w d1,(a0)+ | Store the updated word in video RAM 58 addq.l #2,a0 | Point at the attribute word 59 60 vputcvx: move.w P_ATR(a6),(a0) | Store new attributes in video RAM 61 unlk a6 | Unlink the stack frame 62 rts | Return to caller 63 64 64 .end -
vlib/vputp.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vputp.s -- put a pixel into a 4-bit per pixel bitmap object3 *Version 4 -- 1987-08-04 -- D.N. Lynx Crowe4 *(c) Copyright 1987 -- D.N. Lynx Crowe5 *------------------------------------------------------------------------------6 *int7 *vputp(octad, xloc, yloc, val)8 * struct octent *octad;9 *int xloc, yloc;10 * 11 *Puts the pixel value 'val' at ('xloc','yloc') in the12 *4-bit per pixel bitmap object described by 'octad'.13 * 14 *-----15 *struct octent {16 * 17 *uint ysize,18 *xsize;19 * 20 *int objx,21 *objy;22 * 23 * uint *obase;24 * 25 *char opri,26 *obank;27 * 28 *uint odtw0,29 *odtw1;30 *};31 * 1 | ------------------------------------------------------------------------------ 2 | vputp.s -- put a pixel into a 4-bit per pixel bitmap object 3 | Version 4 -- 1987-08-04 -- D.N. Lynx Crowe 4 | (c) Copyright 1987 -- D.N. Lynx Crowe 5 | ------------------------------------------------------------------------------ 6 | int 7 | vputp(octad, xloc, yloc, val) 8 | struct octent |octad; 9 | int xloc, yloc; 10 11 | Puts the pixel value 'val' at ('xloc','yloc') in the 12 | 4-bit per pixel bitmap object described by 'octad'. 13 14 | ----- 15 | struct octent { 16 17 | uint ysize, 18 | xsize; 19 20 | int objx, 21 | objy; 22 23 | uint |obase; 24 25 | char opri, 26 | obank; 27 28 | uint odtw0, 29 | odtw1; 30 | }; 31 32 32 .text 33 * 33 34 34 .xdef _vputp 35 * 36 OCTAD .equ837 XLOC .equ1238 YLOC .equ1439 VAL .equ1640 * 41 YSIZE .equ042 XSIZE .equ243 OBJX .equ444 OBJY .equ645 OBASE .equ846 OPRI .equ1247 OBANK .equ1348 ODTW0 .equ1449 ODTW1 .equ1650 * 35 36 OCTAD = 8 37 XLOC = 12 38 YLOC = 14 39 VAL = 16 40 41 YSIZE = 0 42 XSIZE = 2 43 OBJX = 4 44 OBJY = 6 45 OBASE = 8 46 OPRI = 12 47 OBANK = 13 48 ODTW0 = 14 49 ODTW1 = 16 50 51 51 .page 52 * 53 _vputp: link a6,#0 *Link stack frames54 movea.l OCTAD(a6),a1 *Get OCTAD base into a155 move.w XLOC(a6),d0 *Get XLOC into d056 cmp.w XSIZE(a1),d0 *Check XLOC range57 bge vputerr *ERROR if too large58 * 59 tst.w d0 *Check XLOC sign60 bmi vputerr *ERROR if negative61 * 62 move.w YLOC(a6),d1 *Get YLOC into d1 to test63 cmp.w YSIZE(a1),d1 *Check YLOC range64 bge vputerr *ERROR if too large65 * 66 tst.w d1 *Check YLOC sign67 bmi vputerr *ERROR if negative68 * 69 lsr.w #2,d0 *Divide XLOC by 470 move.w XSIZE(a1),d1 *Get width into d171 lsr.w #2,d1 *Divide width by 472 mulu YLOC(a6),d1 *Multiply width/4 by YLOC73 ext.l d0 *Extend XLOC/4 to a long74 add.l d0,d1 *... and add it to d175 lsl.l #1,d1 *Make d1 a word offset76 add.l OBASE(a1),d1 *Add OBASE to d177 movea.l d1,a0 *Make a0 point at bitmap data78 move.w XLOC(a6),d0 *Get XLOC79 andi.l # $03,d0 *Mask to low 2 bits80 add.l d0,d0 *Multiply by 2 for word index81 move.l d0,d1 *Save index in d182 add.l #MTAB,d0 *Add mask table base83 movea.l d0,a2 *a2 points at mask84 add.l #STAB,d1 *Add shift table base to index85 move.l d1,a1 *a1 points at shift count86 move.w (a1),d0 *Get shift count in d087 move.w VAL(a6),d1 *Get new pixel in d188 andi.w # $0F,d1 *Mask down to 4 bits89 lsl.w d0,d1 *Shift into position for OR90 move.w (a0),d0 *Get old bitmap word in d091 and.w (a2),d0 *Mask out old pixel92 or.w d1,d0 *OR in new pixel93 move.w d0,(a0) *Store updated word in bitmap94 clr.l d0 *Set return value = 0 = OK95 * 96 vputexit: unlk a6 *Unlink stack frame97 rts *Return to caller98 * 99 vputerr: moveq.l #-1,d0 *Set return value = -1 = ERROR100 bra vputexit *Go unlink stack and return101 * 52 53 _vputp: link a6,#0 | Link stack frames 54 movea.l OCTAD(a6),a1 | Get OCTAD base into a1 55 move.w XLOC(a6),d0 | Get XLOC into d0 56 cmp.w XSIZE(a1),d0 | Check XLOC range 57 bge vputerr | ERROR if too large 58 59 tst.w d0 | Check XLOC sign 60 bmi vputerr | ERROR if negative 61 62 move.w YLOC(a6),d1 | Get YLOC into d1 to test 63 cmp.w YSIZE(a1),d1 | Check YLOC range 64 bge vputerr | ERROR if too large 65 66 tst.w d1 | Check YLOC sign 67 bmi vputerr | ERROR if negative 68 69 lsr.w #2,d0 | Divide XLOC by 4 70 move.w XSIZE(a1),d1 | Get width into d1 71 lsr.w #2,d1 | Divide width by 4 72 mulu YLOC(a6),d1 | Multiply width/4 by YLOC 73 ext.l d0 | Extend XLOC/4 to a long 74 add.l d0,d1 | ... and add it to d1 75 lsl.l #1,d1 | Make d1 a word offset 76 add.l OBASE(a1),d1 | Add OBASE to d1 77 movea.l d1,a0 | Make a0 point at bitmap data 78 move.w XLOC(a6),d0 | Get XLOC 79 andi.l #0x03,d0 | Mask to low 2 bits 80 add.l d0,d0 | Multiply by 2 for word index 81 move.l d0,d1 | Save index in d1 82 add.l #MTAB,d0 | Add mask table base 83 movea.l d0,a2 | a2 points at mask 84 add.l #STAB,d1 | Add shift table base to index 85 move.l d1,a1 | a1 points at shift count 86 move.w (a1),d0 | Get shift count in d0 87 move.w VAL(a6),d1 | Get new pixel in d1 88 andi.w #0x0F,d1 | Mask down to 4 bits 89 lsl.w d0,d1 | Shift into position for OR 90 move.w (a0),d0 | Get old bitmap word in d0 91 and.w (a2),d0 | Mask out old pixel 92 or.w d1,d0 | OR in new pixel 93 move.w d0,(a0) | Store updated word in bitmap 94 clr.l d0 | Set return value = 0 = OK 95 96 vputexit: unlk a6 | Unlink stack frame 97 rts | Return to caller 98 99 vputerr: moveq.l #-1,d0 | Set return value = -1 = ERROR 100 bra vputexit | Go unlink stack and return 101 102 102 .page 103 * 103 104 104 .data 105 * 106 MTAB: dc.w $FFF0,$FF0F,$F0FF,$0FFF *Mask table107 STAB: dc.w 0,4,8,12 *Shift table108 * 105 106 MTAB: dc.w 0xFFF0,0xFF0F,0xF0FF,0x0FFF | Mask table 107 STAB: dc.w 0,4,8,12 | Shift table 108 109 109 .end -
vlib/vsetav.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vsetav.s -- set a character's attributes in video RAM3 *Version 1 -- 1988-10-11 -- D.N. Lynx Crowe4 *(c) Copyright 1988 -- D.N. Lynx Crowe5 *------------------------------------------------------------------------------6 * 7 *vsetav(adr, row, col, atr, len)8 * unsigned int *adr, row, col, atr, len;9 * 10 *Sets attribute 'atr' at ('row', 'col') in the11 *full attribute text object at 'adr'12 *using a line length of 'len'.13 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | vsetav.s -- set a character's attributes in video RAM 3 | Version 1 -- 1988-10-11 -- D.N. Lynx Crowe 4 | (c) Copyright 1988 -- D.N. Lynx Crowe 5 | ------------------------------------------------------------------------------ 6 7 | vsetav(adr, row, col, atr, len) 8 | unsigned int |adr, row, col, atr, len; 9 10 | Sets attribute 'atr' at ('row', 'col') in the 11 | full attribute text object at 'adr' 12 | using a line length of 'len'. 13 | ------------------------------------------------------------------------------ 14 14 .text 15 * 15 16 16 .xdef _vsetav 17 * 18 P_ADR .equ819 P_ROW .equ1220 P_COL .equ1421 P_ATR .equ1622 P_LEN .equ1823 * 24 _vsetav: link a6,#0 *Link stack frame pointer25 move.w P_ROW(a6),d0 *Get row26 mulu P_LEN(a6),d0 *Multiply by len27 clr.l d1 *Clear out d128 move.w P_COL(a6),d1 *Get col29 add.l d1,d0 *Add col into d0 to get char. #30 move.l d0,d1 * Develop cw = (cn/2)*6 in d131 andi.l # $FFFFFFFE,d1 *...32 move.l d1,d2 *...33 add.l d1,d1 *...34 add.l d2,d1 *...35 add.l P_ADR(a6),d1 *Add sbase to cw36 movea.l d1,a0 *a0 points at the word with the char.37 btst.l #0,d0 *Odd char. location ?38 bne vsetav1 *Jump if so39 * 40 addq.l #2,a0 *Point at the attribute word41 bra vsetavx *Go set attribute42 * 43 vsetav1: addq.l #4,a0 *Point at the attribute word44 * 45 vsetavx: move.w P_ATR(a6),d0 *Get new attributes46 or.w d0,(a0) *Set new attributes in video RAM47 unlk a6 *Unlink the stack frame48 rts *Return to caller49 * 17 18 P_ADR = 8 19 P_ROW = 12 20 P_COL = 14 21 P_ATR = 16 22 P_LEN = 18 23 24 _vsetav: link a6,#0 | Link stack frame pointer 25 move.w P_ROW(a6),d0 | Get row 26 mulu P_LEN(a6),d0 | Multiply by len 27 clr.l d1 | Clear out d1 28 move.w P_COL(a6),d1 | Get col 29 add.l d1,d0 | Add col into d0 to get char. # 30 move.l d0,d1 | Develop cw = (cn/2)|6 in d1 31 andi.l #0xFFFFFFFE,d1 | ... 32 move.l d1,d2 | ... 33 add.l d1,d1 | ... 34 add.l d2,d1 | ... 35 add.l P_ADR(a6),d1 | Add sbase to cw 36 movea.l d1,a0 | a0 points at the word with the char. 37 btst.l #0,d0 | Odd char. location ? 38 bne vsetav1 | Jump if so 39 40 addq.l #2,a0 | Point at the attribute word 41 bra vsetavx | Go set attribute 42 43 vsetav1: addq.l #4,a0 | Point at the attribute word 44 45 vsetavx: move.w P_ATR(a6),d0 | Get new attributes 46 or.w d0,(a0) | Set new attributes in video RAM 47 unlk a6 | Unlink the stack frame 48 rts | Return to caller 49 50 50 .end -
vlib/vsetcv.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vsetcv.s -- set a character's colors in video RAM3 *Version 1 -- 1988-10-11 -- D.N. Lynx Crowe4 *(c) Copyright 1988 -- D.N. Lynx Crowe5 *------------------------------------------------------------------------------6 * 7 *vsetcv(adr, row, col, cfb, len)8 * unsigned int *adr, row, col, cfb, len;9 * 10 *Sets colors 'cfb' at ('row', 'col') in the11 *full attribute text object at 'adr'12 *using a line length of 'len'.13 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | vsetcv.s -- set a character's colors in video RAM 3 | Version 1 -- 1988-10-11 -- D.N. Lynx Crowe 4 | (c) Copyright 1988 -- D.N. Lynx Crowe 5 | ------------------------------------------------------------------------------ 6 7 | vsetcv(adr, row, col, cfb, len) 8 | unsigned int |adr, row, col, cfb, len; 9 10 | Sets colors 'cfb' at ('row', 'col') in the 11 | full attribute text object at 'adr' 12 | using a line length of 'len'. 13 | ------------------------------------------------------------------------------ 14 14 .text 15 * 15 16 16 .xdef _vsetcv 17 * 18 P_ADR .equ819 P_ROW .equ1220 P_COL .equ1421 P_CFB .equ1622 P_LEN .equ1823 * 24 _vsetcv: link a6,#0 *Link stack frame pointer25 move.w P_ROW(a6),d0 *Get row26 mulu P_LEN(a6),d0 *Multiply by len27 clr.l d1 *Clear out d128 move.w P_COL(a6),d1 *Get col29 add.l d1,d0 *Add col into d0 to get char. #30 move.l d0,d1 * Develop cw = (cn/2)*6 in d131 andi.l # $FFFFFFFE,d1 *...32 move.l d1,d2 *...33 add.l d1,d1 *...34 add.l d2,d1 *...35 add.l P_ADR(a6),d1 *Add sbase to cw36 movea.l d1,a0 *a0 points at the word with the char.37 btst.l #0,d0 *Odd char. location ?38 bne vsetcv1 *Jump if so39 * 40 addq.l #2,a0 *Point at the attribute word41 bra vsetcvx *Go set attribute42 * 43 vsetcv1: addq.l #4,a0 *Point at the attribute word44 * 45 vsetcvx: move.w (a0),d0 *Get old attributes46 andi.w # $FF00,d0 *Remove old colors47 or.w P_CFB(a6),d0 *Get new colors48 move.w d0,(a0) *Set new attributes in video RAM49 unlk a6 *Unlink the stack frame50 rts *Return to caller51 * 17 18 P_ADR = 8 19 P_ROW = 12 20 P_COL = 14 21 P_CFB = 16 22 P_LEN = 18 23 24 _vsetcv: link a6,#0 | Link stack frame pointer 25 move.w P_ROW(a6),d0 | Get row 26 mulu P_LEN(a6),d0 | Multiply by len 27 clr.l d1 | Clear out d1 28 move.w P_COL(a6),d1 | Get col 29 add.l d1,d0 | Add col into d0 to get char. # 30 move.l d0,d1 | Develop cw = (cn/2)|6 in d1 31 andi.l #0xFFFFFFFE,d1 | ... 32 move.l d1,d2 | ... 33 add.l d1,d1 | ... 34 add.l d2,d1 | ... 35 add.l P_ADR(a6),d1 | Add sbase to cw 36 movea.l d1,a0 | a0 points at the word with the char. 37 btst.l #0,d0 | Odd char. location ? 38 bne vsetcv1 | Jump if so 39 40 addq.l #2,a0 | Point at the attribute word 41 bra vsetcvx | Go set attribute 42 43 vsetcv1: addq.l #4,a0 | Point at the attribute word 44 45 vsetcvx: move.w (a0),d0 | Get old attributes 46 andi.w #0xFF00,d0 | Remove old colors 47 or.w P_CFB(a6),d0 | Get new colors 48 move.w d0,(a0) | Set new attributes in video RAM 49 unlk a6 | Unlink the stack frame 50 rts | Return to caller 51 52 52 .end -
vlib/vsplot4.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vsplot4.s -- output characters to a 4-bit / pixel graphics window3 *with variable vertical pitch, etc.4 *Version 1 -- 1988-10-07 -- D.N. Lynx Crowe5 *(c) Copyright 1988 -- D.N. Lynx Crowe6 *------------------------------------------------------------------------------7 * 8 *vsplot4(obase, nw, fg, row, col, str, pitch, ht, cgtab)9 * uint *obase, nw, fg, row, col, pitch, ht, cgtab[][256];10 * char *str;11 * 12 *Outputs characters from the string at 'str' to an 'nw'13 *character wide 4-bit per pixel graphics window at 'obase'14 *at ('row','col'), using 'fg' as the foreground color.15 *Uses cgtab[][256] as the VSDD formatted character16 *generator table. Assumes 'ht' bit high characters in the17 *cgtable. Uses 'pitch' as the vertical spacing between18 *character rows. No error checks are done.19 *The string must fit the output area (no overlaps, single line).20 *This function leaves the zero pixels alone and just sets the21 *one pixels to the foreground color, allowing overlapping22 *character cells.23 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | vsplot4.s -- output characters to a 4-bit / pixel graphics window 3 | with variable vertical pitch, etc. 4 | Version 1 -- 1988-10-07 -- D.N. Lynx Crowe 5 | (c) Copyright 1988 -- D.N. Lynx Crowe 6 | ------------------------------------------------------------------------------ 7 8 | vsplot4(obase, nw, fg, row, col, str, pitch, ht, cgtab) 9 | uint |obase, nw, fg, row, col, pitch, ht, cgtab[][256]; 10 | char |str; 11 12 | Outputs characters from the string at 'str' to an 'nw' 13 | character wide 4-bit per pixel graphics window at 'obase' 14 | at ('row','col'), using 'fg' as the foreground color. 15 | Uses cgtab[][256] as the VSDD formatted character 16 | generator table. Assumes 'ht' bit high characters in the 17 | cgtable. Uses 'pitch' as the vertical spacing between 18 | character rows. No error checks are done. 19 | The string must fit the output area (no overlaps, single line). 20 | This function leaves the zero pixels alone and just sets the 21 | one pixels to the foreground color, allowing overlapping 22 | character cells. 23 | ------------------------------------------------------------------------------ 24 24 .text 25 * 25 26 26 .xdef _vsplot4 27 * 28 *Argument offsets from a6:29 * 30 OBASE .equ 8 *LONG - Output area base address31 NW .equ 12 *WORD - Character width of output area32 FG .equ 14 *WORD - Foreground color33 ROW .equ 16 *WORD - Row34 COL .equ 18 *WORD - Column35 STR .equ 20 *LONG - String base address36 PITCH .equ 24 *WORD - Vertical spacing between rows37 HT .equ 26 *WORD - Character height38 CGTAB .equ 28 *LONG - Character generator pionter39 * 40 *Program constant definitions:41 * 42 HPIX .equ 8 *Character width in pixels43 HCW .equ 4 *Horizontal character width (bytes)44 PSHIFT .equ 12 *Pixel shift into MS bits45 HSHIFT .equ 4 *Pixel right shift46 * 27 28 | Argument offsets from a6: 29 30 OBASE = 8 | LONG - Output area base address 31 NW = 12 | WORD - Character width of output area 32 FG = 14 | WORD - Foreground color 33 ROW = 16 | WORD - Row 34 COL = 18 | WORD - Column 35 STR = 20 | LONG - String base address 36 PITCH = 24 | WORD - Vertical spacing between rows 37 HT = 26 | WORD - Character height 38 CGTAB = 28 | LONG - Character generator pionter 39 40 | Program constant definitions: 41 42 HPIX = 8 | Character width in pixels 43 HCW = 4 | Horizontal character width (bytes) 44 PSHIFT = 12 | Pixel shift into MS bits 45 HSHIFT = 4 | Pixel right shift 46 47 47 .page 48 * 49 *Register usage:50 * 51 *d0 output word and scratch52 *d1 CG word and scratch53 *d2 pixel counter54 * 55 *d3 foreground color (in the 4 ms bits)56 *d4 background color (in the 4 ms bits)57 *d5 width of the area in bytes58 *d6 scan line counter59 * 60 *a0 CG table pointer61 *a1 output area scan line pointer62 *a2 input string character pointer63 * 64 *a3 output area character base pointer65 * 66 *a6 frame pointer67 *a7 stack pointer68 * 48 49 | Register usage: 50 51 | d0 output word and scratch 52 | d1 CG word and scratch 53 | d2 pixel counter 54 55 | d3 foreground color (in the 4 ms bits) 56 | d4 background color (in the 4 ms bits) 57 | d5 width of the area in bytes 58 | d6 scan line counter 59 60 | a0 CG table pointer 61 | a1 output area scan line pointer 62 | a2 input string character pointer 63 64 | a3 output area character base pointer 65 66 | a6 frame pointer 67 | a7 stack pointer 68 69 69 .page 70 * 71 _vsplot4: link a6,#0 *Link stack frames72 movem.l d3-d6/a3,-(a7) *Save registers we use73 move.w #PSHIFT,d1 *Set shift constant74 move.w FG(a6),d3 *Setup foreground color75 lsl.w d1,d3 *... in ms 4 bits of d3.W76 move.w NW(a6),d5 *Get line width in d5.W77 lsl.w #2,d5 *Multiply width by 4 for offset78 move.w ROW(a6),d0 *Calculate output address79 move.w PITCH(a6),d1 *... PITCH80 mulu d1,d0 * ... *ROW81 add.w HT(a6),d0 *... + HT-182 subq.w #1,d0 *...83 mulu d5,d0 * ... *NW84 clr.l d1 *...85 move.w COL(a6),d1 * ... +86 lsl.w #2,d1 * ... COL *487 add.l d1,d0 *...88 add.l OBASE(a6),d0 *... + OBASE89 movea.l d0,a3 *Leave output address in a390 movea.l STR(a6),a2 *Put string address in a291 * 92 cgl0: clr.l d0 *Clear out upper bits of d093 move.b (a2)+,d0 *Get next character94 beq cgl5 *Done if character EQ 095 * 96 movea.l a3,a1 *Establish output pointer in a197 adda.l #HCW,a3 *Update output pointer for next char.98 movea.l CGTAB(a6),a0 *Establish CG pointer in a099 lsl.w #1,d0 * ... 2 *character100 adda.w d0,a0 *... + cgtab address101 move.w HT(a6),d6 *Set scan line counter in d6102 subq.w #1,d6 *...103 * 70 71 _vsplot4: link a6,#0 | Link stack frames 72 movem.l d3-d6/a3,-(a7) | Save registers we use 73 move.w #PSHIFT,d1 | Set shift constant 74 move.w FG(a6),d3 | Setup foreground color 75 lsl.w d1,d3 | ... in ms 4 bits of d3.W 76 move.w NW(a6),d5 | Get line width in d5.W 77 lsl.w #2,d5 | Multiply width by 4 for offset 78 move.w ROW(a6),d0 | Calculate output address 79 move.w PITCH(a6),d1 | ... PITCH 80 mulu d1,d0 | ... | ROW 81 add.w HT(a6),d0 | ... + HT-1 82 subq.w #1,d0 | ... 83 mulu d5,d0 | ... | NW 84 clr.l d1 | ... 85 move.w COL(a6),d1 | ... + 86 lsl.w #2,d1 | ... COL | 4 87 add.l d1,d0 | ... 88 add.l OBASE(a6),d0 | ... + OBASE 89 movea.l d0,a3 | Leave output address in a3 90 movea.l STR(a6),a2 | Put string address in a2 91 92 cgl0: clr.l d0 | Clear out upper bits of d0 93 move.b (a2)+,d0 | Get next character 94 beq cgl5 | Done if character EQ 0 95 96 movea.l a3,a1 | Establish output pointer in a1 97 adda.l #HCW,a3 | Update output pointer for next char. 98 movea.l CGTAB(a6),a0 | Establish CG pointer in a0 99 lsl.w #1,d0 | ... 2 | character 100 adda.w d0,a0 | ... + cgtab address 101 move.w HT(a6),d6 | Set scan line counter in d6 102 subq.w #1,d6 | ... 103 104 104 .page 105 cgl1: move.w (a0),d1 *Get character generator word in d1106 move.w #(HPIX/2)-1,d2 *Set pixel counter in d2107 clr.l d4 *Get old output word as background108 move.w (a1),d4 *...109 swap d4 *...110 * 111 cgl2: lsr.w #HSHIFT,d0 *Shift output word right 1 pixel112 lsr.l #HSHIFT,d4 *Shift background word 1 pixel113 andi.l # $FFFFF000,d4 *Mask for upper 4 bits of d4.W114 btst.l #0,d1 *Check CG word ls bit115 beq cgl3 *Set background color if bit EQ 0116 * 117 or.w d3,d0 *OR foreground color into output word118 bra cgl4 *Go update CG word119 * 120 cgl3: or.w d4,d0 *OR background color into output word121 * 122 cgl4: lsr.w #1,d1 *Shift CG word right 1 pixel123 dbf d2,cgl2 *Loop for first 4 pixels124 * 125 move.w d0,(a1)+ *Store first output word in scan line126 move.w #(HPIX/2)-1,d2 *Set pixel counter in d2127 clr.l d4 *Get old output word as background128 move.w (a1),d4 *...129 swap d4 *...130 * 131 cgl2a: lsr.w #HSHIFT,d0 *Shift output word right 1 pixel132 lsr.l #HSHIFT,d4 *Shift background word 1 pixel133 andi.l # $FFFFF000,d4 *Mask for upper bits of d4.W134 btst.l #0,d1 *Check CG word ls bit135 beq cgl3a *Set background color if bit EQ 0136 * 137 or.w d3,d0 *OR foreground color into output word138 bra cgl4a *Go update CG word139 * 140 cgl3a: or.w d4,d0 *OR background color into output word141 * 142 cgl4a: lsr.w #1,d1 *Shift CG word right 1 pixel143 dbf d2,cgl2a *Loop for last 4 pixels144 * 145 move.w d0,(a1) *Store second output word in scan line146 suba.w d5,a1 *Update output pointer147 suba.w #2,a1 *...148 adda.l #512,a0 *Update CG pointer for next scan line149 dbf d6,cgl1 *Loop for all scan lines150 * 151 bra cgl0 *Loop for next character152 * 153 cgl5: movem.l (a7)+,d3-d6/a3 *Restore registers154 unlk a6 *Unlink stack frames155 rts *Return to caller156 * 105 cgl1: move.w (a0),d1 | Get character generator word in d1 106 move.w #(HPIX/2)-1,d2 | Set pixel counter in d2 107 clr.l d4 | Get old output word as background 108 move.w (a1),d4 | ... 109 swap d4 | ... 110 111 cgl2: lsr.w #HSHIFT,d0 | Shift output word right 1 pixel 112 lsr.l #HSHIFT,d4 | Shift background word 1 pixel 113 andi.l #0xFFFFF000,d4 | Mask for upper 4 bits of d4.W 114 btst.l #0,d1 | Check CG word ls bit 115 beq cgl3 | Set background color if bit EQ 0 116 117 or.w d3,d0 | OR foreground color into output word 118 bra cgl4 | Go update CG word 119 120 cgl3: or.w d4,d0 | OR background color into output word 121 122 cgl4: lsr.w #1,d1 | Shift CG word right 1 pixel 123 dbf d2,cgl2 | Loop for first 4 pixels 124 125 move.w d0,(a1)+ | Store first output word in scan line 126 move.w #(HPIX/2)-1,d2 | Set pixel counter in d2 127 clr.l d4 | Get old output word as background 128 move.w (a1),d4 | ... 129 swap d4 | ... 130 131 cgl2a: lsr.w #HSHIFT,d0 | Shift output word right 1 pixel 132 lsr.l #HSHIFT,d4 | Shift background word 1 pixel 133 andi.l #0xFFFFF000,d4 | Mask for upper bits of d4.W 134 btst.l #0,d1 | Check CG word ls bit 135 beq cgl3a | Set background color if bit EQ 0 136 137 or.w d3,d0 | OR foreground color into output word 138 bra cgl4a | Go update CG word 139 140 cgl3a: or.w d4,d0 | OR background color into output word 141 142 cgl4a: lsr.w #1,d1 | Shift CG word right 1 pixel 143 dbf d2,cgl2a | Loop for last 4 pixels 144 145 move.w d0,(a1) | Store second output word in scan line 146 suba.w d5,a1 | Update output pointer 147 suba.w #2,a1 | ... 148 adda.l #512,a0 | Update CG pointer for next scan line 149 dbf d6,cgl1 | Loop for all scan lines 150 151 bra cgl0 | Loop for next character 152 153 cgl5: movem.l (a7)+,d3-d6/a3 | Restore registers 154 unlk a6 | Unlink stack frames 155 rts | Return to caller 156 157 157 .end -
vlib/vvputsv.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vvputsv.s -- output characters to a 4-bit / pixel graphics window3 *with variable vertical pitch4 *Version 1 -- 1988-10-07 -- D.N. Lynx Crowe5 *(c) Copyright 1988 -- D.N. Lynx Crowe6 *------------------------------------------------------------------------------7 * 8 *vvputsv(obase, nw, fg, bg, row, col, str, pitch, ht, cgtab)9 * uint *obase, nw, fg, bg, row, col, pitch, ht, cgtab[][256];10 * char *str;11 * 12 *Outputs characters from the string at 'str' to an 'nw'13 *character wide 4-bit per pixel graphics window at 'obase'14 *at ('row','col'), using 'fg' as the foreground color, and15 *'bg' as the background color. Uses cgtab[][256] as the16 *VSDD formatted character generator table. Assumes 'ht' line17 *high characters in the cg table. Uses 'pitch' as the vertical18 *spacing between character rows. No error checks are done.19 *The string must fit the output area (no overlaps, single line).20 * 21 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | vvputsv.s -- output characters to a 4-bit / pixel graphics window 3 | with variable vertical pitch 4 | Version 1 -- 1988-10-07 -- D.N. Lynx Crowe 5 | (c) Copyright 1988 -- D.N. Lynx Crowe 6 | ------------------------------------------------------------------------------ 7 8 | vvputsv(obase, nw, fg, bg, row, col, str, pitch, ht, cgtab) 9 | uint |obase, nw, fg, bg, row, col, pitch, ht, cgtab[][256]; 10 | char |str; 11 12 | Outputs characters from the string at 'str' to an 'nw' 13 | character wide 4-bit per pixel graphics window at 'obase' 14 | at ('row','col'), using 'fg' as the foreground color, and 15 | 'bg' as the background color. Uses cgtab[][256] as the 16 | VSDD formatted character generator table. Assumes 'ht' line 17 | high characters in the cg table. Uses 'pitch' as the vertical 18 | spacing between character rows. No error checks are done. 19 | The string must fit the output area (no overlaps, single line). 20 21 | ------------------------------------------------------------------------------ 22 22 .text 23 * 23 24 24 .xdef _vvputsv 25 * 26 *Argument offsets from a6:27 * 28 OBASE .equ 8 *LONG - Output area base address29 NW .equ 12 *WORD - Character width of output area30 FG .equ 14 *WORD - Foreground color31 BG .equ 16 *WORD - Background color32 ROW .equ 18 *WORD - Row33 COL .equ 20 *WORD - Column34 STR .equ 22 *LONG - String base address35 PITCH .equ 26 *WORD - Vertical spacing between rows36 HT .equ 28 *WORD - Character height (LE PITCH)37 CGTAB .equ 30 *LONG - Character generator table38 * 39 *Program constant definitions:40 * 41 HPIX .equ 8 *Character width in pixels42 HCW .equ 4 *Horizontal character width (bytes)43 PSHIFT .equ 12 *Pixel shift into MS bits44 HSHIFT .equ 4 *Pixel right shift45 * 25 26 | Argument offsets from a6: 27 28 OBASE = 8 | LONG - Output area base address 29 NW = 12 | WORD - Character width of output area 30 FG = 14 | WORD - Foreground color 31 BG = 16 | WORD - Background color 32 ROW = 18 | WORD - Row 33 COL = 20 | WORD - Column 34 STR = 22 | LONG - String base address 35 PITCH = 26 | WORD - Vertical spacing between rows 36 HT = 28 | WORD - Character height (LE PITCH) 37 CGTAB = 30 | LONG - Character generator table 38 39 | Program constant definitions: 40 41 HPIX = 8 | Character width in pixels 42 HCW = 4 | Horizontal character width (bytes) 43 PSHIFT = 12 | Pixel shift into MS bits 44 HSHIFT = 4 | Pixel right shift 45 46 46 .page 47 * 48 *Register usage:49 * 50 *d0 output word and scratch51 *d1 CG word and scratch52 *d2 pixel counter53 * 54 *d3 foreground color (in the 4 ms bits)55 *d4 background color (in the 4 ms bits)56 *d5 width of the area in bytes57 *d6 scan line counter58 * 59 *a0 CG table pointer60 *a1 output area scan line pointer61 *a2 input string character pointer62 * 63 *a3 output area character base pointer64 * 65 *a6 frame pointer66 *a7 stack pointer67 * 47 48 | Register usage: 49 50 | d0 output word and scratch 51 | d1 CG word and scratch 52 | d2 pixel counter 53 54 | d3 foreground color (in the 4 ms bits) 55 | d4 background color (in the 4 ms bits) 56 | d5 width of the area in bytes 57 | d6 scan line counter 58 59 | a0 CG table pointer 60 | a1 output area scan line pointer 61 | a2 input string character pointer 62 63 | a3 output area character base pointer 64 65 | a6 frame pointer 66 | a7 stack pointer 67 68 68 .page 69 * 70 _vvputsv: link a6,#0 *Link stack frames71 movem.l d3-d6/a3,-(a7) *Save registers we use72 move.w #PSHIFT,d1 *Set shift constant73 move.w FG(a6),d3 *Setup foreground color74 lsl.w d1,d3 *... in ms 4 bits of d3.W75 move.w BG(a6),d4 *Setup background color76 lsl.w d1,d4 *... in ms 4 bits of d4.W77 move.w NW(a6),d5 *Get line width in d5.W78 lsl.w #2,d5 *Multiply width by 4 for offset79 move.w ROW(a6),d0 *Calculate output address80 move.w PITCH(a6),d1 *... PITCH81 mulu d1,d0 * ... *ROW82 add.w #HT(a6),d0 *... + HT-183 subq.w #1,d0 *...84 mulu d5,d0 * ... *NW85 clr.l d1 *...86 move.w COL(a6),d1 * ... +87 lsl.w #2,d1 * ... COL *488 add.l d1,d0 *...89 add.l OBASE(a6),d0 *... + OBASE90 movea.l d0,a3 *Leave output address in a391 movea.l STR(a6),a2 *Put string address in a292 * 93 cgl0: clr.l d0 *Clear out upper bits of d094 move.b (a2)+,d0 *Get next character95 beq cgl5 *Done if character EQ 096 * 97 movea.l a3,a1 *Establish output pointer in a198 adda.l #HCW,a3 *Update output pointer for next char.99 movea.l CGTAB(a6),a0 *Establish CG pointer in a0100 lsl.w #1,d0 * ... 2 *character101 adda.w d0,a0 *... + cg table address102 move.w HT(a6),d6 *Set scan line counter in d6103 subq.w #1,d6 *... to HT-1104 * 69 70 _vvputsv: link a6,#0 | Link stack frames 71 movem.l d3-d6/a3,-(a7) | Save registers we use 72 move.w #PSHIFT,d1 | Set shift constant 73 move.w FG(a6),d3 | Setup foreground color 74 lsl.w d1,d3 | ... in ms 4 bits of d3.W 75 move.w BG(a6),d4 | Setup background color 76 lsl.w d1,d4 | ... in ms 4 bits of d4.W 77 move.w NW(a6),d5 | Get line width in d5.W 78 lsl.w #2,d5 | Multiply width by 4 for offset 79 move.w ROW(a6),d0 | Calculate output address 80 move.w PITCH(a6),d1 | ... PITCH 81 mulu d1,d0 | ... | ROW 82 add.w HT(a6),d0 | ... + HT-1 83 subq.w #1,d0 | ... 84 mulu d5,d0 | ... | NW 85 clr.l d1 | ... 86 move.w COL(a6),d1 | ... + 87 lsl.w #2,d1 | ... COL | 4 88 add.l d1,d0 | ... 89 add.l OBASE(a6),d0 | ... + OBASE 90 movea.l d0,a3 | Leave output address in a3 91 movea.l STR(a6),a2 | Put string address in a2 92 93 cgl0: clr.l d0 | Clear out upper bits of d0 94 move.b (a2)+,d0 | Get next character 95 beq cgl5 | Done if character EQ 0 96 97 movea.l a3,a1 | Establish output pointer in a1 98 adda.l #HCW,a3 | Update output pointer for next char. 99 movea.l CGTAB(a6),a0 | Establish CG pointer in a0 100 lsl.w #1,d0 | ... 2 | character 101 adda.w d0,a0 | ... + cg table address 102 move.w HT(a6),d6 | Set scan line counter in d6 103 subq.w #1,d6 | ... to HT-1 104 105 105 .page 106 cgl1: move.w (a0),d1 *Get character generator word in d1107 move.w #(HPIX/2)-1,d2 *Set pixel counter in d2108 * 109 cgl2: lsr.w #HSHIFT,d0 *Shift output word right 1 pixel110 btst.l #0,d1 *Check CG word ls bit111 beq cgl3 *Set background color if bit EQ 0112 * 113 or.w d3,d0 *OR foreground color into output word114 bra cgl4 *Go update CG word115 * 116 cgl3: or.w d4,d0 *OR background color into output word117 * 118 cgl4: lsr.w #1,d1 *Shift CG word right 1 pixel119 dbf d2,cgl2 *Loop for first 4 pixels120 * 121 move.w d0,(a1)+ *Store first output word in scan line122 move.w #(HPIX/2)-1,d2 *Set pixel counter in d2123 * 124 cgl2a: lsr.w #HSHIFT,d0 *Shift output word right 1 pixel125 btst.l #0,d1 *Check CG word ls bit126 beq cgl3a *Set background color if bit EQ 0127 * 128 or.w d3,d0 *OR foreground color into output word129 bra cgl4a *Go update CG word130 * 131 cgl3a: or.w d4,d0 *OR background color into output word132 * 133 cgl4a: lsr.w #1,d1 *Shift CG word right 1 pixel134 dbf d2,cgl2a *Loop for last 4 pixels135 * 136 move.w d0,(a1) *Store second output word in scan line137 suba.w d5,a1 *Update output pointer138 suba.w #2,a1 *...139 adda.l #512,a0 *Update CG pointer for next scan line140 dbf d6,cgl1 *Loop for all scan lines141 * 142 bra cgl0 *Loop for next character143 * 144 cgl5: movem.l (a7)+,d3-d6/a3 *Restore registers145 unlk a6 *Unlink stack frames146 rts *Return to caller147 * 106 cgl1: move.w (a0),d1 | Get character generator word in d1 107 move.w #(HPIX/2)-1,d2 | Set pixel counter in d2 108 109 cgl2: lsr.w #HSHIFT,d0 | Shift output word right 1 pixel 110 btst.l #0,d1 | Check CG word ls bit 111 beq cgl3 | Set background color if bit EQ 0 112 113 or.w d3,d0 | OR foreground color into output word 114 bra cgl4 | Go update CG word 115 116 cgl3: or.w d4,d0 | OR background color into output word 117 118 cgl4: lsr.w #1,d1 | Shift CG word right 1 pixel 119 dbf d2,cgl2 | Loop for first 4 pixels 120 121 move.w d0,(a1)+ | Store first output word in scan line 122 move.w #(HPIX/2)-1,d2 | Set pixel counter in d2 123 124 cgl2a: lsr.w #HSHIFT,d0 | Shift output word right 1 pixel 125 btst.l #0,d1 | Check CG word ls bit 126 beq cgl3a | Set background color if bit EQ 0 127 128 or.w d3,d0 | OR foreground color into output word 129 bra cgl4a | Go update CG word 130 131 cgl3a: or.w d4,d0 | OR background color into output word 132 133 cgl4a: lsr.w #1,d1 | Shift CG word right 1 pixel 134 dbf d2,cgl2a | Loop for last 4 pixels 135 136 move.w d0,(a1) | Store second output word in scan line 137 suba.w d5,a1 | Update output pointer 138 suba.w #2,a1 | ... 139 adda.l #512,a0 | Update CG pointer for next scan line 140 dbf d6,cgl1 | Loop for all scan lines 141 142 bra cgl0 | Loop for next character 143 144 cgl5: movem.l (a7)+,d3-d6/a3 | Restore registers 145 unlk a6 | Unlink stack frames 146 rts | Return to caller 147 148 148 .end -
vlib/vwputp.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vwputp.s -- put a pixel into a 2-bit per pixel bitmap object3 *Version 2 -- 1987-04-14 -- D.N. Lynx Crowe4 *(c) Copyright 1987 -- D.N. Lynx Crowe5 *------------------------------------------------------------------------------6 *int7 *vwputp(octad, xloc, yloc, val)8 * struct octent *octad;9 *int xloc, yloc;10 * 11 *Writes the pixel value 'val' into the 2-bit per pixel12 *bitmap object described by 'octad' at ('xloc','yloc').13 * 14 *-----15 * 16 *struct octent {17 * 18 *uint ysize,19 *xsize;20 * 21 *int objx,22 *objy;23 * 24 * uint *obase;25 * 26 *char opri,27 *oflags;28 * 29 *uint odtw0,30 *odtw1;31 *};32 * 33 *Upper left corner of screen is (0,0) origin.34 * 1 | ------------------------------------------------------------------------------ 2 | vwputp.s -- put a pixel into a 2-bit per pixel bitmap object 3 | Version 2 -- 1987-04-14 -- D.N. Lynx Crowe 4 | (c) Copyright 1987 -- D.N. Lynx Crowe 5 | ------------------------------------------------------------------------------ 6 | int 7 | vwputp(octad, xloc, yloc, val) 8 | struct octent |octad; 9 | int xloc, yloc; 10 11 | Writes the pixel value 'val' into the 2-bit per pixel 12 | bitmap object described by 'octad' at ('xloc','yloc'). 13 14 | ----- 15 16 | struct octent { 17 18 | uint ysize, 19 | xsize; 20 21 | int objx, 22 | objy; 23 24 | uint |obase; 25 26 | char opri, 27 | oflags; 28 29 | uint odtw0, 30 | odtw1; 31 | }; 32 33 | Upper left corner of screen is (0,0) origin. 34 35 35 .text 36 * 36 37 37 .xdef _vputp 38 * 39 OCTAD .equ840 XLOC .equ1241 YLOC .equ1442 VAL .equ1643 * 44 YSIZE .equ045 XSIZE .equ246 OBJX .equ447 OBJY .equ648 OBASE .equ849 OPRI .equ1250 OFLAGS .equ1351 ODTW0 .equ1452 ODTW1 .equ1653 * 38 39 OCTAD = 8 40 XLOC = 12 41 YLOC = 14 42 VAL = 16 43 44 YSIZE = 0 45 XSIZE = 2 46 OBJX = 4 47 OBJY = 6 48 OBASE = 8 49 OPRI = 12 50 OFLAGS = 13 51 ODTW0 = 14 52 ODTW1 = 16 53 54 54 .page 55 * 56 _vwputp: link a6,#0 *Link stack frames57 movea.l OCTAD(a6),a1 *Get OCTAD base into a158 move.w XLOC(a6),d0 *Get XLOC into d059 cmp.w XSIZE(a1),d0 *Check XLOC range60 bge vputerr *ERROR if too large61 * 62 tst.w d0 *Check XLOC sign63 bmi vputerr *ERROR if negative64 * 65 move.w YLOC(a6),d1 *Get YLOC into d1 to test66 cmp.w YSIZE(a1),d1 *Check YLOC range67 bge vputerr *ERROR if too large68 * 69 tst.w d1 *Check YLOC sign70 bmi vputerr *ERROR if negative71 * 72 lsr.w #3,d0 *Divide XLOC by 873 move.w XSIZE(a1),d1 *Get width into d174 lsr.w #3,d1 *Divide width by 875 mulu YLOC(a6),d1 *Multiply width/8 by YLOC76 ext.l d0 *Extend XLOC/8 to a long77 add.l d0,d1 *... and add it to d178 add.l OBASE(a1),d1 *Add OBASE to d179 movea.l d1,a0 *Make a0 point at bitmap data80 move.w XLOC(a6),d0 *Get XLOC81 andi.l # $07,d0 *Mask to low 3 bits82 add.l d0,d0 *Multiply by 2 for word index83 move.l d0,d1 *Save index in d184 add.l #MTAB,d0 *Add mask table base85 movea.l d0,a2 *a2 points at mask86 add.l #STAB,d1 *Add shift table base to index87 move.l d1,a1 *a1 points at shift count88 move.w (a1),d0 *Get shift count in d089 move.w VAL(a6),d1 *Get new pixel in d190 andi.w # $03,d1 *Mask down to 2 bits91 lsl.w d0,d1 *Shift into position for OR92 move.w (a0),d0 *Get old bitmap word in d093 and.w (a2),d0 *Mask out old pixel94 or.w d1,d0 *OR in new pixel95 move.w d0,(a0) *Store updated word in bitmap96 clr.l d0 *Set return value = 0 = OK97 * 98 vputexit: unlk a6 *Unlink stack frame99 rts *Return to caller100 * 101 vputerr: moveq.l #-1,d0 *Set return value = -1 = ERROR102 bra vputexit *Go unlink stack and return103 * 104 MTAB: dc.w $FFFC,$FFF3,$FFCF,$FF3F *Mask table105 dc.w $FCFF,$F3FF,$CFFF,$3FFF106 STAB: dc.w 0,2,4,6,8,10,12,14 *Shift table107 * 55 56 _vwputp: link a6,#0 | Link stack frames 57 movea.l OCTAD(a6),a1 | Get OCTAD base into a1 58 move.w XLOC(a6),d0 | Get XLOC into d0 59 cmp.w XSIZE(a1),d0 | Check XLOC range 60 bge vputerr | ERROR if too large 61 62 tst.w d0 | Check XLOC sign 63 bmi vputerr | ERROR if negative 64 65 move.w YLOC(a6),d1 | Get YLOC into d1 to test 66 cmp.w YSIZE(a1),d1 | Check YLOC range 67 bge vputerr | ERROR if too large 68 69 tst.w d1 | Check YLOC sign 70 bmi vputerr | ERROR if negative 71 72 lsr.w #3,d0 | Divide XLOC by 8 73 move.w XSIZE(a1),d1 | Get width into d1 74 lsr.w #3,d1 | Divide width by 8 75 mulu YLOC(a6),d1 | Multiply width/8 by YLOC 76 ext.l d0 | Extend XLOC/8 to a long 77 add.l d0,d1 | ... and add it to d1 78 add.l OBASE(a1),d1 | Add OBASE to d1 79 movea.l d1,a0 | Make a0 point at bitmap data 80 move.w XLOC(a6),d0 | Get XLOC 81 andi.l #0x07,d0 | Mask to low 3 bits 82 add.l d0,d0 | Multiply by 2 for word index 83 move.l d0,d1 | Save index in d1 84 add.l #MTAB,d0 | Add mask table base 85 movea.l d0,a2 | a2 points at mask 86 add.l #STAB,d1 | Add shift table base to index 87 move.l d1,a1 | a1 points at shift count 88 move.w (a1),d0 | Get shift count in d0 89 move.w VAL(a6),d1 | Get new pixel in d1 90 andi.w #0x03,d1 | Mask down to 2 bits 91 lsl.w d0,d1 | Shift into position for OR 92 move.w (a0),d0 | Get old bitmap word in d0 93 and.w (a2),d0 | Mask out old pixel 94 or.w d1,d0 | OR in new pixel 95 move.w d0,(a0) | Store updated word in bitmap 96 clr.l d0 | Set return value = 0 = OK 97 98 vputexit: unlk a6 | Unlink stack frame 99 rts | Return to caller 100 101 vputerr: moveq.l #-1,d0 | Set return value = -1 = ERROR 102 bra vputexit | Go unlink stack and return 103 104 MTAB: dc.w 0xFFFC,0xFFF3,0xFFCF,0xFF3F | Mask table 105 dc.w 0xFCFF,0xF3FF,0xCFFF,0x3FFF 106 STAB: dc.w 0,2,4,6,8,10,12,14 | Shift table 107 108 108 .end -
vlib/vwputs.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *vwputs.s -- output a character string to a 2-bit per pixel graphics window3 *Version 9 -- 1987-07-28 -- D.N. Lynx Crowe4 *(c) Copyright 1987 -- D.N. Lynx Crowe5 *------------------------------------------------------------------------------6 * 7 *vwputs(obase, nw, fg, bg, row, col, str)8 * int *obase, nw, fg, bg, row, col;9 * char *str;10 * 11 *Outputs characters from the string at 'str' to an 'nw'12 *character wide 2-bit per pixel graphics window at 'obase'13 *at ('row','col'), using 'fg' as the foreground color, and14 *'bg' as the background color. Uses cgtable[][256] as the15 *VSDD formatted character generator table.16 *No error checks are done.17 *------------------------------------------------------------------------------18 * 1 | ------------------------------------------------------------------------------ 2 | vwputs.s -- output a character string to a 2-bit per pixel graphics window 3 | Version 9 -- 1987-07-28 -- D.N. Lynx Crowe 4 | (c) Copyright 1987 -- D.N. Lynx Crowe 5 | ------------------------------------------------------------------------------ 6 7 | vwputs(obase, nw, fg, bg, row, col, str) 8 | int |obase, nw, fg, bg, row, col; 9 | char |str; 10 11 | Outputs characters from the string at 'str' to an 'nw' 12 | character wide 2-bit per pixel graphics window at 'obase' 13 | at ('row','col'), using 'fg' as the foreground color, and 14 | 'bg' as the background color. Uses cgtable[][256] as the 15 | VSDD formatted character generator table. 16 | No error checks are done. 17 | ------------------------------------------------------------------------------ 18 19 19 .text 20 20 .xdef _vwputs 21 * 21 22 22 .xref _cgtable 23 * 24 *Argument offsets from a6:25 * 26 OBASE .equ 8 *L: Output area base address27 NW .equ 12 *W: Character width of output area28 FG .equ 14 *W: Foreground color29 BG .equ 16 *W: Background color30 ROW .equ 18 *W: Row31 COL .equ 20 *W: Column32 STR .equ 22 *L: String base address33 * 34 *Miscellaneous constants:35 * 36 HPIX .equ 8 *Horizontal pixels in the character37 * 38 NVPIX .equ 12 *Vertical pixels in the character39 VPITCH .equ 12 *Vertical pitch between characters40 * 41 *Register usage:42 * 43 *d0 output word and scratch44 *d1 CG word and scratch45 *d2 pixel counter46 *d3 foreground color (in the 2 ms bits)47 *d4 background color (in the 2 ms bits)48 *d5 width of the area in bytes49 *d6 scan line counter50 * 51 *a0 CG table pointer52 *a1 output area scan line pointer53 *a2 input character pointer54 *a3 output area character pointer55 * 23 24 | Argument offsets from a6: 25 26 OBASE = 8 | L: Output area base address 27 NW = 12 | W: Character width of output area 28 FG = 14 | W: Foreground color 29 BG = 16 | W: Background color 30 ROW = 18 | W: Row 31 COL = 20 | W: Column 32 STR = 22 | L: String base address 33 34 | Miscellaneous constants: 35 36 HPIX = 8 | Horizontal pixels in the character 37 38 NVPIX = 12 | Vertical pixels in the character 39 VPITCH = 12 | Vertical pitch between characters 40 41 | Register usage: 42 43 | d0 output word and scratch 44 | d1 CG word and scratch 45 | d2 pixel counter 46 | d3 foreground color (in the 2 ms bits) 47 | d4 background color (in the 2 ms bits) 48 | d5 width of the area in bytes 49 | d6 scan line counter 50 51 | a0 CG table pointer 52 | a1 output area scan line pointer 53 | a2 input character pointer 54 | a3 output area character pointer 55 56 56 .page 57 * 58 _vwputs: link a6,#0 *Link stack frames59 movem.l d3-d6/a3,-(a7) *Save registers we use60 move.w #14,d1 *Set shift constant61 move.w FG(a6),d3 *Setup foreground color62 lsl.w d1,d3 *... in ms 2 bits of d363 move.w BG(a6),d4 *Setup background color64 lsl.w d1,d4 *... in ms 2 bits of d465 move.w NW(a6),d5 *Get width in characters in d566 lsl.w #1,d5 *... make it words67 move.w ROW(a6),d0 *Calculate output address68 move.w #VPITCH,d1 *...69 mulu d1,d0 * ... ROW *VPITCH70 add.w #NVPIX-1,d0 *... + NVPIX-171 mulu d5,d0 * ... *NW72 clr.l d1 *...73 move.w COL(a6),d1 * ... + (COL *2)74 lsl.l #1,d1 *...75 add.l d1,d0 *...76 add.l OBASE(a6),d0 *... + OBASE77 movea.l d0,a3 *Leave output address in a378 movea.l STR(a6),a2 *Put string address in a279 * 57 58 _vwputs: link a6,#0 | Link stack frames 59 movem.l d3-d6/a3,-(a7) | Save registers we use 60 move.w #14,d1 | Set shift constant 61 move.w FG(a6),d3 | Setup foreground color 62 lsl.w d1,d3 | ... in ms 2 bits of d3 63 move.w BG(a6),d4 | Setup background color 64 lsl.w d1,d4 | ... in ms 2 bits of d4 65 move.w NW(a6),d5 | Get width in characters in d5 66 lsl.w #1,d5 | ... make it words 67 move.w ROW(a6),d0 | Calculate output address 68 move.w #VPITCH,d1 | ... 69 mulu d1,d0 | ... ROW | VPITCH 70 add.w #NVPIX-1,d0 | ... + NVPIX-1 71 mulu d5,d0 | ... | NW 72 clr.l d1 | ... 73 move.w COL(a6),d1 | ... + (COL | 2) 74 lsl.l #1,d1 | ... 75 add.l d1,d0 | ... 76 add.l OBASE(a6),d0 | ... + OBASE 77 movea.l d0,a3 | Leave output address in a3 78 movea.l STR(a6),a2 | Put string address in a2 79 80 80 .page 81 cgl0: clr.l d0 *Clear out upper bits of d082 move.b (a2)+,d0 *Get next character83 beq cgl5 *Done if character EQ 084 * 85 movea.l a3,a1 *Establish output pointer in a186 adda.l #2,a3 *Update output pointer for next char.87 lea _cgtable,a0 *Establish CG pointer in a088 lsl.w #1,d0 * ... 2 *character89 adda.w d0,a0 *... + _cgtable address90 move.w #NVPIX-1,d6 *Set scan line counter in d691 * 92 cgl1: move.w #HPIX-1,d2 *Set pixel counter in d293 move.w (a0),d1 *Get character generator word in d194 * 95 cgl2: lsr.w #2,d0 *Shift output word right 1 pixel96 btst.l #0,d1 *Check CG word ls bit97 beq cgl3 *Set background color if bit EQ 098 * 99 or.w d3,d0 *OR foreground color into output word100 bra cgl4 *Go update CG word101 * 102 cgl3: or.w d4,d0 *OR background color into output word103 * 104 cgl4: lsr.w #1,d1 *Shift CG word right 1 pixel105 dbf d2,cgl2 *Loop for all 8 pixels106 * 107 move.w d0,(a1) *Store output word in output bitmap108 suba.w d5,a1 *Update output pointer109 adda.l #512,a0 *Update CG pointer for next scan line110 dbf d6,cgl1 *Loop for all scan lines111 * 112 bra cgl0 *Loop for next character113 * 114 cgl5: movem.l (a7)+,d3-d6/a3 *Restore registers115 unlk a6 *Unlink stack frames116 rts *Return to caller117 * 81 cgl0: clr.l d0 | Clear out upper bits of d0 82 move.b (a2)+,d0 | Get next character 83 beq cgl5 | Done if character EQ 0 84 85 movea.l a3,a1 | Establish output pointer in a1 86 adda.l #2,a3 | Update output pointer for next char. 87 lea _cgtable,a0 | Establish CG pointer in a0 88 lsl.w #1,d0 | ... 2 | character 89 adda.w d0,a0 | ... + _cgtable address 90 move.w #NVPIX-1,d6 | Set scan line counter in d6 91 92 cgl1: move.w #HPIX-1,d2 | Set pixel counter in d2 93 move.w (a0),d1 | Get character generator word in d1 94 95 cgl2: lsr.w #2,d0 | Shift output word right 1 pixel 96 btst.l #0,d1 | Check CG word ls bit 97 beq cgl3 | Set background color if bit EQ 0 98 99 or.w d3,d0 | OR foreground color into output word 100 bra cgl4 | Go update CG word 101 102 cgl3: or.w d4,d0 | OR background color into output word 103 104 cgl4: lsr.w #1,d1 | Shift CG word right 1 pixel 105 dbf d2,cgl2 | Loop for all 8 pixels 106 107 move.w d0,(a1) | Store output word in output bitmap 108 suba.w d5,a1 | Update output pointer 109 adda.l #512,a0 | Update CG pointer for next scan line 110 dbf d6,cgl1 | Loop for all scan lines 111 112 bra cgl0 | Loop for next character 113 114 cgl5: movem.l (a7)+,d3-d6/a3 | Restore registers 115 unlk a6 | Unlink stack frames 116 rts | Return to caller 117 118 118 .end
Note:
See TracChangeset
for help on using the changeset viewer.