Files
Shawn Quick dfcaae62dd Add qlink, the disk tools, and a bootable ProDOS 8 image.
Move the assembler to src/qasm. qlink links OMF 1.0 and 2.0 from a script. makeBin flattens a load file, qomf dumps OMF, and qpro builds ProDOS volumes. APW and MPW assemble through the ORCA front end. Relocatable modules emit OMF objects. Listings stay off unless -l is set.

make boot assembles the GS/OS 6.0.1 ProDOS 8 kernel and BASIC.SYSTEM into an 800K volume. BASIC.SYSTEM accepts ls and pfx, and its splash reports PRODOS BASIC 2.0, copyright 1983-2026. IIGS.601.SRC is the source and the BASIC.SYSTEM oracle that image is built from.
2026-10-16 14:41:55 -07:00

1 line
12 KiB
Plaintext

Print off
;-----------------------------------------------
;
; Imported addresses
;
;-----------------------------------------------
IMPORT AddMidiHook
IMPORT AllNotesOff
IMPORT AllocGen
IMPORT DeAllocGen
IMPORT NoteOff
IMPORT NoteOn
IMPORT long
IMPORT SetUpdateRate
IMPORT SetUserUpdateRtn
IMPORT short
IMPORT update
;-----------------------------------------------
;
; Forward addresses and entries
;
;-----------------------------------------------
ENTRY NSBoot
ENTRY NSReset
ENTRY NSShutdown
ENTRY NSStartStat
ENTRY NSStartup
ENTRY NSVersion
ENTRY NotImp
MACHINE M65816
INCLUDE 'ns.equ'
INCLUDE 'note.macros'
INCLUDE 'E16.Memory'
INCLUDE 'all.macros'
Print on, NoGen, NoHdr, NoMDir
****************************************************************
*
* Note Synthesizer Function Pointer Table
*
* 7/25/88 Matt Denman changed NSFTP to NoteSynCallTable
*
****************************************************************
*
FPT PROC
EXPORT NoteSynCallTable
NoteSynCallTable DC.L 16
DC.L NSBoot-1
DC.L NSStartup-1
DC.L NSShutdown-1
DC.L NSVersion-1
DC.L NSReset-1
DC.L NSStartStat-1
DC.L NotImp-1
DC.L NotImp-1
DC.L AllocGen-1 ;9
DC.L DeAllocGen-1 ;10
DC.L NoteOn-1 ;11
DC.L NoteOff-1 ;12
DC.L AllNotesOff-1 ;13
DC.L SetUpdateRate-1 ;14
DC.L SetUserUpdateRtn-1 ;15
ENDP
****************************************************************
*
* NSBoot
*
* Inputs:
*
* Outputs:
*
****************************************************************
*
* This routine gets called when I'm first loaded into ram. Since
* the sound tools have done most of the work already.
EXPORT NSBoot
NSBoot PROC
longa on
longi on
* clear out my cubbyhole and thereby reset the 'awake' flag
ldx #10 ; 12 bytes there
lda #0
@clear sta >cubbyhole,x
dex
dex
bpl @clear
clc
rtl
ENDP
****************************************************************
*
* NSStartup
*
* Inputs: update rate, interrupt flag, and timer routine
*
* Outputs: none right now
*
*****************************************************************
longa on
longi on
EXPORT NSStartup
NSStartup PROC
updateRate equ 7+4+2 ; 2 for dp; 7 for rtl etc
userRoutine equ 7+0+2
* Start by seeing if we're already started.
lda >myflags
and #awake_bit
beq asleep
* whoops! we were. Return an error.
ldx #errstarted
brl exit
* normal startup. Steal the direct page work area from Sound Tools.
asleep pea 0 ; find out if the sound tools
_SoundToolStatus ; have been started
pla
bne soundon
ldx #soundnotinit
brl exit
soundon pea 0
_SoundVersion
pla ; get the version of the Sound Tools.
and #$7FFF ; don't care if prototype.
cmp #SoundTVer
bcs Ver_OK
ldx #errSoundWrngVer ; Sound Tools have the wrong version.
brl exit
Ver_OK pushword #0 ; this argument is for SETWAP call
pushword #my_tool_number
pushword #0 ; room for result
pushword #0 ;
pushword #0 ; system tool/ sound tool
pushword #8 ; My tool uses the same zero page
_GetWAP ; as the sound tools. ask for it.
* if there's an error here... God help us
lda 1,s
sta >mydp-1 ; store hi byte in cubbyhole
_SetWAP ; my ID, and the WAP, are on stack
lda >mydp-1
and #$FF00 ; regain DP
* Direct page pointer (GCB) is in A. Use it to reserve the last
* generator (#$0E) for a timer. (****** att: ROM REV FIX ****** )
* This is because osc 30 and 31 don't interrupt properly with the
* June 86 ROM.
phd ; save user DP
tcd ; install mine
lda #My_ID ; Note Synth tag is attached
; sta <timer_gen*16 ; to the the last GCB so that
sta <timer_gen<<4 ; to the last GCB so that
* ; IRQ will come to me.
****************************************************************
* Other things to set up in the 'cubbyhole:' pointers and flags
* note that DP is on stack, my DP is installed.
* Stack contents:
* updateRate equ 7+4+2 ; 2 for dp; 7 for rtl etc
* userRoutine equ 7+0+2
* rtl
* rtl
* user DP
; get handle for priority_table and vcb_ram.
pha ; space for result.
pha ;
lda #0 ; Size in bytes of handle.
pha ;
lda #528 ; 32X16=512+16= 528 bytes.
pha ; may only need 32X14 but just in case.
lda #NSID ; get the id to use for NS.
pha ;
lda #attrlocked+attrNoCross+attrfixed ; can't move,purge of Cross banks.
pha ;
pha ; address
pha ;
_NewHandle ; get my memory.
tax ; save the error code, if error.
tsc ; dereference the handle off of ...
phd ; the stack, by moving the dp ...
tcd ; to the stack.
ldy #2 ; index for high word.
lda [1],y ; get the high word.
ora #$100 ; set awake_bit.
sta >myram_ptr+2 ; save high word addr and my_flag.
lda [1] ; get the low word.
sta >myram_ptr ; save low in my reserved memory loc.
pld ; restore dp.
pla ; clean up the stack.
pla ;
; This is now acomplished by the NewHandle code above. Where I get memory.
; Have myram_ptr point to it, and or in that awake_bit.
* lda #priority_table ; priority table is a little different,
* sta >myram_ptr ; now that I'm moving to rom.
* lda #^(priority_table)
* ora #$100 ; set awake_bit that NS is started.
* sta >myram_ptr+2 ; high word addr
* Check if UpdateRate is zero if so use update_rate as default.
lda UpdateRate,s
bne @1
lda #update_rate
sta UpdateRate,s
* take care of the user update vector. set a flag if its non-zero
@1 ldx #0 ;x is a case flag for a moment.
lda userRoutine,s
beq low0
inx ;if both halves of user routine
low0 sta >userUpdate ; are zero, then we don't call
mem_short ; this address
lda userRoutine+2,s
beq high0
inx
high0 sta >userUpdate+2
txa
beq novec
lda >myflags ; we have a non-zero vector.
ora #user_bit ; set a flag and
sta >myflags
lda #$5c ; install a jump long instruction
sta >userjump
novec mem_long
* initialize the priority table. The address of it is in zero page.
lda myram_ptr+1 ; put myram_ptr on stack.
pha ; so I can move the dp on the stack,
phb
lda myram_ptr ; and then access it for long indexed,
sta 1,s ; indirect.
phd ; save old dp.
tsc ; get the stack.
tcd ; set dp to be on stack.
lda #0
ldy #30
fill sta [3],y ; initialize the priority table
dey
dey
bpl fill
pld ; restore dp.
phb ; extra space. 3 bytes pushed already.
* pla ; pull myramp_ptr off of stack.
* pla ;
* pha ; Now install my interrupt
* pha ; handler as the first one
EXPORT reloc2
reloc2 ;
lda #^update ; in line. Save the old
pha ; vector in case someone
EXPORT relocb2
relocb2 ;
lda #<update ; creates yet another kind
pha ; of synthesizer.
_SetUserSoundIRQV ; sound tool $13: install vec
pla ; get next guys irq vector
sta >old_vector ; and save that
pla
mem_short
sta >old_vector+2
php ; save status
sei ; no interupts while using DOC Glue.
lda >SysVol
sta >GStatReg ; no inc, to doc
lda #doc_freqlo+timer_osc ; set frequency of the
sta >GAdrL ; timer osc
lda updateRate+1,s
asl A ; 9/24/86 double the freq
sta >GDataReg
lda #doc_freqhi+timer_osc
sta >GAdrL
lda updateRate+1+1,s
rol A ; 9/24/86 hi byte of freq
sta >GDataReg
lda #doc_vol+timer_osc ; set volume, for kicks...
sta >GAdrL
lda #$00
sta >GDataReg
lda #doc_size+timer_osc
sta >GAdrL
lda #$00
sta >GDataReg
lda #doc_ctrl+timer_osc
sta >GAdrL
lda #doc_irq_bit ; free run, interrupts
sta >GDataReg
plp ; reenable interupts.
mem_long
pld
ldx #0 ; err code
exit pla ; move ,1 to ,7
sta 5,s
pla ; move ,3 to ,9
sta 5,s
pla ; move ,5 to ,11
sta 5,s
txa
cmp #1
rtl
ENDP
eject
****************************************************************
*
* NSShutdown
*
* Inputs:
*
* Outputs:
*
****************************************************************
*
EXPORT NSShutdown
NSShutdown PROC
longa on
longi on
lda >myflags
and #awake_bit
bne proceed
* its not started!
lda #errNotStarted
sec
rtl
proceed _AllNotesOff
mem_short
lda >SysVol
sta >GStatReg ; no inc, to doc
lda #doc_ctrl+timer_osc
sta >GAdrL
lda #doc_halt_reset ; turn off the timer osc
sta >GDataReg
* swap the old IRQ vector back; take mine out of the loop
both long
pha
pha
lda >old_vector+2 ; (ignore hi byte...)
pha
lda >old_vector
pha
_SetUserSoundIRQV
pla
pla
* clear out my cubbyhole and thereby reset the 'awake' flag
ldx #10 ; 12 bytes there
lda #0
clear2 sta >cubbyhole,x
dex
dex
bpl clear2
* ZAP my WAP, so that the tool locator won't give it to me.
pushword #0
pushword #my_tool_number
pushword #0
pushword #0
_SetWAP
* Dispose of the handle I have been using.
Pushword #NSID
_Disposeall
cmp #1
rtl
ENDP
****************************************************************
*
* NSVersion
*
* Inputs:
*
* Outputs:
*
****************************************************************
*
EXPORT NSVersion
NSVersion PROC
longa on
longi on
lda #version_number
sta 7,s
lda #0
clc
rtl
ENDP
****************************************************************
*
* NSReset
*
* Inputs:
*
* Outputs:
*
****************************************************************
*
EXPORT NSReset
NSReset PROC
longi on
longa on
* using mydata
jsl NSShutdown
lda #0 ;no error, either way...
clc
rtl
ENDP
****************************************************************
*
* NSStartStat
*
* Inputs:
*
* Outputs:
*
****************************************************************
*
EXPORT NSStartStat
NSStartStat PROC
longi on
longa on
lda >myflags
and #awake_bit
beq notstarted
lda #$FFFF ; yes, we are awake
bra exit
notstarted lda #0 ; no we are not
exit sta 7,s
lda #0
clc
rtl
ENDP
****************************************************************
*
* NotImp
*
* Inputs:
*
* Outputs:
*
****************************************************************
*
NotImp PROC
longa on
longi on
lda #-1
sec
rtl
ENDP
END